import {
  downloadImage,
  downloadOtherImage,
  toSend,
  writeProfileXml,
  copySingleImage,
  createBatchFolder,
  downloadDTFFiles
} from "@/server/utils";
const { downloadPngList } = require("@/utils/download-queue");
const {
  cropImageTransparentEdges,
  cropTransparentEdges,
  processImages
} = require("../utils/setImage");
import axios from "axios";
import { returnLogFilePath } from "../utils/log";
var request = require("request");
const compressing = require("compressing");
const uuid = require("uuid");
const path = require("path");
const fs = require("fs");
const os = require("os");
const { app } = require("electron");
let fileEnv, env, visionUrl;
axios.defaults.timeout = 12600000;
const multiparty = require("multiparty");
const {
  getVersion,
  setApi,
  getHostApi,
  getDesktopDevice
} = require("@/server/utils/store");

const { pathMap } = require("@/config/index.js");

//获取当前驱动版本
function getCurrentVersion() {
  const version = getVersion();
  return version;
}
//获取当前设备类型
function getCurrentDesktopDevice() {
  const version = getDesktopDevice();
  return version;
}

/**
 * @function readEnv
 * @description 【核心方法】读取项目配置文件，自动区分测试/生产环境
 * 作用：1. 动态获取配置文件路径（开发/打包环境自动适配）
 *      2. 读取env.json配置文件
 *      3. 根据打包命令切换测试/生产环境接口地址
 *      4. 初始化全局接口变量，供项目全局使用
 *      5. 配置加载失败时自动兜底默认配置
 */
function readEnv() {
  let exePath, configPath;
  try {
    if (process.env.NODE_ENV === "development") {
      configPath = path.join(__dirname, "../config/env.json");
    } else {
      exePath = path.dirname(app.getPath("exe")).replace(/\\/g, "/");
      configPath = `${exePath}/config/env.json`;
    }
    const data = fs.readFileSync(configPath, "utf-8");
    const allConfig = JSON.parse(data);

    const isTest = process.env.VUE_APP_ENV === "test";
    const config = isTest ? allConfig.test : allConfig.prod;

    config.configPath = configPath;
    setApi(config);

    fileEnv = config.fileApiUrl;
    env = config.apiApiHost;
    visionUrl = config.visionUrl;
    console.log("配置加载完成：", { fileEnv, env, visionUrl });
  } catch (err) {
    console.error("读取配置文件失败:", err);

    fileEnv = "https://factory.jomalls.com/upload/factory";
    env = "https://factory.jomalls.com/api";
    visionUrl = "https://console.jomalls.com";
    configPath = "D:\\work\\electron-printer\\config\\env.json";
    throw new Error(`配置文件加载失败：${err.message}`);
  }
}

