package com.zzsmart.qomo.kn.cost.manage.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzsmart.qomo.dao.entity.FlowInstance;
import com.zzsmart.qomo.dao.entity.FlowInstanceParameter;
import com.zzsmart.qomo.kn.cost.manage.entity.*;
import com.zzsmart.qomo.kn.cost.manage.enums.CostCountStatusEnum;
import com.zzsmart.qomo.kn.cost.manage.enums.FeeTypeEnum;
import com.zzsmart.qomo.kn.cost.manage.mapper.AppSceneCostCountMapper;
import com.zzsmart.qomo.kn.cost.manage.mapper.AppSceneCostPartMissingInfoMapper;
import com.zzsmart.qomo.kn.cost.manage.plugin.StandardCostService;
import com.zzsmart.qomo.kn.cost.manage.service.IAppSceneCostActualService;
import com.zzsmart.qomo.kn.cost.manage.service.IAppSceneCostCountService;
import com.zzsmart.qomo.kn.cost.manage.service.IAppSceneCostStandardVersionService;
import com.zzsmart.qomo.kn.cost.manage.vo.AppSceneCostCountVO;
import com.zzsmart.qomo.kn.cost.manage.vo.BatchCount;
import com.zzsmart.qomo.kn.cost.manage.vo.MatnrVersionVO;
import com.zzsmart.qomo.kn.cost.manage.vo.MissingComponentVO;
import com.zzsmart.qomo.service.IDataFlowInstanceService;
import com.zzsmart.qomo.service.IFlowInstanceParameterService;
import net.sf.jsqlparser.expression.DateTimeLiteralExpression;
import org.jeecg.common.api.vo.Result;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Description: app_scene_cost_count
 * @Author: jeecg-boot
 * @Date: 2024-07-29
 * @Version: V1.0
 */
@Service
public class AppSceneCostCountServiceImpl extends ServiceImpl<AppSceneCostCountMapper, AppSceneCostCount> implements IAppSceneCostCountService {
    @Autowired
    private IAppSceneCostStandardVersionService costStandardVersionService;
    @Autowired
    private IDataFlowInstanceService flowInstanceService;
    @Autowired
    private IFlowInstanceParameterService flowInstanceParameterService;
    @Autowired
    private AppSceneCostPartMissingInfoMapper costPartMissingInfoMapper;
    @Autowired
    private IAppSceneCostActualService iAppSceneCostActualService;


    /**
     * 查看关键缺失部件
     *
     * @param id
     * @return
     */
    @Override
    public List<MissingComponentVO> queryMissingComponentById(String id) {
        List<MissingComponentVO> list = new ArrayList<>();
        if (id != null) {
            QueryWrapper<AppSceneCostPartMissingInfo> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("costStandardId", id);
            List<AppSceneCostPartMissingInfo> costPartMissingInfos = costPartMissingInfoMapper.selectList(queryWrapper);
            if (costPartMissingInfos != null && costPartMissingInfos.size() > 0) {
                for (int i = 0; i < costPartMissingInfos.size(); i++) {
                    AppSceneCostPartMissingInfo costPartMissingInfo = costPartMissingInfos.get(i);
                    if (costPartMissingInfo.getMissingInfo() != null) {
                        String[] split = costPartMissingInfo.getMissingInfo().split(";");
                        for (int j = 0; j < split.length; j++) {
                            MissingComponentVO temp = MissingComponentVO.builder().materialNumber(costPartMissingInfo.getMaterialNumber()).missingInfo(split[j]).versionNumber(costPartMissingInfo.getVersionNumber()).build();
                            list.add(temp);
                        }
                    }
                }
            }
        }
        return list;
    }

    /**
     * 重新计算
     *
     * @param id
     * @return
     */
    @Override
    public AppSceneCostCount recountById(Integer id) {
        if (id != null) {
            AppSceneCostCount appSceneCostCount = getById(id);
            if (appSceneCostCount != null) {
                //执行标准成本计算
                executeStandardCost(id, appSceneCostCount.getFlowDefinitionId(), appSceneCostCount.getMaterialNo());
            }
        }
        return null;
    }

    /**
     * 执行标准成本计算
     *
     * @param id
     * @param flowDefinitionId
     */
    private void executeStandardCost(Integer id, Integer flowDefinitionId, String meterialNo) {
        boolean isSuccess = false;
        JSONObject parameter = new JSONObject();
        parameter.put("materialNo", meterialNo);
        String parameters = JSON.toJSONString(parameter);
        //执行标准成本计算(参数传递)
        FlowInstance flowInstance = ((IDataFlowInstanceService) flowInstanceService).execute(flowDefinitionId, (String) null, (String) null);
        if (flowInstance != null) {
            FlowInstanceParameter flowInstanceParameter = new FlowInstanceParameter();
            flowInstanceParameter.setFlowInstanceId(flowInstance.getId());
            flowInstanceParameter.setParameters(parameters);
            boolean save = flowInstanceParameterService.save(flowInstanceParameter);
            if (save) {
                isSuccess = true;
            }
        }
//        flowInstanceService.execute(flowDefinitionId, null, null);
    }

