package com.bonus.material.toolProcess.service.Impl;

import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.security.utils.SecurityUtils;
import com.bonus.material.devchange.mapper.MaDevInfoMapper;
import com.bonus.material.device.domain.vo.DevInfoPropertyVo;
import com.bonus.material.device.mapper.DevMergeMapper;
import com.bonus.material.tool.domain.ToolEntity;
import com.bonus.material.toolLedger.domain.ToolLedgerEntity;
import com.bonus.material.toolLedger.mapper.ToolLedgerMapper;
import com.bonus.material.toolProcess.domain.ToolApplyDetailsEntity;
import com.bonus.material.toolProcess.domain.ToolApplyEntity;
import com.bonus.material.toolProcess.mapper.ToolApplyMapper;
import com.bonus.material.toolProcess.service.ToolApplyService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import static com.bonus.common.biz.constant.MaterialConstants.ADMIN_ID;
import static com.bonus.common.biz.constant.MaterialConstants.PROVINCE_COMPANY_DEPT_ID;

@Service
public class ToolApplyServiceImpl implements ToolApplyService {
    private static final Logger log = LoggerFactory.getLogger(ToolApplyServiceImpl.class);
    @Resource
    private ToolApplyMapper toolApplyMapper;
    @Resource
    private ToolLedgerMapper toolLedgerMapper;
    @Resource
    private DevMergeMapper devMergeMapper;
    @Autowired
    private MaDevInfoMapper maDevInfoMapper;

    /**
     * 工具申请单表格
     *
     * @param entity 实体
     * @return 表格
     */
    @Override
    public List<ToolApplyEntity> list(ToolApplyEntity entity) {
        Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
        Long userId = SecurityUtils.getLoginUser().getUserid();
        // 管理员和省公司可查看所有数据
        if (userId != null && deptId != null
                && !userId.equals(ADMIN_ID)
                && !deptId.equals(PROVINCE_COMPANY_DEPT_ID)) {
            entity.setCompanyId(deptId);
        }
        return toolApplyMapper.list(entity);
    }

    /**
     * 工具录入新增
     *
     * @param entity 实体
     * @return 结果
     */
    @Override
    public AjaxResult add(ToolApplyEntity entity) {
        try {
            entity.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
            entity.setCompanyId(SecurityUtils.getLoginUser().getSysUser().getDeptId());
            Integer num = toolApplyMapper.add(entity);
            return num > 0 ? AjaxResult.success(entity) : AjaxResult.error("新增失败");
        } catch (Exception e) {
            log.error(e.getMessage());
            return AjaxResult.error("新增失败");
        }
    }


    /**
     * 工具录入删除
     *
     * @param entity 实体
     * @return 结果
     */
    @Override
    public AjaxResult delete(ToolApplyEntity entity) {
        try {
            Integer num = toolApplyMapper.delete(entity);
            return num > 0 ? AjaxResult.success("删除成功") : AjaxResult.error("删除失败");
        } catch (Exception e) {
            log.error(e.getMessage());
            return AjaxResult.error("删除失败");
        }
    }

    /**
     * 工具录入申请单表格
     *
     * @param entity 实体
     * @return 表格
     */
    @Override
    public List<ToolApplyDetailsEntity> listByApplyId(ToolApplyDetailsEntity entity) {
        List<ToolApplyDetailsEntity> toolApplyDetailsEntities = toolApplyMapper.listByApplyId(entity);
        toolApplyDetailsEntities.forEach(item -> {
            item.setCertificates(maDevInfoMapper.getFileList(item.getId() + 200000, 2));
            item.setInspectionReports(maDevInfoMapper.getFileList(item.getId() + 200000, 3));
            item.setPurchaseInvoices(maDevInfoMapper.getFileList(item.getId() + 200000, 4));
        });
        return toolApplyDetailsEntities;
    }

    /**
     * 工具录入订单删除
     *
     * @param entity 实体
     * @return 结果
     */
    @Override
    public AjaxResult deleteDetail(ToolApplyDetailsEntity entity) {
        try {
            Integer num = toolApplyMapper.deleteDetail(entity);
            return num > 0 ? AjaxResult.success("删除成功") : AjaxResult.error("删除失败");
        } catch (Exception e) {
            log.error(e.getMessage());
            return AjaxResult.error("删除失败");
        }
    }