readEnv();
export default {
  saveImgByUrl: async (req, res) => {
    const desktopDevice = getCurrentDesktopDevice();
    const version = desktopDevice == 3 ? "huiLiCaiImg" : getCurrentVersion();
    console.log("version", version);

    try {
      const response = await axios({
        url: req.body.url,
        method: "GET",
        responseType: "stream"
      });
      let fileName = uuid.v4() + ".png";
      const filePath = path.join(
        process.cwd(),
        `./${version}/Input/` + fileName
      );
      const writer = fs.createWriteStream(filePath);

      response.data.pipe(writer);

      writer.on("finish", () => {
        res.json({
          code: 200,
          data: filePath
        });
      });

      writer.on("error", err => {
        res.json({
          code: 500,
          data: err.message
        });
      });
    } catch (error) {
      console.error("Error downloading image:", error);
      res.json({
        code: 500,
        data: error.message
      });
    }
  },
  writePrintLog: async (req, res) => {
    try {
      let body = req.body;
      let p = path.join(returnLogFilePath(), "print.json");
      p = p.replace("\\api.log", "");
      // console.log(p);
      let data = [];
      if (!fs.existsSync(p)) {
        fs.writeFileSync(p, "[]");
        data = [];
      } else {
        data = fs.readFileSync(p, { encoding: "utf-8" });
        data = JSON.parse(data);
      }
      data.unshift(body);
      fs.writeFileSync(p, JSON.stringify(data));
      res.json({ code: 200 });
    } catch (e) {
      res.json({ code: 500, msg: e });
    }
  },

  downloadBySubOrderNumber: async (req, res) => {
    env = getHostApi().apiApiHost;
    fileEnv = getHostApi().fileApiUrl;
    const params = req.body;
    const targetDir = params.targetDir || "";
    const token = req.headers["jwt-token"];
    const forceProduction = params.forceProduction || false;
    const downloadBySubOrderNumber = pathMap["downloadBySubOrderNumber"];
    try {
      let url = downloadBySubOrderNumber[params.orderType];
      let postUrl = `${env}/${url}`;
      if (params.device == 3) {
        url =
          params.orderType == "CN"
            ? downloadBySubOrderNumber["CNHLC"]
            : params.orderType == "OP"
            ? downloadBySubOrderNumber["OPHLC"]
            : downloadBySubOrderNumber["USHLC"];
        postUrl = `${env}/${url}?forceProduction=${forceProduction}`;
      }

      const { data } = await axios.post(postUrl, [...params.ids], {
        headers: { "jwt-token": token }
      });

      if (data.code !== 200) {
        return res.json(data);
      }
      console.log("data", data);
      let path, processDesignA, processDesignB;
      if (data.data) {
        path = data.data.path || data.data[0];
        processDesignA = data.data.processDesignA;
        processDesignB = data.data.processDesignB;
      } else {
        path = data.message;
      }

      // 转义中文
      if (path) {
        path = encodeURIComponent(path);
      }

      let files = [path];

      files = files.map(el => ({ url: `${fileEnv}${el}` }));
      let result;
      if (params.device === 4) {
        result = await downloadDTFFiles(files[0].url, targetDir);
      } else {
        const downloadFunc =
          params.device === 2 ? downloadOtherImage : downloadImage;
        result = await downloadFunc(files, {
          processDesignA,
          processDesignB
        });
      }
      console.log("result200", result);
      res.json({ code: 200, data: result });
    } catch (err) {
      console.error("Download error:", err);

      res.status(500).json({ code: 500, msg: err.message });
    }
  },
  findByPodProductionNo: async (req, res) => {
    env = getHostApi().apiApiHost;
    const token = req.headers["jwt-token"];
    const params = req.body;

    try {
      const fieldMap = {
        CN: "factorySubOrderNumber",
        US: "factorySubOrderNumber",
        GC: "thirdSubOrderNumber",
        OP: "operationNo"
      };
      let url = pathMap["findByPodProductionNo"][params.orderType];
      let paramsField = fieldMap[params.orderType];

      let { data } = await axios.get(`${env}/${url}`, {
        params: {
          [paramsField]: params.thirdSubOrderNumber,
          resizable: params.resizable
        },
        headers: { "jwt-token": token }
      });
      res.setHeader("Act-Request-URL", `${env}/${url}`);
      res.json(data);
    } catch (err) {
      res.json({ code: 500, msg: err });
    }
  },
  getCompanyList: async (req, res) => {
    try {
      let { data } = await axios.get(
        "https://platform.jomalls.com/api/tools/getCompanyList"
      );
      res.setHeader("X-Backend-Request-URL", "api/tools/getCompanyList");
      res.send(data);
    } catch (err) {
      console.log(err);
      res.json({ code: 500, msg: err });
    }
  },
  commitApply: async () => {},
  completeDelivery: async (req, res) => {
    env = getHostApi().apiApiHost;
    const token = req.headers["jwt-token"];
    const params = req.body;
    const fieldMap = {
      CN: {
        id: params.id,
        podJomallOrderCnId: params.podJomallOrderCnId || ""
      },
      US: {
        id: params.id,
        podJomallOrderUsId: params.podJomallOrderUsId || ""
      },
      GC: { id: params.id },
      OP: { ...params.data },
      DTF: params.ids
    };

    let url = pathMap["completeDelivery"][params.orderType];
    let postData = fieldMap[params.orderType];
    try {
      let { data } = await axios.post(`${env}/${url}`, postData, {
        headers: { "jwt-token": token }
      });
      res.setHeader("X-Backend-Request-URL", url);

      res.send(data);
    } catch (err) {
      console.log(err);
      res.json({ code: 500, msg: err });
    }
  },
  downloadByDesignId: async (req, res) => {
    let q = req.body;
    try {
      const desktopDevice = getCurrentDesktopDevice();
      const version = desktopDevice == 3 ? "huiLiCaiImg" : getCurrentVersion();
      console.log("version", version);

      let dir = path.join(os.homedir(), "/Desktop/" + q.productionNo + ".zip");
      const zipStream = new compressing.zip.Stream();

      for (let k in q.imgList) {
        const p = path.join(
          process.cwd(),
          `./${version}/Input/` + q.imgList[k].fileName
        );
        zipStream.addEntry(p);
      }

      const destStream = fs.createWriteStream(dir);
      zipStream
        .pipe(destStream)
        .on("finish", () => {
          // console.log("success");
          res.json({
            code: 200,
            msg: q.productionNo + ".zip" + "已下载到桌面"
          });
        })
        .on("error", () => {
          res.json({ code: 500, msg: "文件下载失败" });
        });
    } catch (err) {
      console.log(err);
      res.json({ code: 500, msg: err });
    }
  },
  uploadImage: async (req, res) => {
    try {
      const desktopDevice = getCurrentDesktopDevice();
      const version = desktopDevice == 3 ? "huiLiCaiImg" : getCurrentVersion();
      console.log("version", version);

      const p = path.join(process.cwd(), `./${version}/Input/`);
      let fileName = uuid.v4() + ".png";
      // console.log(fileName);

      const form = new multiparty.Form({ uploadDir: p });
      form.parse(req, function(err, fields, files) {
        // console.log(fields, files, err);
        if (err) {
          res.send({ code: 500, err });
        } else {
          fs.renameSync(files.file[0].path, path.join(p, fileName));
          res.json({
            code: 200,
            data: {
              fileName,
              url: path.join(process.cwd(), `./${version}/Input/` + fileName)
            }
          });
        }
      });
    } catch (err) {
      console.log(err);
      res.json({ code: 500, msg: err });
    }
  },
  getPngImg: async (req, res) => {
    try {
      const desktopDevice = getCurrentDesktopDevice();
      const version = desktopDevice == 3 ? "huiLiCaiImg" : getCurrentVersion();
      console.log("version", version);

      const filePath = path.join(
        process.cwd(),
        `./${version}/Input/${req.body.fileName}`
      );
      console.log(filePath);
      // 给客户端返回一个文件流 type类型
      res.set("content-type", { png: "image/png", jpg: "image/jpeg" }); //设置返回类型
      let stream = fs.createReadStream(filePath);
      let responseData = []; //存储文件流
      if (stream) {
        //判断状态
        stream.on("data", function(chunk) {
          responseData.push(chunk);
        });
        stream.on("end", function() {
          const finalData = Buffer.concat(responseData);
          res.write(finalData);
          res.end();
        });
      }
    } catch (err) {
      res.send({ code: 500, msg: err });
    }
  },
  login: async (req, res) => {
    try {
      env = getHostApi().apiApiHost;

      let { data } = await axios.post(`${env}/factory/login`, req.body);
      res.send(data);
    } catch (err) {
      console.log(err);
      res.json({ code: 500, msg: err });
    }
  },
  toPrint: (req, res) => {
    let body = req.body;
    writeProfileXml(body); // 写入xml文件
    // GTX6CMD.exe print -X "Profile\\CO12.xml" -I "Input\\sample.png" -A "Output\\pO12.arxp" -S 03000400 -L 02540254
    console.log(249, body);

    toSend(body)
      .then(() => {
        res.send({ code: 200, msg: "操作成功" });
      })
      .catch(err => {
        res.send({ code: 500, msg: err });
      });
  },
  checkUpdate: async (req, res) => {
    const company = "https://admin.jomalls.com";
    try {
      let q = `${company}/api/manage/rest/app/checkUpdate?version=${req.query.version}&businessType=production_assistant`;

      let { data } = await axios.get(q);
      // console.log("q", q);
      // console.log("data", data);

      if (data.data) {
        q = `${company}/api/manage/rest/app/getLatest?businessType=production_assistant`;
        let r = await axios.get(q);
        res.send(r.data);
      } else {
        res.send(data);
      }
    } catch (err) {
      console.log(err);
      res.json({ code: 500, msg: err });
    }
  },

  incrementalUpdates: async (req, res) => {
    try {
      let from = path.join(process.cwd(), "./resources/app/css.zip");
      let dirName = path.join(process.cwd(), "./resources/app/");
      let stream = fs.createWriteStream(from);
      req.body.url = visionUrl + req.body.url;
      console.log(req.body.url, "下载zip地址");
      request(req.body.url)
        .pipe(stream)
        .on("close", function() {
          compressing.zip
            .uncompress(from, dirName, { zipFileNameEncoding: "gbk" })
            .then(() => {
              fs.unlinkSync(from);
              res.json({ code: 200, msg: "更新成功" });
            })
            .catch(err => {
              res.json({ code: 500, msg: err.message });
            });
        });
    } catch (err) {
      res.json({ code: 500, msg: err.message });
    }
  },
  //裁切单个图片的透明白边
  imageTransparentEdges: async (req, res) => {
    const { inputPath, outputPath } = req.body;
    try {
      const data = await cropImageTransparentEdges(inputPath, outputPath);

      res.json({ code: 200, msg: data });
    } catch (err) {
      res.json({ code: 500, msg: err.message });
    }
  },
  //裁切图片目录中的所有图片的透明白边
  imageListTransparentEdges: async (req, res) => {
    const { inputDir, outputDir } = req.body;
    try {
      const data = await cropTransparentEdges(inputDir, outputDir);

      res.json({ code: 200, msg: data });
    } catch (err) {
      res.json({ code: 500, msg: err.message });
    }
  },
  //输入图片路径或目录
  processImage: async (req, res) => {
    const { inputPath, outputPath } = req.body;
    try {
      const data = await processImages(inputPath, outputPath);

      res.json({ code: 200, msg: data });
    } catch (err) {
      res.json({ code: 500, msg: err.message });
    }
  },

  //删除图片
  cleanDirectorySync: async (req, res) => {
    const desktopDevice = getCurrentDesktopDevice();
    const version = desktopDevice == 3 ? "huiLiCaiImg" : getCurrentVersion();
    console.log("version", version);

    let dirPath = path.join(process.cwd(), `./${version}/Input`);
    if (!fs.existsSync(dirPath)) {
      console.log(`目录不存在: ${dirPath}`);
      res.json({ code: 500, msg: `目录不存在: ${dirPath}` });
      return;
    }
    try {
      const files = fs.readdirSync(dirPath, { withFileTypes: true });
      let deletedFiles = [];
      for (const file of files) {
        const fullPath = path.join(dirPath, file.name);
        if (file.isFile() && path.extname(file.name).toLowerCase() === ".png") {
          await fs.promises.unlink(fullPath);
          deletedFiles.push(fullPath);
          console.log(`已删除文件: ${fullPath}`);
        }
      }
      res.json({ code: 200, msg: `删除成功！`, data: deletedFiles });
    } catch (error) {
      let msg = "";
      if (error.code === "ENOENT") {
        msg = `目录不存在: ${dirPath}`;
        console.warn(`目录不存在: ${dirPath}`);
      } else {
        msg = `清理错误: ${error.message}`;
        console.error(`清理错误: ${error.message}`);
      }
      res.json({ code: 205, msg: msg });
    }
  },
  saveToPng: async (req, res) => {
    try {
      const desktopDevice = getCurrentDesktopDevice();
      const version = desktopDevice == 3 ? "huiLiCaiImg" : getCurrentVersion();
      console.log("version", version);

      const p = path.join(process.cwd(), `./${version}/Input/`);
      const form = new multiparty.Form({ uploadDir: p });
      form.parse(req, function(err, fields, files) {
        // console.log(367, fields, files, err);
        if (err) {
          res.send({ code: 500, err });
        } else {
          let list = [];
          files.files.forEach(file => {
            let fileName = uuid.v4() + ".png";
            fs.renameSync(file.path, path.join(p, fileName));
            list.push({
              fileName,
              url: path.join(process.cwd(), `./${version}/Input/` + fileName)
            });
          });
          res.json({
            code: 200,
            data: list
          });
        }
      });
    } catch (err) {
      console.log(err);
      res.json({ code: 500, msg: err });
    }
  },
  //获取国家名称及代码
  getAllCountry: async (req, res) => {
    const token = req.headers["jwt-token"];
    let url = "https://factory.jomalls.com/api/logisticsAddress/getAllCountry";
    try {
      let { data } = await axios.get(url, { headers: { "jwt-token": token } });

      res.send(data);
    } catch (error) {
      console.log(error);
      res.json({ code: 500, msg: error });
    }
  },
  //复制文件夹下文件
  copySingleImageFn: async (req, res) => {
    try {
      const { imgPath, targetPath } = req.body;
      await copySingleImage(imgPath, targetPath);
      res.json({ code: 200 });
    } catch (error) {
      console.log(error);
      res.json({ code: 500, msg: error });
    }
  },

  processTransparentBackground: async (req, res) => {
    env = getHostApi().apiApiHost;
    const token = req.headers["jwt-token"];
    const { imgUrl, subOrderNumber, orderType } = req.body;

    const processTransparentBackground =
      pathMap["processTransparentBackground"];
    let url = processTransparentBackground[orderType];
    let postData = { url: imgUrl, subOrderNumber };
    try {
      let { data } = await axios.get(`${env}/${url}`, {
        params: postData,
        headers: { "jwt-token": token }
      });
      console.log("processTransparentBackground", data);
      if (data.message) {
        data.message = encodeURIComponent(data.message);
      }

      let files = data.data || [data.message];

      files = files.map(el => ({ url: `${fileEnv}${el}` }));
      console.log("processTransparentBackground,files", files);

      const result = await downloadImage(files);

      res.json({ code: 200, data: result });
    } catch (err) {
      console.log(err);
      res.json({ code: 500, msg: err });
    }
  },
  scanProduce: async (req, res) => {
    env = getHostApi().apiApiHost;
    const token = req.headers["jwt-token"];
    const params = req.body;
    let url = "factory/podOrderOperation/scan-produce";
    console.log("scanProduce", `${env}/${url}`);

    try {
      let { data } = await axios.get(`${env}/${url}`, {
        headers: { "jwt-token": token },
        params: {
          id: params.id,
          status: params.status
        }
      });
      res.send(data);
    } catch (error) {
      console.log("scanProduce", error);
      res.json({ code: 500, msg: error });
    }
  },
  checkInventory: async (req, res) => {
    env = getHostApi().apiApiHost;
    const token = req.headers["jwt-token"];
    const params = req.body;
    let url = "factory/podOrderOperation/check-inventory";
    console.log("checkInventory", `${env}/${url}`);

    try {
      let { data } = await axios.get(`${env}/${url}`, {
        headers: { "jwt-token": token },
        params: {
          id: params.id,
          status: params.status
        }
      });
      res.send(data);
    } catch (error) {
      console.log("checkInventory", error);
      res.json({ code: 500, msg: error });
    }
  },
  createBatchFolder: async (req, res) => {
    try {
      const { downloadDir, isArray, basePath } = req.body;
      const fn = isArray ? createBatchFolder : createBatchFolder;
      const data = await fn(basePath, downloadDir);
      res.send(data);
    } catch (error) {
      console.log("createBatchFolder", error);
      res.json({ code: 500, msg: error });
    }
  },
  downloadMaterial: async (req, res) => {
    try {
      const { urls, targetPath } = req.body;
      const data = await downloadPngList(urls, targetPath);
      res.send(data);
    } catch (error) {
      console.log("downloadMaterial", error);
      res.json({ code: 500, msg: error });
    }
  },
  //获取生产配置
  productionConfig: async (req, res) => {
    env = getHostApi().apiApiHost;
    const token = req.headers["jwt-token"];

    let url = pathMap["productionConfig"];

    try {
      let { data } = await axios.get(`${env}/${url}`, {
        headers: { "jwt-token": token }
      });
      res.send(data);
    } catch (error) {
      console.log("checkInventory", error);
      res.json({ code: 500, msg: error });
    }
  },
  //更新生产配置
  productionConfigUpdate: async (req, res) => {
    env = getHostApi().apiApiHost;
    const token = req.headers["jwt-token"];
    const params = req.body;
    let url = pathMap["productionConfigUpdate"];

    try {
      let { data } = await axios.post(`${env}/${url}`, params, {
        headers: { "jwt-token": token }
      });
      res.send(data);
    } catch (error) {
      console.log("checkInventory", error);
      res.json({ code: 500, msg: error });
    }
  },
  //排版列表（分页）
  productionSoftware: async (req, res) => {
    env = getHostApi().apiApiHost;
    const token = req.headers["jwt-token"];
    const params = req.body;
    let url = pathMap["productionSoftware"];

    try {
      let { data } = await axios.post(`${env}/${url}`, params, {
        headers: { "jwt-token": token }
      });
      res.send(data);
    } catch (error) {
      console.log("checkInventory", error);
      res.json({ code: 500, msg: error });
    }
  },
  //查询该批次下的所有素材
  listMaterialsByBatch: async (req, res) => {
    env = getHostApi().apiApiHost;
    const token = req.headers["jwt-token"];
    const params = req.body;
    let url = pathMap["listMaterialsByBatch"];

    try {
      let { data } = await axios.get(`${env}/${url}`, {
        headers: { "jwt-token": token },
        params
      });
      res.send(data);
    } catch (error) {
      console.log("checkInventory", error);
      res.json({ code: 500, msg: error });
    }
  },
  //重新合成排版
  psReComposingDesignImages: async (req, res) => {
    env = getHostApi().apiApiHost;
    const token = req.headers["jwt-token"];
    const params = req.body;
    let url = pathMap["psReComposingDesignImages"];

    try {
      let { data } = await axios.get(`${env}/${url}`, {
        headers: { "jwt-token": token },
        params
      });
      res.send(data);
    } catch (error) {
      console.log("checkInventory", error);
      res.json({ code: 500, msg: error });
    }
  },
  //根据批次分页查询操作单
  listOperationByBatch: async (req, res) => {
    env = getHostApi().apiApiHost;
    const token = req.headers["jwt-token"];
    const params = req.body;
    let url = pathMap["listOperationByBatch"];

    try {
      let { data } = await axios.post(`${env}/${url}`, params, {
        headers: { "jwt-token": token }
      });
      res.send(data);
    } catch (error) {
      console.log("checkInventory", error);
      res.json({ code: 500, msg: error });
    }
  },
  replenishmentComposingDesignImages: async (req, res) => {
    env = getHostApi().apiApiHost;
    const token = req.headers["jwt-token"];
    const { ids, type, templateWidth, targetDir } = req.body;
    let url = pathMap["replenishmentComposingDesignImages"];

    try {
      let { data } = await axios.post(
        `${env}/${url}?type=${type}&templateWidth=${templateWidth}`,
        ids,
        {
          headers: { "jwt-token": token }
        }
      );
      if (data.code !== 200) {
        return res.json(data);
      }
      console.log("data", data);
      let path = data.message;
      // 转义中文
      if (path) {
        path = encodeURIComponent(path);
      }
      let files = [path];
      files = files.map(el => ({ url: `${fileEnv}${el}` }));
      const result = await downloadDTFFiles(files[0].url, targetDir);
      res.json({ code: 200, data: result });
    } catch (error) {
      console.log("checkInventory", error);
      res.json({ code: 500, msg: error });
    }
  }
};
