import * as express from "express";
import { getConnection } from "typeorm";
import DeceasedRetail from "../../entity/DeceasedRetail";
import curd from "@/lib/curd/curd";
import SeletedServiceList from "@/entity/SeletedServiceList";
import Deceased from "@/entity/Deceased";
import PaymentRecord from "@/entity/Payment";
import parseRangDate, { getPaginationParams } from "@/util/globalMethods";
import { Request, Response } from "express";

const router = express.Router();

async function GetData(result) {
  const ids = Array.from(
    new Set(result.list.map((item) => Number(item.deceasedId)))
  );

  if (ids.length) {
    const manyResult = await getConnection()
      .getRepository(Deceased)
      .createQueryBuilder("deceased")
      .where("deceased.id IN (:...ids)", {
        ids,
      })
      .getMany();

    result.list = result.list.map((item: any) => {
      let findData = manyResult.find(
        (fitem: any) => fitem.id === item.deceasedId
      );

      return {
        ...item,
        deceased: findData,
      };
    });
  }
  let paymentIds = result.list
    .filter((item) => item.retailState === 1)
    .map((item) => item.id);
  if (paymentIds.length) {
    let manyResult = await getConnection()
      .getRepository(PaymentRecord)
      .createQueryBuilder("PaymentRecord")
      .where("PaymentRecord.deceased_retail_id IN (:...ids)", {
        ids: paymentIds,
      })
      .getMany();

    result.list = result.list.map((item: any) => {
      return {
        ...item,
        payment: manyResult.find((fitem) => fitem.deceasedRetailId === item.id),
      };
    });
  }
}

router.post("/query", async (req: Request, res: Response) => {
  try {
    const {
      pageNumber = 1,
      pageSize = 10,
      deceased = {},
      retail = {},
    } = req.body;

    // 参数校验
    const connection = getConnection();
    const queryBuilder = connection
      .getRepository(DeceasedRetail)
      .createQueryBuilder("retail")
      .leftJoinAndMapOne(
        "retail.deceased",
        Deceased,
        "deceased",
        "deceased.id = retail.deceased_id"
      )
      .leftJoinAndMapOne(
        "retail.payment",
        PaymentRecord,
        "payment",
        "payment.deceased_retail_id = retail.id"
      )
      .where(`retail.cancel_state = 0`)
      .andWhere("retail.retail_type = :retailType", {
        retailType: retail.retailType ?? 0,
      });

    req.body.startDate = retail.startDate;
    req.body.endDate = retail.endDate;
    let { startDate, endDate } = parseRangDate(req);
    if (retail.retailType === 2) {
      if (retail.familyName) {
        queryBuilder.andWhere("retail.familyName LIKE :familyName", {
          familyName: `%${retail.familyName}%`,
        });
      }
      if (deceased.name) {
        queryBuilder.andWhere("retail.deceased_Name LIKE :name", {
          name: `%${deceased.name}%`,
        });
      }
    }
    if (retail.retailType === 1) {
      if (deceased.name) {
        queryBuilder.andWhere("deceased.name LIKE :name", {
          name: `%${deceased.name}%`,
        });
      }
      if (retail.familyName) {
        queryBuilder.andWhere("retail.familyName LIKE :familyName", {
          familyName: `%${retail.familyName}%`,
        });
      }
    }
    if (startDate && endDate) {
      queryBuilder
        .andWhere(`retail.purchaseDate BETWEEN :start AND :end`)
        .setParameters({ start: startDate, end: endDate });
    }

    if (retail.guide) {
      queryBuilder.andWhere(`retail.guide LIKE :guide`, {
        guide: retail.guide,
      });
    }

    // 执行分页查询
    const [list, total] = await queryBuilder
      .orderBy("retail.createDate", "DESC")
      .skip((pageNumber - 1) * pageSize)
      .take(pageSize)
      .getManyAndCount();

    let result = {
      list,
      total,
      pageSize,
      pageNumber,
    };
    await GetData(result);

    res.json({
      code: 200,
      data: result,
    });
  } catch (err) {
    console.error("查询失败:", err);
    res.status(500).json({
      code: 500,
      msg: process.env.NODE_ENV === "production" ? "服务器错误" : err.message,
    });
  }
});

