package com.sw.mes.yb.pad.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sw.mes.base.factory.inspect.entity.DefaultCrystalAttrs;
import com.sw.mes.base.factory.inspect.service.DefaultCrystalAttrService;
import com.sw.mes.base.global.GlobalSwitch;
import com.sw.mes.base.global.GlobalSwitchNamespace;
import com.sw.mes.base.system.entity.DictionaryItem;
import com.sw.mes.base.system.service.DictionaryItemService;
import com.sw.mes.core.constant.Constants;
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.ResultGenerator;
import com.sw.mes.core.utils.*;
import com.sw.mes.enumvalue.EnumValuesServer;
import com.sw.mes.inspect.entity.YbInspectData;
import com.sw.mes.inspect.service.YbInspectDataService;
import com.sw.mes.yb.pad.dto.ProductionBackCuttingRecordDto;
import com.sw.mes.yb.pad.dto.ProductionBackCuttingRecordInformationDto;
import com.sw.mes.yb.pad.dto.RecordSegmentNoInfoDto;
import com.sw.mes.yb.pad.dto.RecutInfoDetailInfo;
import com.sw.mes.yb.pad.entity.ProductionBackCuttingRecord;
import com.sw.mes.yb.pad.entity.SectionNoDetail;
import com.sw.mes.yb.pad.service.ProductionRecutService;
import com.sw.mes.yb.pad.service.SectionNoDetailService;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.modelmapper.ModelMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
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.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * @Author
 * @Description：
 * @Date: Create in
 * @Modified By:
 */
@RestController
@RequestMapping("/ProductionBackCuttingRecord")
@Slf4j
@Api(description = "圆棒返切画线接口")
public class ProductionRecutController {
    @Autowired
    ModelMapper modelMapper;

    @Autowired
    private ProductionRecutService productionRecutService;

    @Autowired
    private DictionaryItemService dictionaryItemService;
    @Autowired
    private SectionNoDetailService sectionNoDetailService;

    @Autowired
    private DefaultCrystalAttrService defaultCrystalAttrService;

    @Autowired
    YbInspectDataService ybInspectDataService;

