package com.sw.mes.itemclean.clean.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.gson.Gson;
import com.sw.mes.core.annotation.Jinko;
import com.sw.mes.core.api.system.YbFeignClients;
import com.sw.mes.core.context.BaseContextHandler;
import com.sw.mes.core.dto.DictionaryItemDto;
import com.sw.mes.core.dto.ProductionOrderDto;
import com.sw.mes.core.dto.materialCleanDto.MaterialCleanModelDto;
import com.sw.mes.core.dto.sap.ReportSapChargItemDto;
import com.sw.mes.core.dto.sap.ReportSapGoodsmvtDto;
import com.sw.mes.core.enums.EnumValuesFactory;
import com.sw.mes.core.enums.ItemCleanEnums;
import com.sw.mes.core.exception.BusinessException;
import com.sw.mes.core.response.ResponsePage;
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.DateUtil;
import com.sw.mes.core.utils.DynmaicQueryWrapper;
import com.sw.mes.core.utils.RequestPage;
import com.sw.mes.core.utils.ThreadManager;
import com.sw.mes.itemclean.clean.domain.*;
import com.sw.mes.itemclean.clean.dto.*;
import com.sw.mes.itemclean.clean.dto.boxNoOperate.BatchNo;
import com.sw.mes.itemclean.clean.dto.boxNoOperate.BoxNoOperate;
import com.sw.mes.itemclean.clean.service.*;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.ServletRequest;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/clean/cleanRework")
@Slf4j
@Api(tags = "返工打签")
public class CleanReworkController {
    @Autowired
    ModelMapper modelMapper;

    @Autowired
    private CleanReworkingService cleanReworkingService;

    @Autowired
    private CleanReworkingDetailService cleanReworkingDetailService;

    @Autowired
    private MaterialUnpackingService materialUnpackingService;

    @Autowired
    private MaterialCleaningService materialCleaningService;

    @Autowired
    private MaterialBrokenService materialBrokenService;

    @Autowired
    private YbFeignClients ybFeignClients;

    @Autowired
    private GenerateBusinessNoService generateBusinessNoService;

    @Autowired
    private MaterialStoreSignBoxService materialStoreSignBoxService;

    @Autowired
    YbFeignClients ybFeignService;

    private final static String RE_MARK = "PP";

    @Jinko(author = "yyl", value = "返工打签-返工打签")
    @ApiOperation(value = "返工打签-返工分页查询列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "rows", value = "行数", dataType = "integer", paramType = "query"),
            @ApiImplicitParam(name = "page", value = "页码", dataType = "integer", paramType = "query"),
    })
    @GetMapping("/listByPage")
    public Result<ResponsePage<CleanReworkingDto>> listByPage(ServletRequest request, @ApiIgnore RequestPage requestPage) {
        //分页查询
        QueryWrapper<CleanReworking> queryWrapper =  DynmaicQueryWrapper.searchFilter(request, CleanReworking.class);
        queryWrapper.orderByDesc("id");
        Page<CleanReworking> listPage = cleanReworkingService.page(new Page<>(requestPage.getPage(), requestPage.getRows()), queryWrapper);
        List<CleanReworkingDto> dtos = listPage.getRecords().stream()
                .map(entity -> toLazyDto(entity))
                .collect(Collectors.toList());
        for (CleanReworkingDto dto : dtos) {
            List<CleanReworkingDetail> byRid = cleanReworkingDetailService.getByRid(dto.getId());
            List<CleanReworkingDetailDto> collect = byRid.stream().map(entity -> toLazyDto(entity))
                    .collect(Collectors.toList());
            dto.setCleanReworkingDetailDtoList(collect);
            dto.setCreateTime(dto.getCreateDate());
        }
        ResponsePage responsePage = new ResponsePage(dtos, listPage.getTotal());
        return ResultGenerator.success(responsePage);
    }