router.get("/list", async (req, res) => {
  try {
    let { retailType } = req.method === "GET" ? req.query : req.body;
    let queryBuilder = getConnection()
      .getRepository(DeceasedRetail)
      .createQueryBuilder("dr")
      .where(`dr.retailType=${retailType}`)
      .andWhere(`dr.cancelState = 0`);

    const { pageSize, pageNumber } = getPaginationParams(req);

    let [list, total] = await queryBuilder
      .orderBy("dr.createDate", "DESC")
      .skip((pageNumber - 1) * pageSize)
      .take(pageSize)
      .getManyAndCount();
    let result = {
      list,
      pageNumber,
      pageSize,
      total,
    };

    await GetData(result);
    res.status(200).send({ code: 200, data: result });
  } catch (err) {
    res.status(500).send({ code: 500, msg: err.message });
  }
});

/**
 * retailId: 销售单ID
 * deceasedId： 人的ID，且必须传retailType
 */
router.get("/selected-service", async (req, res) => {
  let retailId = req.query.retailId;
  let deceasedId = req.query.deceasedId;
  let retailType = req.query.retailType;
  try {
    let retail;
    if (retailId) {
      if (retailType && Number(retailType) === 2) {
        retail = await getConnection()
          .getRepository(DeceasedRetail)
          .findOne({
            where: {
              id: Number(retailId),
              retailType,
            },
          });
      } else {
        retail = await getConnection()
          .getRepository(DeceasedRetail)
          .findOne(Number(retailId));
      }
    }
    if (deceasedId) {
      retail = await getConnection()
        .getRepository(DeceasedRetail)
        .createQueryBuilder("deceasedRetail")
        .where("deceasedRetail.retail_type = :retailType", {
          retailType,
        })
        .andWhere("deceasedRetail.deceased_id = :deceasedId", {
          deceasedId,
        })
        .getOne();
    }
    if (!retail) return res.status(200).send({ code: 200, data: { list: [] } });

    const ids = retail.serviceItems
      ? retail.serviceItems.split(",").map((id) => Number(id))
      : [];

    if (!ids.length)
      return res.status(200).send({ code: 200, data: { list: [] } });
    const result = await getConnection()
      .getRepository(SeletedServiceList)
      .createQueryBuilder("seleted_service_list")
      .where("seleted_service_list.id IN (:...ids)", {
        ids,
      })
      .getMany();

    res.status(200).send({ code: 200, data: { list: result } });
  } catch (err) {
    res.status(500).send({ code: 500, msg: err.message });
  }
});

router.get("/checkout", async (req, res) => {
  let { id } = req.query;
  if (!id) {
    return res.status(500).send({ code: 500, msg: "未传入结账id" });
  }

  let deceasedRetailRep = getConnection().getRepository(DeceasedRetail);
  let deceasedRetail = await deceasedRetailRep.findOne(Number(id));

  if (!deceasedRetail)
    return res.status(500).send({ code: 500, msg: "该记录不存在" });

  deceasedRetail.retailState = 1;

  await deceasedRetailRep.save(deceasedRetail);

  res.status(200).send({ code: 200, data: deceasedRetail, msg: "结账成功！" });
});

// 添加逝者零售
router.post("/add", async (req, res) => {
  delete req.body.id;
  const connection = getConnection();
  try {
    const tempServiceItems = req.body.services.map((item) => {
      delete item.id;

      return item;
    });
    req.body.serviceItems = "";

    const deceasedRetailRep = connection.getRepository(DeceasedRetail);
    const newDeceasedRetail = await curd({ entity: DeceasedRetail, req }).add();

    if (tempServiceItems.length) {
      tempServiceItems.forEach((item) => {
        item.retailId = newDeceasedRetail.id;
      });
      let executeData = await connection
        .getRepository(SeletedServiceList)
        .save(tempServiceItems);

      newDeceasedRetail.serviceItems = executeData
        .map((item) => item.id)
        .join(",");

      await deceasedRetailRep.save(newDeceasedRetail);
    }

    res.send({ code: 200, msg: "逝者零售添加成功", data: newDeceasedRetail });
  } catch (err) {
    res.status(500).send({ code: 500, msg: err.message });
  }
});