    /**
     * 添加标准成本计算任务
     *
     * @param appSceneCostCount
     */
    @Override
    public void addCostCountTask(AppSceneCostCountVO appSceneCostCount) {
        //1.新增版本号记录成功后
        //appSceneCostCount.setCostVersion("Version"+String.valueOf(new Random().nextInt(100000)));
        AppSceneCostStandardVersion costStandardVersion = AppSceneCostStandardVersion.builder()
                .graphicnumber(appSceneCostCount.getDrawingNo())
                .matnr(appSceneCostCount.getMaterialNo())
                .stage(appSceneCostCount.getStage())
                .version(appSceneCostCount.getCostVersion())
                .versionYear(appSceneCostCount.getYear())
                .werks(appSceneCostCount.getWerks())
                .build();
        costStandardVersion.setCreatedtime(new Date());
        boolean save = costStandardVersionService.save(costStandardVersion);
        //2.新增标准成本计算任务，并立即执行标准成本计算
        if (save) {
            AppSceneCostCount appSceneCostCount1 = AppSceneCostCount.builder()
                    .materialNo(appSceneCostCount.getMaterialNo())
                    .stage(appSceneCostCount.getStage())
                    .flowDefinitionId(appSceneCostCount.getFlowDefinitionId())
                    .year(appSceneCostCount.getYear())
                    .costVersion(costStandardVersion.getVersion())
                    .status(CostCountStatusEnum.Executing.getValue())
                    .werks(appSceneCostCount.getWerks())
                    .createTime(new Date())
                    .build();
            boolean flag = save(appSceneCostCount1);
            //方案一：模型组件运行
//            if (flag) {
//                //发送更新成本计算状态的队列消息（队列名:updateCostCountStatus）
//
//                //执行标准成本计算
//                executeStandardCost(appSceneCostCount1.getId(), appSceneCostCount1.getFlowDefinitionId(), appSceneCostCount.getMaterialNo());
//                //TODO 新增部件缺失信息记录
//                AppSceneCostPartMissingInfo costPartMissingInfo = AppSceneCostPartMissingInfo.builder().costStandardId(appSceneCostCount1.getId().toString()).materialNumber(appSceneCostCount1.getMaterialNo()).versionNumber(appSceneCostCount1.getCostVersion()).missingInfo("电源线;绝缘层涂料").build();
//                costPartMissingInfoMapper.insert(costPartMissingInfo);
//            }

            // 方案二：直接执行标准成本计算
            countStandardCost(appSceneCostCount1, (new Random().nextInt(1000)) + (new Random().nextInt(100)));
        }
    }

    /**
     * 执行标准成本计算
     *
     * @param appSceneCostCount1
     */
    private void countStandardCost(AppSceneCostCount appSceneCostCount1, Integer flowInstanceId) {
        //0.获取物料下所有的子物料
        StandardCostService.getAllMaterialBomInfoByTopMaterialCode(appSceneCostCount1.getWerks(),appSceneCostCount1.getMaterialNo(), "MaterialInput", "MaterialInput001", flowInstanceId);
        //1.物料成本计算
        StandardCostService.countMaterialCostByTopMaterialCode(appSceneCostCount1.getMaterialNo(), "MaterialCost", "MaterialCost002", flowInstanceId, FeeTypeEnum.MaterialCost.getCode());
        //2.人工成本计算
        //AppSceneCostHourRate hourRate = new AppSceneCostHourRate();
        //hourRate.setYear(appSceneCostCount1.getYear());
        //hourRate.setCostCenterCode(appSceneCostCount1.getCostCenter());
        //hourRate.setFactory(appSceneCostCount1.getFactory()==null?"7100":appSceneCostCount1.getFactory());
        //StandardCostService.countLaborCostByTopMaterialCode(appSceneCostCount1.getMaterialNo(), "LaborCost", "LaborCost003", flowInstanceId, FeeTypeEnum.LaborCost.getCode(), hourRate);
        //3.制造计算（各种费用）MaterialCost("MaterialCost", "物料成本"), EquipmentFee("EquipmentFee", "设备费"), SupplyMaterialFee("SupplyMaterialFee", "辅料费"), DriverFee("DriverFee", "水电费"), OtherFee("OtherFee", "其他费用"), LogisticsFee("LogisticsFee", "物流费")
       //3.1设备费计算
        //.countManufacturingCostByTopMaterialCode(appSceneCostCount1.getMaterialNo(), "ManufacturingCost", "ManufacturingCost004", flowInstanceId, FeeTypeEnum.EquipmentFee.getCode(), hourRate);
       //3.2辅料费计算
        //StandardCostService.countManufacturingCostByTopMaterialCode(appSceneCostCount1.getMaterialNo(), "ManufacturingCost", "ManufacturingCost005", flowInstanceId, FeeTypeEnum.SupplyMaterialFee.getCode(), hourRate);
        //3.3水电费
        //StandardCostService.countManufacturingCostByTopMaterialCode(appSceneCostCount1.getMaterialNo(), "ManufacturingCost", "ManufacturingCost006", flowInstanceId, FeeTypeEnum.DriverFee.getCode(), hourRate);
       //3.4其他费用
        //StandardCostService.countManufacturingCostByTopMaterialCode(appSceneCostCount1.getMaterialNo(), "ManufacturingCost", "ManufacturingCost007", flowInstanceId, FeeTypeEnum.OtherFee.getCode(), hourRate);
        StandardCostService.countManufacturingCost(appSceneCostCount1.getMaterialNo(), "ManufacturingCost", "ManufacturingCost007", flowInstanceId);
        //3.5物流费
        //StandardCostService.countManufacturingCostByTopMaterialCode(appSceneCostCount1.getMaterialNo(), "ManufacturingCost", "ManufacturingCost008", flowInstanceId, FeeTypeEnum.LogisticsFee.getCode(), hourRate);
        //4.标准成本本计算
        StandardCostService.countStandardCostByTopMaterialCode(appSceneCostCount1.getMaterialNo(), "StandardCost", "StandardCost009", flowInstanceId, FeeTypeEnum.StandardCost.getCode(),appSceneCostCount1.getStage(),appSceneCostCount1.getCostVersion());



        //appSceneCostCount1.setStatus(2);
        //saveOrUpdate(appSceneCostCount1);
        //upda(AppSceneCostCount.builder().id(appSceneCostCount1.getId()).status(2).build());
    }