//
//    @ApiOperation(value = "详细信息")
//    @GetMapping("/{id}")
//    public Result<MaterialReworkSignatureDto> get(@PathVariable @ApiParam(value="设备类型id") Integer id) {
//        MaterialReworkSignature materialReworkSignature = materialReworkSignatureService.getById(id);
//        if (null == materialReworkSignature)
//            return ResultGenerator.fail("该对象不存在");
//        return ResultGenerator.success(toEagerDto(materialReworkSignature));
//    }

    @Jinko(author = "yyl", value = "返工打签")
    @ApiOperation(value = "返工打签")
    @PostMapping("/create")
    public Result create(@RequestBody @Valid @ApiParam(value = "Dto对象") CleanReworkingDto cleanReworkingDto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        cleanReworkingDto.setCreateTime(new Date());
        cleanReworkingDto.setCreateUser(BaseContextHandler.getUsername());
        cleanReworkingDto.setCreateDate(new Date());
        String ppProductBatch = generateBusinessNoService.generateBoxNoForUnpack(RE_MARK);
        cleanReworkingDto.setProductBatchNo(ppProductBatch);
        initData(cleanReworkingDto);

        ReworkingDto reworkingDto = printData(cleanReworkingDto);


        return ResultGenerator.success(reworkingDto);
    }

    @Jinko(author = "yyl", value = "通过返工批次号获取信息")
    @ApiOperation(value = "通过返工批次号获取信息")
    @GetMapping("/findDataByProductBatchNo")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "productBatchNo", value = "返工生成批次", dataType = "String", paramType = "query")
    })
    public Result findDataByProductBatchNo(String productBatchNo) {
        CleanReworking cleanReworking = cleanReworkingService.getByBatchNo(productBatchNo);
        if (null == cleanReworking)
            return ResultGenerator.fail("该对象不存在");
        return ResultGenerator.success(cleanReworking);
    }

    public ReworkingDto printData(@ApiParam("Dto对象") @RequestBody @Valid CleanReworkingDto cleanReworkingDto) {
//        Result<MaterialCleanModelDto> result = ybFeignClients.findMaterialCleanByFinishedCode(cleanReworkingDto.getMaterialCode());
//        if (!result.getCode().equals(ResultCode.SUCCESS.code)) {
//            throw new RuntimeException("查询原料清洗产品模型发生错误");
//        }
//        MaterialCleanModelDto materialCleanModelDto = result.getData();
//        if (materialCleanModelDto == null) {
//            throw new RuntimeException("不存在" + cleanReworkingDto.getMaterialCode() + "原料清洗产品模型！");
//        }
//        String factory = materialCleanModelDto.getFactory();
//        String dopedTypeCode = materialCleanModelDto.getDopedTypeCode();

        ReworkingDto reworkingDto = new ReworkingDto();
        reworkingDto.setBoxNo(cleanReworkingDto.getMaterialBoxNo());
//        reworkingDto.setFactory(factory);
//        reworkingDto.setMaterialModel(dopedTypeCode);
        reworkingDto.setMaterialName(cleanReworkingDto.getMaterialName());
        reworkingDto.setReWorkWeight(cleanReworkingDto.getWeight().toString());
        reworkingDto.setMaterialGear(cleanReworkingDto.getMaterialGear());
        reworkingDto.setMaterialLevel(cleanReworkingDto.getMaterialLevel());

        String formatTime11 = DateUtil.getFormatTime11(new Date());
        reworkingDto.setDate(formatTime11);
        reworkingDto.setSource(cleanReworkingDto.getSource());
        return reworkingDto;
    }

    /**
     * 更新时不能修改之前已经录入的重量
     *
     * @param cleanReworkingDto
     * @param bindingResult
     * @return
     */

    @ApiOperation(value = "更新")
    @PostMapping("/update")
    public Result update(@RequestBody @Valid @ApiParam(value = "Dto对象") CleanReworkingDto cleanReworkingDto, BindingResult bindingResult) {
        if (bindingResult.hasErrors())
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        if (cleanReworkingDto.getId() == null)
            return ResultGenerator.fail("id不能为空");
        CleanReworking entity = cleanReworkingService.getById(cleanReworkingDto.getId());
        if (entity == null)
            return ResultGenerator.fail("原信息不存在");
        try {
            cleanReworkingDto.setId(entity.getId());
            cleanReworkingDto.setUpdateTime(new Date());
            cleanReworkingDto.setUpdateUser(BaseContextHandler.getUsername());
            initData(cleanReworkingDto);

            ReworkingDto reworkingDto = printData(cleanReworkingDto);
            return ResultGenerator.success(reworkingDto);
        } catch (Exception e) {
            return ResultGenerator.fail(e.getMessage());
        }
    }

    @ApiOperation(value = "查询返工数据")
    @PostMapping("/findData")
    public Result findData(@RequestBody @Valid @ApiParam(value = "Dto对象") ReworkingDto reworkingDto) {

        String materialSource = reworkingDto.getMaterialSource();
        ReworkingDto reWorkData = getReWorkData(reworkingDto, materialSource);
        return ResultGenerator.success(reWorkData);
    }

    public ReworkingDto getReWorkData(@ApiParam("Dto对象") @RequestBody @Valid ReworkingDto reworkingDto, String materialSource) {
        if(materialSource.equals(EnumValuesFactory.CleaningWipStorageCode.分选.getValue())){
            MaterialUnpacking fxProductBatchNo = materialUnpackingService.getFxProductBatchNo(reworkingDto.getReWorkBatchNo());
            if(null == fxProductBatchNo){
                throw new RuntimeException("未查询到物料");
            }
            reworkingDto.setReWorkBatchNo(reworkingDto.getReWorkBatchNo());
            reworkingDto.setMaterialGear(fxProductBatchNo.getMaterialGear());
            reworkingDto.setMaterialLevel(fxProductBatchNo.getMaterialLevel());
            reworkingDto.setMaterialModel(fxProductBatchNo.getMaterialModel());
            reworkingDto.setMaterialName(fxProductBatchNo.getMaterialName());
            reworkingDto.setMaterialWeight(fxProductBatchNo.getWeight());
//            materialUnpackingService.updateBoxStatus(fxProductBatchNo.getBoxNo(), ,reworkingDto.getBoxNo());
        } else if (materialSource.equals(EnumValuesFactory.CleaningWipStorageCode.清洗.getValue())) {
            MaterialCleaning byBatchNo = materialCleaningService.getByBatchNo(reworkingDto.getReWorkBatchNo());
            if(null == byBatchNo){
                throw new RuntimeException("未查询到物料");
            }
//            materialUnpackingService.updateBoxStatus(byBatchNo.getBoxNo(), ,reworkingDto.getBoxNo());
            reworkingDto.setReWorkBatchNo(reworkingDto.getReWorkBatchNo());
            reworkingDto.setMaterialGear(byBatchNo.getMaterialGear());
            reworkingDto.setMaterialLevel(byBatchNo.getMaterialLevel());
            reworkingDto.setMaterialModel(byBatchNo.getMaterialModel());
            reworkingDto.setMaterialName(byBatchNo.getMaterialName());
            reworkingDto.setMaterialWeight(byBatchNo.getWeight());
        } else {
            MaterialBroken byBatchNo = materialBrokenService.getByBatchNo(reworkingDto.getReWorkBatchNo());
            if(null == byBatchNo){
                throw new RuntimeException("未查询到物料");
            }
//            materialUnpackingService.updateBoxStatus(null, null, reworkingDto.getBoxNo());
            reworkingDto.setReWorkBatchNo(reworkingDto.getReWorkBatchNo());
            reworkingDto.setMaterialGear(byBatchNo.getMaterialGear());
            reworkingDto.setMaterialLevel(byBatchNo.getMaterialLevel());
            reworkingDto.setMaterialModel(byBatchNo.getMaterialModel());
            reworkingDto.setMaterialName(byBatchNo.getMaterialName());
            reworkingDto.setMaterialWeight(byBatchNo.getWeight());
        }

        return reworkingDto;
    }

    public void initData(@ApiParam("Dto对象") @Valid @RequestBody CleanReworkingDto cleanReworkingDto) {
        //1 创建返工对象
        CleanReworking cleanReworking = fromDto(cleanReworkingDto);
        cleanReworkingService.saveOrUpdate(cleanReworking);
        //2 创建领料对象
//        MaterialStoreSignBox materialStoreSignBox = new MaterialStoreSignBox();
//       // MaterialStoreSignBox materialStoreSignBox = fromDto(materialStoreSignBoxDto);
//        //发起入库此处不在生成批次号，入参已经传进来
//        materialStoreSignBox.setStatus(ItemCleanEnums.MaterialStatus.已接收.getKey());
//        materialStoreSignBox.setPickingStatus(ItemCleanEnums.MaterialPickStatus.未领料.getKey());
//        materialStoreSignBox.setUseStatus(ItemCleanEnums.MaterialUseStatus.未使用.getKey());
//        materialStoreSignBox.setDelFlag(ItemCleanEnums.MaterialDelFlag.未删除.getKey());
//        materialStoreSignBox.setMaterialResource(ItemCleanEnums.MaterialResource.valueOf(cleanReworking.getSource()).getKey());
//        materialStoreSignBox.setMaterialType(ItemCleanEnums.MaterialType.返工料.getKey());
//        materialStoreSignBox.setWeight(cleanReworking.getWeight());
//        materialStoreSignBox.setProductBatchNo(cleanReworking.getProductBatchNo());
//        materialStoreSignBox.setBoxNo(cleanReworking.getMaterialBoxNo());
//        materialStoreSignBox.setMaterialBoxNo(cleanReworking.getProductBatchNo());
//        materialStoreSignBox.setMaterialCode(cleanReworking.getMaterialCode());
//        materialStoreSignBox.setMaterialName(cleanReworking.getMaterialName());
//        materialStoreSignBox.setMaterialGear(cleanReworking.getMaterialGear());
//        materialStoreSignBox.setMaterialLevel(cleanReworking.getMaterialLevel());
//        materialStoreSignBox.setMaterialModel(cleanReworking.getMaterialModel());
//        materialStoreSignBox.setUnusedWeight(cleanReworking.getWeight());
//        materialStoreSignBox.setUsedWeight(BigDecimal.ZERO);
//        materialStoreSignBox.setCreateTime(LocalDateTime.now());
//        materialStoreSignBox.setCreateUser(BaseContextHandler.getUsername());
//        materialStoreSignBox.setAufnr(cleanReworking.getWorkOrderNo());
//        materialStoreSignBoxService.saveOrUpdate(materialStoreSignBox);
        /*List<CleanReworkingDetailDto> cleanReworkingDetailDtoList = cleanReworkingDto.getCleanReworkingDetailDtoList();

        //todo 验证物料等级、档位、名称是否一致
        //物料等级
        String materialLevel = cleanReworkingDto.getMaterialLevel();
        //物料档位
        String materialGear = cleanReworkingDto.getMaterialGear();
        //物料名称
        String materialName = cleanReworkingDto.getMaterialName();
        //物料规格
        String materialModel = cleanReworkingDto.getMaterialModel();
*/
       /* for (CleanReworkingDetailDto cleanReworkingDetailDto : cleanReworkingDetailDtoList) {
            ReworkingDto reworkingDto = new ReworkingDto();
            reworkingDto.setReWorkBatchNo(cleanReworkingDetailDto.getProductBatchNo());
            ReworkingDto reWorkData = this.getReWorkData(reworkingDto, cleanReworkingDto.getSource());
            if(!reWorkData.getMaterialLevel().equals(materialLevel)) {
                throw new RuntimeException("存在" + materialLevel + "和" + reWorkData.getMaterialLevel() + "不同等级的物料无法合批");
            }
            if(!reWorkData.getMaterialGear().equals(materialGear)) {
                throw new RuntimeException("存在" + materialGear + "和" + reWorkData.getMaterialGear() + "不同档位的物料无法合批");
            }
            if(!reWorkData.getMaterialName().equals(materialName)) {
                throw new RuntimeException("存在" + materialName + "和" + reWorkData.getMaterialName() + "不同物料名称的物料无法合批");
            }
            if(!reWorkData.getMaterialModel().equals(materialModel)) {
                throw new RuntimeException("存在" + materialModel + "和" + reWorkData.getMaterialModel() + "不同物料名称的物料无法合批");
            }
        }*/

       /* for (CleanReworkingDetailDto cleanReworkingDetailDto : cleanReworkingDetailDtoList) {
            CleanReworkingDetail cleanReworkingDetail = fromDto1(cleanReworkingDetailDto);
            ReworkingDto reworkingDto = new ReworkingDto();
            reworkingDto.setReWorkBatchNo(cleanReworkingDetailDto.getProductBatchNo());
            reworkingDto.setMaterialSource(cleanReworkingDto.getSource());
//            Result data = this.findData(reworkingDto);
            ReworkingDto reWorkData = getReWorkData(reworkingDto, reworkingDto.getMaterialSource());
//            Object data1 = data.getData();
            BigDecimal weight = new BigDecimal(0);
            if(null != reWorkData && null == cleanReworkingDetailDto.getId()){
//                JSONObject jsonObject = JSONObject.parseObject(String.valueOf(data1));
//                weight.add(new BigDecimal(jsonObject.get("materialWeight").toString()));
                weight.add(reWorkData.getMaterialWeight());
                cleanReworkingDetail.setRid(cleanReworking.getId());
                cleanReworkingDetail.setProductBatchNo(cleanReworkingDetailDto.getProductBatchNo());
                BigDecimal unusedWeightTotal = weight.subtract(cleanReworkingDetailDto.getReworkinggWeight());
                materialUnpackingService.updateBoxStatus(cleanReworkingDetailDto.getReworkingBoxNo(), unusedWeightTotal, cleanReworkingDto.getMaterialBoxNo());
            }
            cleanReworkingDetailService.saveOrUpdate(cleanReworkingDetail);
        }*/

        //返工回收料产出报工SAP
//        ThreadManager.getThreadPollProxy().execute(() -> {
//            try {
//                //2.1 报工副产品产出到SAP
//                String warehouseCode = getWareHouseCodeByWorkOrderNo(cleanReworking.getWorkOrderNo());
//                this.handleReportSapGoodsmvtDto(cleanReworking.getWorkOrderNo(), cleanReworking.getMaterialCode(), cleanReworking.getProductBatchNo(), cleanReworking.getWeight(), "KG", warehouseCode);
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        });
    }
    /**
     * 返工打签,副产品报给内部系统,供上报sap使用
     *
     * @param workOrderNo    工单
     * @param materialCode   物料编码
     * @param produceBatchNo 产品批次
     * @param weight         数量(重量)
     * @param unitName       单位(KG,PC)
     * @param warehouseCode       库存地点编码
     */
    @Jinko(author = "yyl", value = "返工打签,副产品报给内部系统,供上报sap使用")
    private void handleReportSapGoodsmvtDto(String workOrderNo, String materialCode, String produceBatchNo, BigDecimal weight, String unitName,String warehouseCode) {
        ReportSapGoodsmvtDto reportSapGoodsmvtDto = new ReportSapGoodsmvtDto();
        List<ReportSapChargItemDto> reportSapChargItemDtos = new ArrayList<>();
        ReportSapChargItemDto reportSapChargItemDto = new ReportSapChargItemDto();
//        reportSapChargItemDto.setAtnam("S11");
//        reportSapChargItemDto.setAtwrt("JK1");
        reportSapChargItemDtos.add(reportSapChargItemDto);
        reportSapGoodsmvtDto.setChargItems(reportSapChargItemDtos);
        reportSapGoodsmvtDto.setAufnr(workOrderNo);
        reportSapGoodsmvtDto.setCharg(produceBatchNo);
        reportSapGoodsmvtDto.setBwart("531");
        reportSapGoodsmvtDto.setWerks("5041");
        reportSapGoodsmvtDto.setMatnr(materialCode);
        reportSapGoodsmvtDto.setMenge(weight == null ? "0" : weight.toString());
        reportSapGoodsmvtDto.setMeins(unitName);
        reportSapGoodsmvtDto.setLgort(warehouseCode);
        reportSapGoodsmvtDto.setZfcpFlag("X");
        reportSapGoodsmvtDto.setProcName("余料");
        ybFeignService.sendSapGoodsmvt(reportSapGoodsmvtDto);
    }

    /**
     * 通过工单号获取库位成品仓
     *
     * @param workOrderNo   计划工单
     * @return
     */
    @Jinko(author = "yyl", value = "通过工单号获取库位成品仓")
    private String getWareHouseCodeByWorkOrderNo(String workOrderNo) {
        //2.1 报工副产品产出到SAP
        Result<ProductionOrderDto> productionOrder = ybFeignClients.getListByAufnr(workOrderNo);
        String field4 = "";
        String warehouseCode = "";
        if (productionOrder.getCode() != ResultCode.SUCCESS.getCode() || null == productionOrder.getData()) {
            throw new RuntimeException("工单查询异常：" + productionOrder.getMessage());
        }
        ProductionOrderDto orderData = productionOrder.getData();
        if (null != orderData) {
            field4 = orderData.getField4();
        }
        if (null != field4) {
            Result<DictionaryItemDto> dictionaryItemDtoResult = ybFeignClients.findNameByThemeValueAndItemValue("ByProductWarehouseLocation", field4);
            if (null != dictionaryItemDtoResult && null != dictionaryItemDtoResult.getData() && ResultCode.SUCCESS.getCode() == dictionaryItemDtoResult.getCode()) {
                warehouseCode = dictionaryItemDtoResult.getData().getExtendValue1();
            } else {
                throw new BusinessException(dictionaryItemDtoResult.getMessage() + "详情: 关键字[ByProductWarehouseLocation]中的[工作中心编码]: " + field4 + " 未配置");
            }
        }
        return warehouseCode;
    }

    public CleanReworking fromDto(CleanReworkingDto dto) {
        return modelMapper.map(dto, CleanReworking.class);
    }

    public CleanReworkingDetail fromDto1(CleanReworkingDetailDto dto) {
        return modelMapper.map(dto, CleanReworkingDetail.class);
    }

    public CleanReworkingDto toLazyDto(CleanReworking entity) {
        return modelMapper.map(entity, CleanReworkingDto.class);
    }

   public CleanReworkingDetailDto toLazyDto(CleanReworkingDetail entity) {
        return modelMapper.map(entity, CleanReworkingDetailDto.class);
    }

}
