var express = require('express');
var router = express.Router();
var doSQL = require('../mysql/index').doSQL;
const axios = require('axios');
const { createProxyMiddleware, responseInterceptor } = require('http-proxy-middleware');
const fs = require("fs");
var path = require("path");
var config = require('../config');

const baseURL = config.camunda.base;

//1.获取最新流程定义列表
router.get('/engine-rest/process-definition', function(request, response) {
    //查询流程总数量
    axios.get(baseURL + '/engine-rest/process-definition/count?latestVersion=true').then(res=>{
        let count = res.data.count;
        doRequest(request).then(data=>{
          response.send({
              code: 200,
              data: {
                  list: data,
                  total: count
              }
          });
      }).catch(err=>{
          response.send(JSON.stringify({
              code: 600,
              message: err
          }));
      })
    })
    
});

//2.获取流程实例列表
router.get('/engine-rest/history/process-instance', function(request, response) {
  let processDefinitionKey = request.query.processDefinitionKey;
  let finished = request.query.finished;
  //查询实例总数量
  axios.get(baseURL + `/engine-rest/history/process-instance/count`,{
    params: {
      processDefinitionKey,
      finished
    }
  }).then(res=>{
      let count = res.data.count;
      doRequest(request).then(data=>{
        response.send({
            code: 200,
            data: {
                list: data,
                total: count
            }
        });
    }).catch(err=>{
        response.send(JSON.stringify({
            code: 600,
            message: err
        }));
    })
  })
  
});

//3.获取流程实例任务列表
router.get('/engine-rest/history/task', function(request, response) {
  let processInstanceId = request.query.processInstanceId;
  //查询实例任务总数量
  axios.get(baseURL + `/engine-rest/history/task/count?processInstanceId=${processInstanceId}`).then(res=>{
      let count = res.data.count;
      doRequest(request).then(data=>{
        //如果任务已完成，获取任务评论
        let promiseArr = [];
        data.forEach(item=> {
          promiseArr.push(axios.get(baseURL + `/engine-rest/task/${item.id}/comment`))
        })
        Promise.all(promiseArr).then(res=>{
          res.forEach((item,index)=> {
            data[index].comment = item.data;
          })
          response.send({
              code: 200,
              data: {
                  list: data,
                  total: count
              }
          });
        })
    }).catch(err=>{
        response.send(JSON.stringify({
            code: 600,
            message: err
        }));
    })
  })
  
});

//4.添加候选人
router.post('/engine-rest/task/:taskId/identity-links', function(request, response) {
  doRequest(request).then(data=>{
    response.send({
        code: 200
    });
  }).catch(err=>{
      response.send(JSON.stringify({
          code: 600,
          message: err
      }));
  })
});

//5.移除候选人
router.post('/engine-rest/task/:taskId/identity-links/delete', function(request, response) {
  doRequest(request).then(data=>{
    response.send({
        code: 200
    });
  }).catch(err=>{
      response.send(JSON.stringify({
          code: 600,
          message: err
      }));
  })
});