    public AppSceneCostCount queryByVersion(String version){
        QueryWrapper<AppSceneCostCount> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("cost_version", version);
        return getOne(queryWrapper);
    }

    public Result<String> BatchCount(HttpServletRequest request, HttpServletResponse response) {
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest)request;
        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
        Iterator var6 = fileMap.entrySet().iterator();
        if (var6.hasNext()) {
            Map.Entry<String, MultipartFile> entity = (Map.Entry)var6.next();
            MultipartFile file = (MultipartFile)entity.getValue();
            ImportParams params = new ImportParams();
            params.setTitleRows(0);
            params.setHeadRows(1);
            params.setNeedSave(false);

            try {
                List<BatchCount> list = ExcelImportUtil.importExcel(file.getInputStream(), BatchCount.class, params);
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
                Date dt = new Date();
                for (BatchCount batchCount:list){
                    AppSceneCostCountVO vo=new AppSceneCostCountVO();
                    vo.setWerks(batchCount.getWerks());
                    vo.setMaterialNo(batchCount.getMatnr());
                    vo.setStage(batchCount.getStage());
                    String version = batchCount.getMatnr()+"_"+batchCount.getStage()+"_"+sdf.format(dt);
                    vo.setCostVersion(version);
                    addCostCountTask(vo);
                }
                //long start = System.currentTimeMillis();
                //this.service.saveBatch(list);
                //log.info("消耗时间" + (System.currentTimeMillis() - start) + "毫秒");
                Result var13 = Result.ok("文件导入成功！数据行数：" + list.size());
                return var13;
            } catch (Exception var24) {
                String msg = var24.getMessage();
                log.error(msg, var24);
                Result var12;
                if (msg != null && msg.indexOf("Duplicate entry") >= 0) {
                    var12 = Result.error("文件导入失败:有重复数据！");
                    return var12;
                } else {
                    var12 = Result.error("文件导入失败:" + var24.getMessage());
                    return var12;
                }
            } finally {
                try {
                    file.getInputStream().close();
                } catch (IOException var23) {
                    var23.printStackTrace();
                }

            }
        } else {
            return Result.error("文件导入失败！");
        }
    }

    @Override
    public MatnrVersionVO getVersionsByMatnr(String werks, String matnr, String ymonth){
        MatnrVersionVO matnrVersionVO=MatnrVersionVO.builder()
                .matnr(matnr)
                .ymonth(ymonth)
                .build();

        List<String> aufnrs=new ArrayList<>();
        QueryWrapper<AppSceneCostActual> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("werks",werks);
        queryWrapper.eq("matnr",matnr);
        if(ymonth!=null&&!ymonth.equals("")){
            queryWrapper.eq("ymonth",ymonth);
        }
        queryWrapper.orderByDesc("create_time");
        List<AppSceneCostActual> actualList=iAppSceneCostActualService.list(queryWrapper);
        for (AppSceneCostActual appSceneCostActual:actualList){
            aufnrs.add(appSceneCostActual.getAufnr());
        }

        matnrVersionVO.setAufnrs(aufnrs);

        List<String> stdversion=new ArrayList<>();
        QueryWrapper<AppSceneCostCount> queryWrapper1=new QueryWrapper<>();
        queryWrapper1.eq("werks",werks);
        queryWrapper1.eq("material_no",matnr);
        if(ymonth!=null&&!ymonth.equals("")){
            queryWrapper.like("version","%_"+ymonth+"%");
        }
        queryWrapper1.orderByDesc("create_time");
        List<AppSceneCostCount> stdcounts=this.list(queryWrapper1);
        for (AppSceneCostCount appSceneCostActual:stdcounts){
            stdversion.add(appSceneCostActual.getCostVersion());
        }
        matnrVersionVO.setStdVersion(stdversion);

        return matnrVersionVO;
    }
}
