package com.sw.mes.itemclean.clean.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.sw.mes.core.api.system.YbFeignClients;
import com.sw.mes.core.context.BaseContextHandler;
import com.sw.mes.core.dto.erp.ErpAddResultDto;
import com.sw.mes.core.dto.erp.ErpRequestDto;
import com.sw.mes.core.dto.materialCleanDto.MaterialCleanModelDto;
import com.sw.mes.core.entity.MesToErpCcpEntity;
import com.sw.mes.core.enums.EnumValues;
import com.sw.mes.core.enums.ErpPypeEnum;
import com.sw.mes.core.enums.ItemCleanEnums;
import com.sw.mes.core.response.Result;
import com.sw.mes.core.response.ResultCode;
import com.sw.mes.core.response.ResultGenerator;
import com.sw.mes.core.utils.NumberUtil;
import com.sw.mes.core.utils.StringUtils;
import com.sw.mes.itemclean.clean.domain.*;
import com.sw.mes.itemclean.clean.dto.*;
import com.sw.mes.itemclean.clean.mapper.MaterialGroupDetailMapper;
import com.sw.mes.itemclean.clean.service.MaterialGroupDetailService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sw.mes.itemclean.clean.service.MaterialGroupService;
import com.sw.mes.itemclean.clean.service.MaterialPlanOrderService;
import feign.Request;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 组托明细 服务实现类
 * </p>
 *
 * @author liuzemin
 * @since 2022-11-10
 */
@Service
public class MaterialGroupDetailServiceImpl extends ServiceImpl<MaterialGroupDetailMapper, MaterialGroupDetail> implements MaterialGroupDetailService {
    @Autowired
    MaterialGroupDetailMapper baseDao;

    @Autowired
    private YbFeignClients ybFeignClients;
    @Autowired
    private MaterialPlanOrderService materialPlanOrderService;
    @Autowired
    private MaterialGroupService materialGroupService;

    @Value("${spring.erpServiceUrl}")
    private String erpServiceUrl;

    @Override
    public IPage<MaterialGroupToDetailDto> queryList(IPage<MaterialGroupToDetailDto> iPage, GroupDetailParamQuery query) {
        return baseDao.queryList(iPage, query);
    }

    @Override
    public List<MaterialGroupToDetailDto> queryListByParam(GroupDetailParamQuery query) {
        return baseDao.queryListByParam(query);
    }

    @Override
    public List<MaterialGroupDetail> findList(GroupDetailParamQuery groupDetailParamQuery) {
        return baseDao.findList(groupDetailParamQuery);
    }