    /**
     * 新增设备详情
     *
     * @param entity 实体
     * @return 结果
     */
    @Override
    public AjaxResult addDetail(List<ToolApplyDetailsEntity> entity) {
        try {
            for (ToolApplyDetailsEntity detail : entity) {
                toolApplyMapper.deleteTool(detail.getId());
                Integer num = toolApplyMapper.addDetail(detail);
                if (num > 0) {
                    detail.getCertificates().forEach(item -> {
                        // 这里编写对每个 image 的处理逻辑，比如打印、处理等
                        item.setFileType(2);
                        item.setMaId(detail.getId() + 200000);
                        item.setCreator(Math.toIntExact(SecurityUtils.getLoginUser().getUserid()));
                        devMergeMapper.interFile(item);
                    });

                    detail.getInspectionReports().forEach(item -> {
                        // 这里编写对每个 image 的处理逻辑，比如打印、处理等
                        item.setFileType(3);
                        item.setMaId(detail.getId() + 200000);
                        item.setCreator(Math.toIntExact(SecurityUtils.getLoginUser().getUserid()));
                        devMergeMapper.interFile(item);
                    });

                    detail.getPurchaseInvoices().forEach(item -> {
                        // 这里编写对每个 image 的处理逻辑，比如打印、处理等
                        item.setFileType(4);
                        item.setMaId(detail.getId() + 200000);
                        item.setCreator(Math.toIntExact(SecurityUtils.getLoginUser().getUserid()));
                        devMergeMapper.interFile(item);
                    });
                }

            }
            return AjaxResult.success("新增成功");
        } catch (Exception e) {
            log.error(e.getMessage());
            return AjaxResult.error("新增失败");
        }
    }

    /**
     * 工具类型树
     *
     * @param entity 实体
     * @return 树结构
     */
    @Override
    public AjaxResult getTreeSelect(ToolEntity entity) {
        // 1. 按条件查询目标节点（符合筛选条件的节点）
        List<ToolEntity> allNodes = toolApplyMapper.getTreeSelect(entity);
        // 2. 找出所有根节点（parent_id = null 或 parent_id = 0，根据业务调整）
        List<ToolEntity> rootNodes = allNodes.stream().filter(node -> node.getParentId() == null || node.getParentId() == 0).collect(Collectors.toList());
        // 3. 为每个根节点递归添加子节点
        for (ToolEntity root : rootNodes) {
            addChildren(root, allNodes);
        }
        return AjaxResult.success(rootNodes);
    }

    /**
     * 修改订单状态
     *
     * @param entity 条件
     * @return 条数
     */
    @Override
    public AjaxResult update(ToolApplyEntity entity) {
        try {
            Integer num = toolApplyMapper.update(entity);
            return num > 0 ? AjaxResult.success("修改成功") : AjaxResult.error("修改失败");
        } catch (Exception e) {
            log.error(e.getMessage());
            return AjaxResult.error("修改失败");
        }
    }

    /**
     * 修改订单装备状态
     *
     * @param entity 条件
     * @return 条数
     */
    @Override
    public AjaxResult updateDetail(ToolApplyDetailsEntity entity) {
        try {
            //查询要修改的数据
            List<Long> longs = toolApplyMapper.selectDetailIdsByCondition(entity);
            Integer num = toolApplyMapper.updateDetail(entity);
            if (entity.getStatus().equals("2") && num > 0) {
                //插入台账表
                List<ToolApplyDetailsEntity> toolApplyDetailsEntities = toolApplyMapper.listById(longs);
                addToolLedger(toolApplyDetailsEntities);
            }
            Integer i = toolApplyMapper.getCount(entity.getApplyId());
            if (i == 0) {
                ToolApplyEntity applyEntity = new ToolApplyEntity();
                applyEntity.setId(entity.getApplyId());
                applyEntity.setStatus("2");
                toolApplyMapper.update(applyEntity);
            }
            return num > 0 ? AjaxResult.success("修改成功") : AjaxResult.error("修改失败");
        } catch (Exception e) {
            log.error(e.getMessage());
            return AjaxResult.error("修改失败");
        }
    }