router.post("/updateRetail", async (req, res) => {
  const connection = getConnection();
  try {
    const tempServiceItems = req.body.services.map((item) => {
      return item;
    });
    req.body.serviceItems = "";

    const deceasedRetailRep = connection.getRepository(DeceasedRetail);
    let newDeceasedRetail = await deceasedRetailRep.findOne({
      id: req.body?.retail?.id,
    });

    if (!newDeceasedRetail) {
      newDeceasedRetail = await deceasedRetailRep.findOne({
        where: { deceasedId: req.body.deceasedId, retailType: 0 },
      });
    }

    if (tempServiceItems.length) {
      tempServiceItems.forEach((item) => {
        item.retailId = newDeceasedRetail.id;
        item.updateDate = new Date();
        item.createDate = new Date();
      });

      const ids = newDeceasedRetail.serviceItems
        .split(",")
        .map((id) => Number(id));
      if (ids.length) {
        await connection
          .getRepository(SeletedServiceList)
          .createQueryBuilder("seleted_service_list")
          .where("seleted_service_list.id IN (:...ids)", {
            ids,
          })
          .delete()
          .execute();
      }

      let executeData = await connection
        .getRepository(SeletedServiceList)
        .save(tempServiceItems);

      newDeceasedRetail.salesAmount = req.body.salesAmount;

      newDeceasedRetail.serviceItems = executeData
        .map((item) => item.id)
        .join(",");

      // 保存人
      let deceased = await connection
        .getRepository(Deceased)
        .findOne(req.body.id);
      if (deceased) {
        deceased = { ...deceased, ...req.body.deceased };
        deceased.salesAmount = newDeceasedRetail.salesAmount;

        await connection.getRepository(Deceased).save(deceased);
      }
    } else {
      const ids = newDeceasedRetail.serviceItems
        .split(",")
        .map((id) => Number(id));
      if (ids.length) {
        await connection
          .getRepository(SeletedServiceList)
          .createQueryBuilder("seleted_service_list")
          .where("seleted_service_list.id IN (:...ids)", {
            ids,
          })
          .delete()
          .execute();
      }
      newDeceasedRetail.serviceItems = "";
    }

    await deceasedRetailRep.save(newDeceasedRetail);

    res.send({ code: 200, msg: "逝者服务单修改成功", data: newDeceasedRetail });
  } catch (err) {
    res.status(500).send({ code: 500, msg: err.message });
  }
});

// 更新逝者信息
router.post("/update", async (req, res) => {
  const id = Number(req.body.id);

  if (!id) {
    return res.send({ code: 400, msg: "逝者ID不能为空！" });
  }

  try {
    const connection = getConnection();
    const deceasedRepository = connection.getRepository(DeceasedRetail);
    const deceasedRep = connection.getRepository(Deceased);

    let services = req.body.retail?.services || req.body.services;
    const tempServiceItems = services.map((item) => {
      delete item.id;

      return item;
    });

    let findData = await deceasedRepository.findOne(id);

    let decease = await deceasedRep.findOne(Number(findData.deceasedId));

    const ids = findData.serviceItems.split(",").map((id) => Number(id));
    if (ids.length) {
      await connection
        .getRepository(SeletedServiceList)
        .createQueryBuilder("seleted_service_list")
        .where("seleted_service_list.id IN (:...ids)", {
          ids,
        })
        .delete()
        .execute();
    }

    findData = { ...findData, ...req.body };
    if (tempServiceItems.length) {
      tempServiceItems.forEach((item) => {
        item.retailId = id;
        item.hasDeceased = 0;
        item.updateDate = new Date();
        item.createDate = new Date();
      });
      let executeData = await connection
        .getRepository(SeletedServiceList)
        .save(tempServiceItems);

      findData.serviceItems = executeData.map((item) => item.id).join(",");
    }
    let newDeceased: Deceased = { ...req.body };
    delete newDeceased.id;

    decease = { ...decease, ...newDeceased };

    await deceasedRep.save(decease);
    await deceasedRepository.save(findData);

    res.send({ code: 200, msg: "更新成功", data: findData });
  } catch (err) {
    res.status(500).send({ code: 500, msg: err.message });
  }
});

// 删除逝者信息
router.get("/delete", async (req, res) => {
  const id = Number(req.query.id);

  if (!id) {
    return res.send({ code: 400, msg: "数据ID不能为空！" });
  }

  try {
    const connection = getConnection();
    const deceasedRepository = connection.getRepository(DeceasedRetail);

    const findData = await deceasedRepository.findOne(id);

    const ids = findData.serviceItems.split(",").map((id) => Number(id));
    if (ids.length) {
      await connection
        .getRepository(SeletedServiceList)
        .createQueryBuilder("seleted_service_list")
        .where("seleted_service_list.id IN (:...ids)", {
          ids,
        })
        .delete()
        .execute();
    }
    await deceasedRepository.remove(findData);

    res.send({ code: 200, msg: "删除成功！" });
  } catch (err) {
    res.status(500).send({ code: 500, msg: err.message });
  }
});

export default router;