    @ApiOperation(value = "分页查询ProductionBackCuttingRecord列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "rows", value = "行数", dataType = "integer", paramType = "query"),
            @ApiImplicitParam(name = "page", value = "页码", dataType = "integer", paramType = "query"),
    })
    @GetMapping("/listByPage")
    public Result<ResponsePage<ProductionBackCuttingRecordDto>> listByPage(ServletRequest request, @ApiIgnore RequestPage requestPage) {
        Specification<ProductionBackCuttingRecord> specification = DynamicSpecifications.bySearchFilter(request, ProductionBackCuttingRecord.class);
        Page<ProductionBackCuttingRecord> page = productionRecutService.findByExample(specification, PageUtil.createPageable(requestPage));
        List<ProductionBackCuttingRecordDto> dtos = page.getContent().stream()
                .map(this::toLazyDto)
                .collect(Collectors.toList());
        dtos.stream().forEach(dto->{
            List<Map<String, Object>> list = productionRecutService.findInformationBySegmentNo(dto.getSegmentNo());
            List<ProductionBackCuttingRecordInformationDto> productionBackCuttingRecordInformationDtos = JSON.parseArray(JSON.toJSONString(list), ProductionBackCuttingRecordInformationDto.class);
            if (productionBackCuttingRecordInformationDtos.size()>0){
                dto.setProductionBackCuttingRecordInformationDto(productionBackCuttingRecordInformationDtos.get(0));
            }
        });
        ResponsePage responsePage = new ResponsePage(dtos, page.getTotalElements());
        return ResultGenerator.success(responsePage);
    }

    @ApiOperation(value = "获取所有ProductionBackCuttingRecord")
    @GetMapping("/listAll")
    public Result<List<ProductionBackCuttingRecordDto>> listAll(ServletRequest request) {
        Specification<ProductionBackCuttingRecord> specification = DynamicSpecifications.bySearchFilter(request, ProductionBackCuttingRecord.class);
        List<ProductionBackCuttingRecord> productionBackCuttingRecords = productionRecutService.findByExampleSort(specification, null);
        List<ProductionBackCuttingRecordDto> productionBackCuttingRecordDtos = productionBackCuttingRecords.stream()
                .map(productionBackCuttingRecord -> toLazyDto(productionBackCuttingRecord))
                .collect(Collectors.toList());
        return ResultGenerator.success(productionBackCuttingRecordDtos);
    }

    @ApiOperation(value = "ProductionBackCuttingRecord详细信息")
    @GetMapping("/{id}")
    public Result<ProductionBackCuttingRecordDto> get(@PathVariable @ApiParam(value = "ProductionBackCuttingRecordid") Long id) {
        ProductionBackCuttingRecord productionBackCuttingRecord = productionRecutService.get(id);
        if (null == productionBackCuttingRecord) {
            return ResultGenerator.fail("该ProductionBackCuttingRecord不存在");
        }
        return ResultGenerator.success(toEagerDto(productionBackCuttingRecord));
    }

    @ApiOperation(value = "创建ProductionBackCuttingRecord")
    @PostMapping("/create")
    public Result create(@RequestBody @Valid @ApiParam(value = "ProductionBackCuttingRecord对象") ProductionBackCuttingRecordDto productionBackCuttingRecordDto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        SectionNoDetail sectionNoDetail = sectionNoDetailService.findBySectionNo(productionBackCuttingRecordDto.getSegmentNo());
        if (sectionNoDetail == null) {
            throw new BusinessException("晶段编号不存在");
        }
        List<DictionaryItem> dictionaryItems = dictionaryItemService.findByThemeValueAndItemName(Constants.WEIGHT_RATIO, sectionNoDetail.getSpecs(), true);
        if (dictionaryItems.size() == 0) {
            throw new BusinessException("请配置【" + sectionNoDetail.getSpecs() + "】规格的理论重量系数");
        }
        BigDecimal weightLossCoefficient = NumberUtil.Object2BigDecimal(dictionaryItems.get(0).getValue());
        if (weightLossCoefficient == null || weightLossCoefficient.compareTo(new BigDecimal("1")) < 1) {
            throw new BusinessException("【" + dictionaryItems.get(0).getValue() + "】理论重量系数格式不正确，只能为大于0的数字类型");
        }
        DefaultCrystalAttrs defaultCrystalAttrList = defaultCrystalAttrService.getDefaultCrystalAttrs(sectionNoDetail.getDopant(), sectionNoDetail.getSpecs(), null);
        productionRecutService.createBackCuttingRecord(productionBackCuttingRecordDto, weightLossCoefficient, defaultCrystalAttrList, true);
        return ResultGenerator.success();
    }

    @ApiOperation(value = "创建ProductionBackCuttingRecordV2")
    @PostMapping("/createV2")
    public Result createV2(@RequestBody @Valid @ApiParam(value = "ProductionBackCuttingRecord对象") List<ProductionBackCuttingRecordDto> productionBackCuttingRecordDtos, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
      /*  List<DictionaryItem> paintCrystalUsedLength = dictionaryItemService.findByThemeValueAndEnable("paintCrystalUsedLength", true);
        Map<String, String> collect = paintCrystalUsedLength.stream().collect(Collectors.toMap(DictionaryItem::getName, DictionaryItem::getValue));*/
        SectionNoDetail sectionNoDetail = null;
        Integer length = 0;
        for (ProductionBackCuttingRecordDto productionBackCuttingRecordDto : productionBackCuttingRecordDtos) {
            sectionNoDetail = sectionNoDetailService.findBySectionNo(productionBackCuttingRecordDto.getSegmentNo());
            if (sectionNoDetail == null) {
                throw new BusinessException("晶段编号不存在");
            }
            List<RecutInfoDetailInfo> detail = productionBackCuttingRecordDto.getDetail();
            if(detail.size() < 1){
                throw new BusinessException("划线信息不存在");
            }
            // 需求添加判断氧/碳/电阻/少子 圆棒反切需要卡控，需要出评级结果才能选择
            if (StringUtils.isNotBlank(productionBackCuttingRecordDto.getCause())) {
                DictionaryItem dictionaryItem = dictionaryItemService.findNameByThemeValueAndItemValueAndEnable(Constants.YB_RECUT_TYPE, productionBackCuttingRecordDto.getCause(), true);
                if (null != dictionaryItem && !StringUtils.equals(dictionaryItem.getExtendValue(),"1")) {
                    YbInspectData ybInspectData = ybInspectDataService.findBySectionNo(productionBackCuttingRecordDto.getSegmentNo());
                    if (null == ybInspectData) {
                        throw new BusinessException("返切原因："+ productionBackCuttingRecordDto.getCause()+",单晶编号：" + productionBackCuttingRecordDto.getSegmentNo() + ",检验记录不存在，请先圆棒检验,再返切！");
                    }
                   /* if (StringUtils.isBlank(ybInspectData.getProductLevel())){
                        throw new BusinessException("返切原因："+ productionBackCuttingRecordDto.getCause()+",单晶编号：" + productionBackCuttingRecordDto.getSegmentNo() + ",评级未出结果，禁止性能反切！");
                    }*/
                    productionBackCuttingRecordDto.setBackcutFlag(1);
                }else {
                    productionBackCuttingRecordDto.setBackcutFlag(0);
                }
            }else {
                productionBackCuttingRecordDto.setBackcutFlag(0);
            }
           /* for (RecutInfoDetailInfo recutInfoDetailInfo : detail) {
                if(collect.containsKey(sectionNoDetail.getSpecs())){
                    length = Integer.valueOf(collect.get(sectionNoDetail.getSpecs()));
                    if(recutInfoDetailInfo.getType().equals(EnumValuesServer.LineType.晶段.getValue()) && recutInfoDetailInfo.getLength().compareTo(new BigDecimal(length)) < 0){
                        throw new BusinessException(recutInfoDetailInfo.getSegmentNo() + "：晶段长度小于有效长度");
                    }
                } else {
                    throw new BusinessException("请前往数据字典配置规格为【" + sectionNoDetail.getSpecs() + "】的划线晶段可用长度控制");
                }
            }*/
        }
       /* if(sectionNoDetail.getSectionNo().startsWith("B")){
            YbInspectData sectionNo = ybInspectDataService.getSectionNo(sectionNoDetail.getSectionNo());
            if(StringUtils.isBlank(sectionNoDetail.getSpecs())){
                sectionNoDetail.setSpecs(sectionNo.getProductTypeSecond());
            }
            if(StringUtils.isBlank(sectionNoDetail.getDopant())){
                sectionNoDetail.setDopant(sectionNo.getDopant());
            }
        }*/
       /* List<DictionaryItem> dictionaryItems = dictionaryItemService.findByThemeValueAndItemName(Constants.WEIGHT_RATIO, sectionNoDetail.getSpecs(), true);
        if (dictionaryItems.size() == 0) {
            throw new BusinessException("请配置【" + sectionNoDetail.getSpecs() + "】规格的理论重量系数");
        }
        BigDecimal weightLossCoefficient = NumberUtil.Object2BigDecimal(dictionaryItems.get(0).getValue());
        if (weightLossCoefficient == null || weightLossCoefficient.compareTo(new BigDecimal("1")) < 1) {
            throw new BusinessException("【" + dictionaryItems.get(0).getValue() + "】理论重量系数格式不正确，只能为大于0的数字类型");
        }*/
        DefaultCrystalAttrs defaultCrystalAttrList = defaultCrystalAttrService.getDefaultCrystalAttrs(sectionNoDetail.getDopant(), sectionNoDetail.getSpecs(), null);
       //productionRecutService.createBackCuttingRecordV2(productionBackCuttingRecordDtos, weightLossCoefficient, defaultCrystalAttrList, true);

        // 添加开关，业务走不同逻辑
        if (GlobalSwitch.enable(GlobalSwitchNamespace.NAMESPACE_YB_CHECK, "AutomaticRoundBackCut", true)) {
            productionRecutService.createBackCuttingRecordV2New(productionBackCuttingRecordDtos, null, defaultCrystalAttrList, true);
        }else {
            productionRecutService.createBackCuttingRecordV2(productionBackCuttingRecordDtos, null, defaultCrystalAttrList, true);
        }
        return ResultGenerator.success();
    }

    @ApiOperation(value = "更新ProductionBackCuttingRecord")
    @PostMapping("/update")
    public Result update(@RequestBody @Valid @ApiParam(value = "ProductionBackCuttingRecord") ProductionBackCuttingRecordDto dto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        if (dto.getId() == null) {
            return ResultGenerator.fail("id不能为空");
        }
        ProductionBackCuttingRecord entity = productionRecutService.get(dto.getId());
        if (entity == null) {
            return ResultGenerator.fail("原信息不存在");
        }
        try {
            ProductionBackCuttingRecord entityfromFto = fromDto(dto);
            BeanUtils.copyProperties(entityfromFto, entity, BeanUtil.getIgnoreProperties(entityfromFto, null, null));
            productionRecutService.saveOrUpdate(entity);
            return ResultGenerator.success();
        } catch (Exception e) {
            return ResultGenerator.fail(e.getMessage());
        }
    }

    @ApiOperation(value = "自动进行返切划线")
    @PostMapping("/autoCreateAppearanceCut")
    public Result autoCreateV(@RequestBody  @Valid @ApiParam(value = "查询编号及点位") JSONObject text) {
        JSONObject params = text.getJSONObject("params");
        String sectionNo = params.getString("sectionNo");

        int yinlie = (int)Math.floor(text.getDoubleValue("yinlie") + 0.5);
        int weicuo = (int)Math.floor(text.getDoubleValue("weicuo") + 0.5);
//        Integer yinlie = params.getInteger("yinlie");
//        Integer weicuo = params.getInteger("weicuo");

        if((yinlie == weicuo && yinlie == 1)){
            return ResultGenerator.success();
        }

        SectionNoDetail sectionNoDetail = sectionNoDetailService.findBySectionNo(sectionNo);
        if (sectionNoDetail == null) {
            throw new BusinessException("晶段编号不存在");
        }

        List<DictionaryItem> dictionaryItems = dictionaryItemService.findByThemeValueAndItemName(Constants.WEIGHT_RATIO, sectionNoDetail.getSpecs(), true);
        if (dictionaryItems.size() == 0) {
            throw new BusinessException("请配置【" + sectionNoDetail.getSpecs() + "】规格的理论重量系数");
        }
        BigDecimal weightLossCoefficient = NumberUtil.Object2BigDecimal(dictionaryItems.get(0).getValue());
        if (weightLossCoefficient == null || weightLossCoefficient.compareTo(new BigDecimal("1")) < 1) {
            throw new BusinessException("【" + dictionaryItems.get(0).getValue() + "】理论重量系数格式不正确，只能为大于0的数字类型");
        }
        DefaultCrystalAttrs defaultCrystalAttrList = defaultCrystalAttrService.getDefaultCrystalAttrs(sectionNoDetail.getDopant(), sectionNoDetail.getSpecs(), null);

        productionRecutService.autoCreateAppearanceCut(text, weightLossCoefficient, defaultCrystalAttrList, sectionNoDetail, true);
        return ResultGenerator.success();
    }

    @ApiOperation(value = "删除ProductionBackCuttingRecord")
    @PostMapping("/delete")
    public Result remove(@ApiParam(value = "id集合,逗号分隔,如2,4", type = "query") @RequestParam Long[] ids) {
        for (Long id : ids) {
            productionRecutService.deleteBackInfoDetail(id);
        }
        return ResultGenerator.success();
    }

    @ApiOperation(value = "托盘号获取晶段信息")
    @GetMapping("/findSegmentInfo")
    public Result<RecordSegmentNoInfoDto> findSegmentNoInfo(@ApiParam(value = "载具编号", type = "query") @RequestParam String trayNo) {
        return productionRecutService.findSegmentNoInfo(trayNo);
    }

    /**
     * 通过托号获取晶段基本信息v2 - 支持拼棒业务，返回值改变
     *
     * @param trayNo 托盘
     * @return 晶段信息列表，整棒长度为1
     */
    @ApiOperation(value = "通过托号获取晶段基本信息v2 - 支持拼棒业务，返回值改变")
    @GetMapping("/findSegmentNoInfoV2")
    public Result<LinkedList<RecordSegmentNoInfoDto>> findSegmentNoInfoV2(@ApiParam(value = "载具编号", type = "query") @RequestParam String trayNo) {
        return productionRecutService.findSegmentNoInfoV2(trayNo);
    }

    @ApiOperation(value = "单晶编号获取晶段信息")
    @GetMapping("/findInfoBySectionNo")
    public Result<RecordSegmentNoInfoDto> findSegmentNoInfoBySectionNo(@ApiParam(value = "晶段编号", type = "query") @RequestParam String sectionNo) {
        return productionRecutService.findSegmentNoInfoBySectionNo(sectionNo);
    }


    /**
     * 通过托号获取晶段基本信息v2 - 支持拼棒业务，返回值改变
     *
     * @param sectionNo 晶段编号
     * @return 晶段信息列表，整棒长度为1
     */
    @ApiOperation(value = "单晶编号获取晶段信息V2- 支持拼棒业务，返回值改变")
    @GetMapping("/findInfoBySectionNoV2")
    public Result<LinkedList<RecordSegmentNoInfoDto>> findSegmentNoInfoBySectionNoV2(@ApiParam(value = "晶段编号", type = "query") @RequestParam String sectionNo) {
        Result<LinkedList<RecordSegmentNoInfoDto>> segmentNoInfoBySectionNoV2 = null;

        // 添加开关，业务走不同逻辑
        if (GlobalSwitch.enable(GlobalSwitchNamespace.NAMESPACE_YB_CHECK, "AutomaticRoundBackCut", true)) {
            segmentNoInfoBySectionNoV2 = this.productionRecutService.findSegmentNoInfoBySectionNoV2New(sectionNo);
        }else {
            segmentNoInfoBySectionNoV2 = this.productionRecutService.findSegmentNoInfoBySectionNoV2(sectionNo);
        }
        return segmentNoInfoBySectionNoV2;
    }

    @ApiOperation(value = "单晶编号获取返切画线记录")
    @GetMapping("/findBySectionNo")
    public Result<ProductionBackCuttingRecord> findBySectionNo(@ApiParam(value = "晶段编号", type = "query") @RequestParam String sectionNo) {
        return ResultGenerator.success(productionRecutService.findTopBySegmentNoOrderByIdDesc(sectionNo));
    }

    @ApiOperation(value = "获取单晶编号")
    @PostMapping("/getSegmentNo")
    public Result getSegmentNo(@ApiParam(value = "GetSegmentNoDto", type = "query") @RequestBody ProductionBackCuttingRecordDto productionBackCuttingRecordDto) {
        return ResultGenerator.success(this.productionRecutService.getSegmentNo(productionBackCuttingRecordDto));
    }

    @ApiOperation(value = "获取单晶编号V2")
    @PostMapping("/getSegmentNoV2")
    public Result<List<ProductionBackCuttingRecordDto>> getSegmentNoV2(@ApiParam(value = "GetSegmentNoDto", type = "query")
                                                                       @RequestBody List<ProductionBackCuttingRecordDto> productionBackCuttingRecordDtos) {
        for (ProductionBackCuttingRecordDto productionBackCuttingRecordDto : productionBackCuttingRecordDtos) {
            List<RecutInfoDetailInfo> detail = productionBackCuttingRecordDto.getDetail();
            if (detail.size() < 1) {
                throw new BusinessException(productionBackCuttingRecordDto.getSegmentNo() + "切断明细内，至少包含一段晶段");
            }
            YbInspectData bySectionNo = ybInspectDataService.findBySectionNo(productionBackCuttingRecordDto.getSegmentNo());
           /* List<DictionaryItem> paintCrystalUsedLength = dictionaryItemService.findByThemeValueAndEnable("paintCrystalUsedLength", true);
            Map<String, String> collect = paintCrystalUsedLength.stream().collect(Collectors.toMap(DictionaryItem::getName, DictionaryItem::getValue));
            for (RecutInfoDetailInfo recutInfoDetailInfo : detail) {
                if(collect.containsKey(bySectionNo.getProductTypeSecond())){
                    Integer length = Integer.valueOf(collect.get(bySectionNo.getProductTypeSecond()));
                    if(recutInfoDetailInfo.getType().equals(EnumValuesServer.LineType.晶段.getValue()) && recutInfoDetailInfo.getLength().compareTo(new BigDecimal(length)) < 0){
                        throw new RuntimeException("晶段长度小于有效长度" + length);
                    }
                } else {
                    throw new BusinessException("请前往数据字典配置规格为【" + bySectionNo.getProductTypeSecond() + "】的划线晶段可用长度控制");
                }
            }*/
        }
        this.productionRecutService.getSegmentNoV2(productionBackCuttingRecordDtos);
        return ResultGenerator.success(productionBackCuttingRecordDtos);
    }

    @ApiOperation(value = "Test")
    @PostMapping("/test1")
    public Result<List<ProductionBackCuttingRecordDto>> test(@RequestBody String text) {
        YbInspectData ybInspectData = JSONObject.parseObject(text, YbInspectData.class);
        this.productionRecutService.execProductionBackCuttingRecord(ybInspectData);
        return ResultGenerator.success();
    }

    public ProductionBackCuttingRecordDto toLazyDto(ProductionBackCuttingRecord entity) {
        return modelMapper.map(entity, ProductionBackCuttingRecordDto.class);
    }

    public ProductionBackCuttingRecordDto toEagerDto(ProductionBackCuttingRecord entity) {
        ProductionBackCuttingRecordDto dto = modelMapper.map(entity, ProductionBackCuttingRecordDto.class);
        return dto;
    }

    public ProductionBackCuttingRecord fromDto(ProductionBackCuttingRecordDto dto) {
        return modelMapper.map(dto, ProductionBackCuttingRecord.class);
    }
}