    private void addToolLedger(List<ToolApplyDetailsEntity> toolApplyDetailsEntities) {
        toolApplyDetailsEntities.forEach(item -> {

            if (item.getManageType().equals("0")) {
                ToolLedgerEntity toolLedgerEntity = new ToolLedgerEntity();
                toolLedgerEntity.setTypeId(item.getTypeId());
                toolLedgerEntity.setManageMode(Integer.valueOf(item.getManageType()));
                toolLedgerEntity.setCompanyId(SecurityUtils.getLoginUser().getSysUser().getDeptId());
                toolLedgerEntity.setOriginCost(item.getToolPrice());
                toolLedgerEntity.setIdentifyCode(item.getIdentifyCode());
                toolLedgerEntity.setSupplierId(item.getSupplierId());
                toolLedgerEntity.setProductionDate(item.getProductionDate());
                toolLedgerEntity.setTotalNum(item.getApplyNum());
                toolLedgerEntity.setAvailableNum(item.getApplyNum());
                toolLedgerEntity.setToolCode(toolLedgerMapper.getCode());

                toolLedgerMapper.add(toolLedgerEntity);
                toolLedgerEntity.setCertificates(maDevInfoMapper.getFileList(Math.toIntExact(item.getId() + 200000L), 2));
                maDevInfoMapper.delFileList(Math.toIntExact(item.getId() + 200000L), 2);
                toolLedgerEntity.setInspectionReports(maDevInfoMapper.getFileList(Math.toIntExact(item.getId() + 200000L), 3));
                maDevInfoMapper.delFileList(Math.toIntExact(item.getId() + 200000L), 3);
                toolLedgerEntity.setPurchaseInvoices(maDevInfoMapper.getFileList(Math.toIntExact(item.getId() + 200000L), 4));
                maDevInfoMapper.delFileList(Math.toIntExact(item.getId() + 200000L), 4);
                toolLedgerEntity.getCertificates().forEach(file -> {
                    // 这里编写对每个 image 的处理逻辑，比如打印、处理等
                    file.setFileType(2);
                    file.setMaId(Math.toIntExact(toolLedgerEntity.getId() + 100000L));
                    file.setCreator(Math.toIntExact(SecurityUtils.getLoginUser().getUserid()));
                    devMergeMapper.interFile(file);
                });

                toolLedgerEntity.getInspectionReports().forEach(file -> {
                    // 这里编写对每个 image 的处理逻辑，比如打印、处理等
                    file.setFileType(3);
                    file.setMaId(Math.toIntExact(toolLedgerEntity.getId() + 100000L));
                    file.setCreator(Math.toIntExact(SecurityUtils.getLoginUser().getUserid()));
                    devMergeMapper.interFile(file);
                });

                toolLedgerEntity.getPurchaseInvoices().forEach(file -> {
                    // 这里编写对每个 image 的处理逻辑，比如打印、处理等
                    file.setFileType(4);
                    file.setMaId(Math.toIntExact(toolLedgerEntity.getId() + 100000L));
                    file.setCreator(Math.toIntExact(SecurityUtils.getLoginUser().getUserid()));
                    devMergeMapper.interFile(file);
                });
                item.setToolId(toolLedgerEntity.getId());
                toolApplyMapper.updateByToolId(item);
            } else {
                ToolLedgerEntity byType = toolLedgerMapper.getByType(item.getTypeId(),SecurityUtils.getLoginUser().getSysUser().getDeptId());
                if (byType != null) {
                    BigDecimal totalNum = byType.getTotalNum();
                    BigDecimal applyNum = item.getApplyNum();
                    BigDecimal availableNum = byType.getAvailableNum();
                    // 处理 null：如果为 null 视为 0
                    totalNum = (totalNum == null) ? BigDecimal.ZERO : totalNum;
                    applyNum = (applyNum == null) ? BigDecimal.ZERO : applyNum;
                    availableNum = (availableNum == null) ? BigDecimal.ZERO : availableNum;
                    // 调用 add()         方法求和，重新设置值
                    byType.setTotalNum(totalNum.add(applyNum));
                    byType.setAvailableNum(availableNum.add(applyNum));
                    byType.setOriginCost(item.getToolPrice());
                    toolLedgerMapper.updateByTypeAndId(byType);
                    item.setToolId(byType.getId());
                    toolApplyMapper.updateByToolId(item);
                } else {
                    ToolLedgerEntity toolLedgerEntity = new ToolLedgerEntity();
                    toolLedgerEntity.setTypeId(item.getTypeId());
                    toolLedgerEntity.setManageMode(Integer.valueOf(item.getManageType()));
                    toolLedgerEntity.setCompanyId(SecurityUtils.getLoginUser().getSysUser().getDeptId());
                    toolLedgerEntity.setTotalNum(item.getApplyNum());
                    toolLedgerEntity.setAvailableNum(item.getApplyNum());
                    toolLedgerEntity.setOriginCost(item.getToolPrice());

                    toolLedgerMapper.add(toolLedgerEntity);

                    toolLedgerEntity.setCertificates(maDevInfoMapper.getFileList(Math.toIntExact(item.getId() + 200000L), 2));
                    maDevInfoMapper.delFileList(Math.toIntExact(item.getId() + 200000L), 2);
                    toolLedgerEntity.setInspectionReports(maDevInfoMapper.getFileList(Math.toIntExact(item.getId() + 200000L), 3));
                    maDevInfoMapper.delFileList(Math.toIntExact(item.getId() + 200000L), 3);
                    toolLedgerEntity.setPurchaseInvoices(maDevInfoMapper.getFileList(Math.toIntExact(item.getId() + 200000L), 4));
                    maDevInfoMapper.delFileList(Math.toIntExact(item.getId() + 200000L), 4);
                    toolLedgerEntity.getCertificates().forEach(file -> {
                        // 这里编写对每个 image 的处理逻辑，比如打印、处理等
                        file.setFileType(2);
                        file.setMaId(Math.toIntExact(toolLedgerEntity.getId() + 100000L));
                        file.setCreator(Math.toIntExact(SecurityUtils.getLoginUser().getUserid()));
                        devMergeMapper.interFile(file);
                    });

                    toolLedgerEntity.getInspectionReports().forEach(file -> {
                        // 这里编写对每个 image 的处理逻辑，比如打印、处理等
                        file.setFileType(3);
                        file.setMaId(Math.toIntExact(toolLedgerEntity.getId() + 100000L));
                        file.setCreator(Math.toIntExact(SecurityUtils.getLoginUser().getUserid()));
                        devMergeMapper.interFile(file);
                    });

                    toolLedgerEntity.getPurchaseInvoices().forEach(file -> {
                        // 这里编写对每个 image 的处理逻辑，比如打印、处理等
                        file.setFileType(4);
                        file.setMaId(Math.toIntExact(toolLedgerEntity.getId() + 100000L));
                        file.setCreator(Math.toIntExact(SecurityUtils.getLoginUser().getUserid()));
                        devMergeMapper.interFile(file);
                    });

                    item.setToolId(toolLedgerEntity.getId());
                    toolApplyMapper.updateByToolId(item);
                }
            }
        });
    }