function getProcessInstanceDetail(taskInfo,id) {
  return new Promise((resolve, reject) => {
    const query = `
      SELECT wi.form_id, wi.process_key, wi.form_values, wi.process_instance_id, wi.status, wf.form_name, wf.form_desc, wf.form_path
      FROM workflow_instance wi
      LEFT JOIN workflow_form wf ON wf.id = wi.form_id
      WHERE process_instance_id = ?
    `;
    const params = [id];
    doSQL(query, params).then(res=>{
        let data = res.data[0];
        axios.get(baseURL + `/engine-rest/process-definition/${taskInfo.processDefinitionId}`)
          .then(res=>{
            let processInfo = res.data;
            if(data){
              try {
                let form = require(path.join(__dirname, '../' + data.form_path));
                resolve({
                  processName: processInfo.name,
                  ...taskInfo,
                  ...data,
                  form: form.formFields
                })
              } catch (error) {
                resolve({
                  processName: processInfo.name,
                  ...taskInfo,
                  ...data
                })
              }
              
              // fs.readFile(path.join(__dirname, '../' + data.form_path), 'utf-8', function(err, form) {
              //   if (err) {
              //       resolve({
              //         processName: processInfo.name,
              //         ...taskInfo,
              //         ...data
              //       })
              //   } else {
              //       resolve({
              //         processName: processInfo.name,
              //         ...taskInfo,
              //         ...data,
              //         form: JSON.parse(form)
              //       })
              //   }
              // });
            } else {
              resolve({
                processName: processInfo.name,
                ...taskInfo
              })
            }
          })
          .catch(error => {
            // 处理 axios 错误
            resolve({
              ...taskInfo
            })
          });
    }).catch(error => {
      // 处理 doSQL 错误
      reject(error);
    });
  });
}
//6.查询候选任务
router.get('/engine-rest/task', async function(request, response) {
  let candidateUser = request.query.candidateUser;
  let assignee = request.query.assignee;
  let candidateGroup = request.query.candidateGroup;
  try {
    let count = 0;
    let primiseArr = [];
    if(!candidateUser && !assignee && !candidateGroup){
      res = await axios.get(baseURL + '/engine-rest/task/count');
      count = res.data.count;
      const data = await doRequest(request);
      // 按照 created 字段倒序排序
      data.sort((a, b) => new Date(b.created) - new Date(a.created));
      data.forEach(item => {
        primiseArr.push(getProcessInstanceDetail(item, item.processInstanceId));
      });
    }else{
      // 如果传入了参数，分别查询
      let requests = [];
      if (candidateUser) {
        requests.push(axios.get(baseURL + '/engine-rest/task', {
          params: { candidateUser: candidateUser }
        }));
      }
      if (assignee) {
        requests.push(axios.get(baseURL + '/engine-rest/task', {
          params: { assignee: assignee }
        }));
      }
      if (candidateGroup) {
        requests.push(axios.get(baseURL + '/engine-rest/task', {
          params: { candidateGroup: candidateGroup }
        }));
      }

      // 等待所有请求完成
      const responses = await Promise.all(requests);

      // 合并所有请求的结果
      let tasks = [];
      responses.forEach(response => {
        tasks = tasks.concat(response.data);
      });

      // 去重
      const uniqueTasks = tasks.filter((task, index, self) =>
        index === self.findIndex((t) => (
          t.id === task.id
        ))
      );
      // 按照 created 字段倒序排序
      uniqueTasks.sort((a, b) => new Date(b.created) - new Date(a.created));

      // 分页处理
      let firstResult = request.query.firstResult || 0;
      let maxResults = request.query.maxResults || 10;
      const paginatedTasks = uniqueTasks.slice(firstResult, firstResult + maxResults);

      // 获取任务总数
      count = uniqueTasks.length;

      // 获取任务详情
      paginatedTasks.forEach(item => {
        primiseArr.push(getProcessInstanceDetail(item, item.processInstanceId));
      });
    }
    
    const results = await Promise.all(primiseArr);
    response.send({
      code: 200,
      data: {
        list: results,
        total: count
      }
    });
  } catch (err) {
    console.error('Error:', err);
    response.send({
      code: 600,
      message: err.message || '处理请求时发生错误'
    });
  }
});

//7.领取任务
router.post('/engine-rest/task/:taskId/claim', function(request, response) {
  doRequest(request).then(data=>{
    response.send({
        code: 200
    });
  }).catch(err=>{
      response.send(JSON.stringify({
          code: 600,
          message: err
      }));
  })
});
//8.取消执行人
router.post('/engine-rest/task/:taskId/unclaim', function(request, response) {
  doRequest(request).then(data=>{
    response.send({
        code: 200
    });
  }).catch(err=>{
      response.send(JSON.stringify({
          code: 600,
          message: err
      }));
  })
});
//9.执行任务
router.post('/engine-rest/task/:taskId/complete', function(request, response) {
  doRequest(request).then(data=>{
    response.send({
        code: 200
    });
  }).catch(err=>{
      response.send(JSON.stringify({
          code: 600,
          message: err
      }));
  })
});
//10.设置任务评论
router.post('/engine-rest/task/:taskId/comment/create', function(request, response) {
  doRequest(request).then(data=>{
    response.send({
        code: 200
    });
  }).catch(err=>{
      response.send(JSON.stringify({
          code: 600,
          message: err
      }));
  })
});

/**
 * 创建自定义流程实例
 * @description 本系统内生成流程实例，并启动camunda流程--------标准需要开事务
 * @
 */