    @Override
    public Result reportedErp(MaterialGroupDto dto) {
        LocalDateTime now = LocalDateTime.now();
        // 循环料
        MaterialGroup materialGroup = materialGroupService.getById(dto.getId());
        if(null == materialGroup){
            return ResultGenerator.fail("循环料主表原信息不存在");
        }
        if (EnumValues.ReportedErp.未上报.getKey() != materialGroup.getReportedState()) {
            return ResultGenerator.fail("组托详情当前不处于未上报状态,不能进行上报ERP操作：" + materialGroup.getProductBatchNo());
        }
        GroupDetailParamQuery groupDetailParamQuery = new GroupDetailParamQuery();
        groupDetailParamQuery.setGroupNo(materialGroup.getGroupNo());
        List<MaterialGroupDetail> list = findList(groupDetailParamQuery);
        if(list.isEmpty()){
            return ResultGenerator.fail("循环料从表原信息不存在");
        }
        double sunWeight = 0D;
        MaterialPlanOrder materialPlanOrder = materialPlanOrderService.findByAufnr(dto.getAufnr());
        for(MaterialGroupDetail materialGroupDetail : list) {
            if (EnumValues.ReportedErp.未上报.getKey() != materialGroupDetail.getReportedState()) {
                return ResultGenerator.fail("组托详情当前不处于未上报状态,不能进行上报ERP操作：" + materialGroupDetail.getMaterialBoxNo());
            }
            materialGroupDetail.setReportedState(EnumValues.ReportedErp.已上报.getKey());
            sunWeight += materialGroupDetail.getWeight().doubleValue();
        }
        MaterialGroupDetail materialGroupDetail = list.get(0);
        // todo 上报ERP，成功更新上报状态

        MesToErpCcpEntity mesToErpCcpEntity = new MesToErpCcpEntity();
        // "cwhcode": "315", --仓库编码	从订单，常规：315，研发：316
        mesToErpCcpEntity.setCwhcode("013"); // 320 五车间  332 六车间  两个
        // "crdcode": "10216", --出库类别/收发类别	常规：10216，研发：10201
        mesToErpCcpEntity.setCrdcode("20108");
        // "cdepcode": "1413", --部门编码	从订单获取
        mesToErpCcpEntity.setCdepcode("1203");
        // "cwhname": "回收原料库", --仓库名称
        mesToErpCcpEntity.setCwhname("单晶酸洗半成品库（三期）");
        // "cdepname": "开方五车间",--部门名称	从订单获取
        mesToErpCcpEntity.setCdepname("料理二车间（三期）");
//        MaterialCleanModelDto materialCleanModelDto = new MaterialCleanModelDto();
//        materialCleanModelDto.setName(materialGroupDetail.getMaterialName());
        Result<List<MaterialCleanModelDto>> materialModelByCode = ybFeignClients.findByName(materialGroupDetail.getMaterialName());
        if(null != materialModelByCode && ResultCode.SUCCESS.getCode() == materialModelByCode.getCode() && !materialModelByCode.getData().isEmpty()){
            MaterialCleanModelDto materialCleanModelDto1 = materialModelByCode.getData().get(0);
            //  单位 产成品使用母建，回收料使用子健 新增   cinvm_unit todo
//            mesToErpCcpEntity.setCinvm_unit();
            // "cinvcode": "100100180103", --材料编码	从订单获取       材料编码  产成品使用母建的料号，回收料使用子健的料号
            mesToErpCcpEntity.setCinvcode(materialCleanModelDto1.getFinishedCode());
        }
//        mesToErpCcpEntity.setCinvcode(materialGroup.getFinishedCode());

        if(null != materialPlanOrder){
            // "iproorderid": "1000009317", --生产订单id	从订单获取
            mesToErpCcpEntity.setIproorderid(NumberUtil.object2String(materialPlanOrder.getId(),null));



            // 材料名称  产成品使用母建，回收料使用子健 新增  cinvname   todo 无
//            mesToErpCcpEntity.setCinvname(materialPlanOrder.getMaterialName());
            // 规格型号 产成品使用母建，回收料使用子健 新增 cinsted
//            mesToErpCcpEntity.setCinsted(materialPlanOrder.getMaterialModel());

            // 应入库数量，取订单数量 产成品使用母建，回收料使用子健 新增 inquantity todo 不确定
            mesToErpCcpEntity.setInquantity(NumberUtil.object2String(materialPlanOrder.getPlanMenge(),null));
//            erpOrderService.findByModIdAndInvCode1()

            // 入库记录ID 先不进行填写进行调试 产成品使用母建，回收料使用子健 新增 impoids

            // 是否关联副产品 先不进行填写进行调试 产成品使用母建，回收料使用子健 新增    brelated

            // 生产订单号 产成品使用母建，回收料使用子健 新增     cmocode
//            mesToErpCcpEntity.setCmocode();
            // 生产订单行号,目前填写1 产成品使用母建，回收料使用子健 新增  imoseq

            // 子建行号,目前填写1 产成品使用母建，回收料使用子健 新增    irowno

            // "cmpocode": "2308011408-12吋(BNE01A1)(正泰045)", --订单号     合并汇总用的订单：erpOrderNo
            mesToErpCcpEntity.setCmpocode(materialGroupDetail.getAufnr());
        }



        // "cbatch": "(2)2023-8-16/129BP(A)正泰045", --批号
        mesToErpCcpEntity.setCbatch(materialGroupDetail.getProductBatchNo());
        // "iquantity": "1.0000000000", --数量	同种订单产品合并汇总后的数量
        mesToErpCcpEntity.setIquantity(String.valueOf(sunWeight));
        mesToErpCcpEntity.setErpType(ErpPypeEnum.循环料产出.getKey());
        if(null != materialGroup.getCreateTime()) {
            ZoneId zoneId = ZoneId.systemDefault();
            Date from = Date.from(materialGroup.getCreateTime().atZone(zoneId).toInstant());
            mesToErpCcpEntity.setDocTime(from);
        }
        ErpRequestDto erpRequestDto = new ErpRequestDto();
        erpRequestDto.setMesToErpCcpEntity(mesToErpCcpEntity);
        erpRequestDto.setUrl(erpServiceUrl);
//        ErpAddResultDto erpAddResultDto = erpRequestUtil.postToErp(erpRequestDto);
        Request.Options options = new Request.Options(60L, TimeUnit.SECONDS, 60L, TimeUnit.SECONDS, true);
        Result<ErpAddResultDto> result = ybFeignClients.postToErp(options,erpRequestDto);
        if(null == result || ResultCode.SUCCESS.getCode() != result.getCode()){
            throw new RuntimeException("循环料产出上报调用圆棒服务失败：" + JSONObject.toJSONString(result));
        }
        ErpAddResultDto erpAddResultDto = result.getData();
        if(null == erpAddResultDto || !erpAddResultDto.getErrcode().equals(String.valueOf(ResultCode.SUCCESS.getCode()))){
            throw new RuntimeException("循环料产出上报失败：" + JSONObject.toJSONString(erpAddResultDto.getErrmsg()));
        }
        // 回写ERP订单
        for(MaterialGroupDetail groupDetail : list){
            groupDetail.setErpOrder(erpAddResultDto.getCcode());
            groupDetail.setErpWarehouseCode("302");
            groupDetail.setErpTime(now);
        }
        updateBatchById(list);
        materialGroup.setReportedState(EnumValues.ReportedErp.已上报.getKey());
        materialGroup.setErpOrder(erpAddResultDto.getCcode());
        materialGroup.setErpWarehouseCode("302");
        materialGroup.setErpTime(now);
        materialGroupService.updateById(materialGroup);
        return ResultGenerator.success();
    }