    /**
     * 修改订单装备状态
     *
     * @param entity 条件
     * @return 条数
     */
    @Override
    public AjaxResult updateAllDetail(ToolApplyDetailsEntity entity) {
        try {
            ToolApplyEntity applyEntity = new ToolApplyEntity();
            applyEntity.setId(entity.getApplyId());
            applyEntity.setStatus("2");
            toolApplyMapper.update(applyEntity);
            List<Long> longs = toolApplyMapper.selectAllDetailIdsByApplyId(entity);
            Integer num = toolApplyMapper.updateAllDetail(entity);
            if (entity.getStatus().equals("2") && num > 0) {
                List<ToolApplyDetailsEntity> toolApplyDetailsEntities = toolApplyMapper.listById(longs);
                addToolLedger(toolApplyDetailsEntities);
            }
            return num > 0 ? AjaxResult.success("修改成功") : AjaxResult.error("修改失败");
        } catch (Exception e) {
            log.error(e.getMessage());
            return AjaxResult.error("修改失败");
        }
    }

    /**
     * 获取审核列表
     *
     * @param entity 实体
     * @return 表格
     */
    @Override
    public List<ToolApplyEntity> listReview(ToolApplyEntity entity) {
        Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
        Long userId = SecurityUtils.getLoginUser().getUserid();
        // 管理员和省公司可查看所有数据
        if (userId != null && deptId != null
                && !userId.equals(ADMIN_ID)
                && !deptId.equals(PROVINCE_COMPANY_DEPT_ID)) {
            entity.setCompanyId(deptId);
        }
        return toolApplyMapper.listReview(entity);
    }

    /**
     * @param entity
     * @return
     */
    @Override
    public List<ToolApplyDetailsEntity> listEncoding(ToolApplyDetailsEntity entity) {
        return toolApplyMapper.listEncoding(entity);
    }

    /**
     * @param id
     * @return
     */
    @Override
    public AjaxResult deleteTool(Integer id) {
        try {
            Integer num = toolApplyMapper.deleteTool(id);
            return num > 0 ? AjaxResult.success("修改成功") : AjaxResult.error("修改失败");
        } catch (Exception e) {
            log.error(e.getMessage());
            return AjaxResult.error("修改失败");
        }
    }

    /**
     * @param entity
     * @return
     */
    @Override
    public AjaxResult listWarehousingToolByApplyId(ToolApplyDetailsEntity entity) {
        List<ToolApplyDetailsEntity> toolApplyDetailsEntities = toolApplyMapper.listWarehousingToolByApplyId(entity);
        toolApplyDetailsEntities.forEach(item -> {
            item.setCertificates(maDevInfoMapper.getFileList(item.getId() + 200000, 2));
            item.setInspectionReports(maDevInfoMapper.getFileList(item.getId() + 200000, 3));
            item.setPurchaseInvoices(maDevInfoMapper.getFileList(item.getId() + 200000, 4));
        });
        return AjaxResult.success(toolApplyDetailsEntities);
    }


    /**
     * 递归为父节点添加子节点
     *
     * @param parent   父节点
     * @param allNodes 所有节点列表
     */
    private void addChildren(ToolEntity parent, List<ToolEntity> allNodes) {
        // 筛选当前父节点的子节点（parent_id = 父节点的 type_id）
        List<ToolEntity> children = allNodes.stream().filter(node -> parent.getTypeId().equals(node.getParentId())).collect(Collectors.toList());
        // 为父节点设置子节点
        parent.setChildren(children);

        // 递归为子节点添加它们的子节点
        for (ToolEntity child : children) {
            addChildren(child, allNodes);
        }
    }
}