router.post('/start', function(request, response) {
  //1. 启动camunda流程
  let processKey = request.body.processKey;
  let createUser = request.body.createUser;
  //1.本系统内生成流程实例
  let formId = request.body.formId;
  let formValues = request.body.formValues;
  const query = `
  INSERT INTO workflow_instance (form_id, process_key, process_instance_id, form_values, status, create_user)
    VALUES (?, ?, NULL, ?, 1, ?)
  `;
  const params = [formId, processKey, formValues, createUser];

  doSQL(query,params).then(res=>{
    if(!res.error){
      //获取刚刚插入的id
      const insertId = res.data.insertId; 
      axios.post(baseURL + `/engine-rest/process-definition/key/${processKey}/start`, {
        businessKey: insertId
      }).then(res=>{
        let processInstanceId = res.data.id;
        if( processInstanceId ){
          //2. 创建本系统内的流程实例包含form_id，process_instance_id，status
          const query = `UPDATE workflow_instance SET process_instance_id = ? WHERE id = ?`;
          const params = [processInstanceId, insertId];

          doSQL(query, params).then(res=>{
            if(!res.error){
              response.send({
                code: 200,
                message: '启动流程成功'
              });
            }else{
              const query = `delete from workflow_instance where id = ?`;
              const params = [insertId];
              doSQL(query, params).then(res=>{
                response.send({
                  code: 600,
                  message: '启动流程失败'
                });
              })
            }
          })
        }else {
          response.send({
            code: 600,
            message: '启动流程失败'
          });
        }
      })
    }else{
      response.send({
        code: 600,
        message: '启动流程失败'
      });
    }
  })
});


router.use('/', createProxyMiddleware({
  target: baseURL,
  changeOrigin: true,  // 确保请求头正确
  pathRewrite: {
    '^/process': '',  // 去掉路径前缀
  },
  timeout: 60000,  // 设置超时为60秒
  selfHandleResponse: true,
  on: {
    // proxyReq: (proxyReq, req, res) => {
    //   console.log('代理请求发送到目标服务器:', proxyReq.path);
    //   console.log('请求头:', proxyReq.getHeaders());
    // },
    proxyRes: responseInterceptor(async (responseBuffer, proxyRes, req, res) => {
      const response = responseBuffer.toString('utf8'); // convert buffer to string
      let originalData;
      try {
        originalData = response ? JSON.parse(response) : {}; // parse JSON
      } catch (error) {
        originalData = {
          code: 500,
          message: 'Error parsing response',
          data: response
        };
      }
      
      //异常特殊处理
      if(originalData?.message?.includes('ENGINE-03076')){
        return JSON.stringify({
          code: 503,
          msg: '流程存在启用的实例，无法删除！'
        });
      }else{
        let statusCode = proxyRes.statusCode == 204 ? 200 : proxyRes.statusCode;
        const wrappedData = {
          code: originalData.code || statusCode, // 包含 HTTP 状态码
          data: originalData.data || originalData,        // 返回的实际数据
          timestamp: new Date().toISOString(),           // 添加时间戳
        };
        return JSON.stringify(wrappedData);
      }
    }),
    error: (err, req, res) => {
      console.error('Proxy error:', err);
      res.status(500).json({
        code: 500,
        message: 'Proxy request failed',
        error: err.message
      });
    }
  },
}));


// function proxyDataResolver(fn) {
//     return proxy(baseURL + '', {
//         proxyReqPathResolver: function (req) {
//           // 移除请求路径中的开头 /process
//           return req.url.replace(/^\/process/, '');
//         },
//         proxyReqOptDecorator: function(proxyReqOpts, req) {
//           // 确保请求头中包含正确的 Content-Type
//           if (req.headers['content-type']) {
//             proxyReqOpts.headers['Content-Type'] = req.headers['content-type'];
//           }
//           return proxyReqOpts;
//         },
//         userResDecorator: function (proxyRes, proxyResData, req, res) {
//           try {
//             // 处理返回的结果
//             const originalData = JSON.parse(proxyResData.toString('utf8')); // 解析 JSON
//             const wrappedData = {
//               code: originalData.code || proxyRes.statusCode, // 包含 HTTP 状态码
//               data: fn ? fn(originalData) : (originalData.data || originalData),        // 返回的实际数据
//               timestamp: new Date().toISOString(),           // 添加时间戳
//             };
//             return JSON.stringify(wrappedData); // 转换为字符串返回
//           } catch (error) {
//             console.error('Error processing response:', error);
//             return proxyResData; // 如果解析失败，直接返回原始数据
//           }
//         },
//     })
// }

function doRequest(req) {
    return new Promise((resolve, reject) => {
        // 构建请求选项
        const url = baseURL + `${req.url.replace(/^\/process/, '')}`;
        axios({
            url: url,
            method: req.method,
            data: req.body,
          })
          .then(response => {
            resolve(response.data,response)
          })
          .catch(error => {
            reject(error)
          });
          
    });
}


module.exports = router;