    @Override
    public MaterialGroupDetail getGroupDetailInfoByMaterialBoxNo(String materialBoxNo) {
        LambdaQueryWrapper<MaterialGroupDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MaterialGroupDetail::getMaterialBoxNo, materialBoxNo);
        queryWrapper.eq(MaterialGroupDetail::getDelFlag, ItemCleanEnums.MaterialDelFlag.未删除.getKey());
        queryWrapper.eq(MaterialGroupDetail::getStatus, ItemCleanEnums.MaterialGroupDetailStatus.未组托.getKey());
        queryWrapper.last("limit 1");
        return getOne(queryWrapper);
    }

    @Override
    public void updateStatusByIds(List<Integer> ids, MaterialGroup materialGroup) {
        UpdateWrapper<MaterialGroupDetail> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("status", ItemCleanEnums.MaterialGroupDetailStatus.已组托.getKey());
        updateWrapper.set("update_user", BaseContextHandler.getUsername());
        updateWrapper.set("update_time", LocalDateTime.now());
        updateWrapper.set("group_id", materialGroup.getId());
        updateWrapper.set("group_no",materialGroup.getGroupNo());
        updateWrapper.set("supplies_grain",materialGroup.getSuppliesGrain());
        updateWrapper.in("id", ids);

        this.update(updateWrapper);
    }

    @Override
    public void updateStatusByGroupId(Integer groupId) {
        UpdateWrapper<MaterialGroupDetail> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("status", ItemCleanEnums.MaterialGroupDetailStatus.未组托.getKey());
        updateWrapper.set("update_user", BaseContextHandler.getUsername());
        updateWrapper.set("group_no", null);
        updateWrapper.set("group_id", null);
        updateWrapper.set("update_time", LocalDateTime.now());
        updateWrapper.eq("group_id", groupId);
        this.update(updateWrapper);
    }

    @Override
    public List<MaterialGroupDetail> getGroupDetailsByGroupId(Integer id) {
        LambdaQueryWrapper<MaterialGroupDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MaterialGroupDetail::getGroupId, id);
        queryWrapper.eq(MaterialGroupDetail::getDelFlag, ItemCleanEnums.MaterialDelFlag.未删除.getKey());
        queryWrapper.eq(MaterialGroupDetail::getStatus, ItemCleanEnums.MaterialGroupDetailStatus.已组托.getKey());
        return this.list(queryWrapper);
    }

    @Override
    public List<MaterialGroupDetail> getGroupDetailInfosByMaterialBoxNo(List<String> boxNos) {
        LambdaQueryWrapper<MaterialGroupDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(MaterialGroupDetail::getMaterialBoxNo, boxNos);
        queryWrapper.eq(MaterialGroupDetail::getDelFlag, ItemCleanEnums.MaterialDelFlag.未删除.getKey());
        queryWrapper.eq(MaterialGroupDetail::getStatus, ItemCleanEnums.MaterialGroupDetailStatus.未组托.getKey());
        return this.list(queryWrapper);
    }

    @Override
    public List<MaterialGroupToBoxDetailDto> queryBoxList( GroupDetailParamQuery query) {
        return baseDao.queryBoxList(query);
    }

    @Override
    public IPage<MaterialGroupToBoxDetailDto> queryBoxPage(IPage<MaterialGroupToBoxDetailDto> iPage, GroupDetailParamQuery query) {
        return baseDao.queryBoxList(iPage, query);
    }
}
