package com.sw.mes.issue.controller;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import com.sw.mes.core.utils.StringUtils;
import com.sw.mes.inspect.entity.YbInspectData;
import com.sw.mes.inspect.service.YbInspectDataService;
import org.apache.commons.collections.CollectionUtils;
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.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.sw.mes.base.workinprocess.entity.PlanProcessingOrder;
import com.sw.mes.base.workinprocess.service.PlanProcessingOrderService;
import com.sw.mes.core.enums.EnumValuesFactory;
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.BeanUtil;
import com.sw.mes.core.utils.DynamicSpecifications;
import com.sw.mes.core.utils.PageUtil;
import com.sw.mes.core.utils.RequestPage;
import com.sw.mes.issue.dto.McsYbIssueDto;
import com.sw.mes.issue.dto.YbIssueDetialDto;
import com.sw.mes.issue.dto.YbIssueDto;
import com.sw.mes.issue.dto.YbIssueToDetailDto;
import com.sw.mes.issue.entity.YbIssue;
import com.sw.mes.issue.entity.YbIssueDetial;
import com.sw.mes.issue.service.YbIssueDetialService;
import com.sw.mes.issue.service.YbIssueRecordService;
import com.sw.mes.issue.service.YbIssueService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import springfox.documentation.annotations.ApiIgnore;

/**
 * @Author @Description：
 * @Date: Create in
 * @Modified By:
 */
@RestController
@RequestMapping("/ybIssue")
@Api(description = "圆棒发料关联接口")
public class YbIssueController {

    @Autowired
    ModelMapper modelMapper;

    @Autowired
    private YbIssueService ybIssueService;

    @Autowired
    private YbIssueDetialService ybIssueDetialService;

    @Autowired
    private YbIssueRecordService ybIssueRecordService;

    @Autowired
    private PlanProcessingOrderService planProcessingOrderService;

    @Autowired
    private YbInspectDataService ybInspectDataService;

    @ApiOperation(value = "分页查询圆棒发料列表")
    @ApiImplicitParams({ @ApiImplicitParam(name = "rows", value = "行数", dataType = "integer", paramType = "query"),
            @ApiImplicitParam(name = "page", value = "页码", dataType = "integer", paramType = "query"),
            @ApiImplicitParam(name = "trayNo", value = "托号", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "search_LIKE_destination", value = "去向", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "search_GTE_time", value = "开始时间", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "search_EQ_crystalNo", value = "单晶编号", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "search_LTE_time", value = "结束时间", dataType = "String", paramType = "query"), })
    @GetMapping("/listByPage")
    public Result<ResponsePage<YbIssueDto>> listByPage(ServletRequest request, @ApiIgnore RequestPage requestPage) {

        if (null != request.getParameter("search_EQ_crystalNo") || !StringUtils.isEmpty(request.getParameter("search_EQ_crystalNo"))){
            requestPage.setOrderField(null);

            String startTime = null;
            if (!StringUtils.isEmpty(request.getParameter("search_GTE_time"))){
                startTime = request.getParameter("search_GTE_time");
            }
            String endTime = null;
            if (!StringUtils.isEmpty(request.getParameter("search_LTE_time"))){
                endTime = request.getParameter("search_LTE_time");
            }
            Integer status = null;
            if (!StringUtils.isEmpty(request.getParameter("search_EQ_status"))){
                status=Integer.parseInt(request.getParameter("search_EQ_status"));
            }
            String trayNo = null;
            if (!StringUtils.isEmpty(request.getParameter("search_EQ_trayNo"))){
                trayNo = request.getParameter("search_EQ_trayNo");
            }
            ResponsePage<YbIssueDto> pageList = ybIssueService.getPageList(trayNo, status, startTime, endTime, request.getParameter("search_EQ_crystalNo"), PageUtil.createPageable(requestPage));
            return ResultGenerator.success(pageList);
        }

        Specification<YbIssue> specification = DynamicSpecifications.bySearchFilter(request, YbIssue.class);
        Page<YbIssue> page = ybIssueService.findByExample(specification, PageUtil.createPageable(requestPage,new String[]{"destination DESC","status ASC","id DESC"}));
        List<YbIssueDto> dtos = page.getContent().stream().map(entity -> toLazyDto(entity))
                .collect(Collectors.toList());
        ResponsePage responsePage = new ResponsePage(dtos, page.getTotalElements());
        return ResultGenerator.success(responsePage);
    }


//    /**
//     * 联表查询
//     * @param
//     * @param requestPage
//     * @return
//     */
//    @ApiOperation(value = "分页查询圆棒发料列表")
//    @ApiImplicitParams({ @ApiImplicitParam(name = "rows", value = "行数", dataType = "integer", paramType = "query"),
//            @ApiImplicitParam(name = "page", value = "页码", dataType = "integer", paramType = "query"),
//            @ApiImplicitParam(name = "search_EQ_trayNo", value = "托号", dataType = "string", paramType = "query"),
//            @ApiImplicitParam(name = "search_EQ_status", value = "状态", dataType = "integer", paramType = "query"),
//            @ApiImplicitParam(name = "search_EQ_crystalNo", value = "单晶编号", dataType = "String", paramType = "query"),
//            @ApiImplicitParam(name = "search_GTE_time", value = "开始时间", dataType = "Date", paramType = "query"),
//            @ApiImplicitParam(name = "search_LTE_time", value = "结束时间", dataType = "Date", paramType = "query"),})
//    @GetMapping("/listByPage")
//    public Result<ResponsePage<YbIssueDto>> listByPage(String search_EQ_trayNo, Integer search_EQ_status, String search_GTE_time, String search_LTE_time,String search_EQ_crystalNo, @ApiIgnore RequestPage requestPage) {
//        requestPage.setOrderField(null);
//        if (StringUtils.isBlank(search_EQ_trayNo)) search_EQ_trayNo = null;
//        if (StringUtils.isBlank(search_EQ_crystalNo)) search_EQ_crystalNo = null;
//        if (StringUtils.isBlank(search_GTE_time)) search_GTE_time = null;
//        if (StringUtils.isBlank(search_LTE_time)) search_LTE_time = null;
//
//        ResponsePage<YbIssueDto> pageList = ybIssueService.getPageList(search_EQ_trayNo, search_EQ_status, search_GTE_time, search_LTE_time, search_EQ_crystalNo, PageUtil.createPageable(requestPage));
//        return ResultGenerator.success(pageList);
//    }




    @ApiOperation(value = "导出圆棒发料记录接口")
    @ApiImplicitParams({ @ApiImplicitParam(name = "trayNo", value = "托号", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "search_GTE_time", value = "开始时间", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "search_LTE_time", value = "结束时间", dataType = "String", paramType = "query"), })
    @GetMapping("/exportExcel")
    public void export(HttpServletRequest request, HttpServletResponse response) {
        try {
            String trayNo = request.getParameter("trayNo");
            String startTime = request.getParameter("search_GTE_time");
            String endTime = request.getParameter("search_LTE_time");

            List<Map<String, Object>> mapList = ybIssueService.queryListByParam(trayNo, startTime, endTime);
            List<YbIssueToDetailDto> list = mapList.stream()
                    .map(item -> JSON.parseObject(JSON.toJSONString(item), YbIssueToDetailDto.class))
                    .collect(Collectors.toList());

            ybIssueService.exportExcel(request, response, list);
        } catch (Exception e) {
            throw new RuntimeException("导出圆棒发料记录表失败，错误信息：" + e.getMessage());
        }
    }

    @ApiOperation(value = "获取所有圆棒发料关联")
    @GetMapping("/listAll")
    public Result<List<YbIssueDto>> listAll(ServletRequest request) {
        Specification<YbIssue> specification = DynamicSpecifications.bySearchFilter(request, YbIssue.class);
        List<YbIssue> ybIssues = ybIssueService.findByExampleSort(specification, null);
        List<YbIssueDto> ybIssueDtos = ybIssues.stream().map(ybIssue -> toLazyDto(ybIssue))
                .collect(Collectors.toList());
        return ResultGenerator.success(ybIssueDtos);
    }

    @ApiOperation(value = "圆棒发料关联详细信息")
    @GetMapping("/{id}")
    public Result<YbIssueDto> get(@PathVariable @ApiParam(value = "圆棒发料关联id") Long id) {
        YbIssueDto dto = new YbIssueDto();
        YbIssue ybIssue = ybIssueService.get(id);
        YbIssueDto ybIssueDto = toEagerDto(ybIssue);
        BeanUtils.copyProperties(ybIssueDto, dto);
        List<YbIssueDetial> byIssueId = ybIssueDetialService.findByIssueId(id);
        List<YbIssueDetialDto> collect = byIssueId.stream().map(ybIssueDetial -> toLazyDtos(ybIssueDetial))
                .collect(Collectors.toList());
        dto.setDetialDtoList(collect);
        if (null == ybIssue)
            return ResultGenerator.fail("该圆棒发料关联不存在");
        return ResultGenerator.success(dto);
    }

    @ApiOperation(value = "创建圆棒发料关联")
    @PostMapping("/create")
    public Result create(@RequestBody @Valid @ApiParam(value = "圆棒发料关联对象") YbIssueDto ybIssueDto,
            BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
//      YbIssue ybIssue = fromDto(ybIssueDto);
        ybIssueService.saveYbIssue(ybIssueDto);
        return ResultGenerator.success();
    }

    @ApiOperation(value = "圆棒发料获取单晶编号")
    @GetMapping("/getNo")
    public Result getNo(String no) {
        Map<String, Object> cryNo = ybIssueService.getNo(no);
        if (null != cryNo && cryNo.size() > 0) {
            return ResultGenerator.success(cryNo);
        }
        return ResultGenerator.fail(no + "该工单不是圆棒检验进站--加工中状态！");
    }

    @ApiOperation(value = "更新圆棒发料关联")
    @PostMapping("/update")
    public Result update(@RequestBody @Valid @ApiParam(value = "圆棒发料关联") YbIssueDto dto, BindingResult bindingResult) {
        if (StringUtils.isEmpty(dto.getDestination())){
            return ResultGenerator.fail("去向为空！");
        }
        if (bindingResult.hasErrors())
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        if (dto.getId() == null)
            return ResultGenerator.fail("id不能为空");
        YbIssue entity = ybIssueService.get(dto.getId());
        if (entity == null)
            return ResultGenerator.fail("原信息不存在");
        try {
            YbIssue entityfromFto = fromDto(dto);
            BeanUtils.copyProperties(entityfromFto, entity, BeanUtil.getIgnoreProperties(entityfromFto, null, null));
            ybIssueService.saveOrUpdate(entity);

            // 编辑详情
            for (YbIssueDetialDto ybIssueDetialDto : dto.getDetialDtoList()) {
                if (null != ybIssueDetialDto) {

                    // 增加卡控 ，防止晶棒类型（回收料、非回收料）与发料去向不匹配
                    YbInspectData inspectDataBase = ybInspectDataService.findBySectionNo(ybIssueDetialDto.getCrystalNo());
                    if(null == inspectDataBase){
                        return ResultGenerator.fail("检验数据不存在");
                    }
                    if (StringUtils.isEmpty(inspectDataBase.getGradeType())){
                        return ResultGenerator.fail("圆棒评级分类为空！");
                    }
                    if (dto.getDestination().equals("回收料")) {
                        if (!inspectDataBase.getGradeType().contains("回收料")){
                            return ResultGenerator.fail(ybIssueDetialDto.getCrystalNo()+":该晶棒评级分类为:"+inspectDataBase.getProductLevel()+",请选择去向：开方");
                        }
                    }else if (dto.getDestination().equals("开方")){
                        if (inspectDataBase.getGradeType().contains("回收料")){
                            return ResultGenerator.fail(ybIssueDetialDto.getCrystalNo()+":该晶棒评级分类为:"+inspectDataBase.getProductLevel()+",请选择去向：回收料");
                        }
                    }

                    YbIssueDetial ybIssueDetial = new YbIssueDetial();
                    String crystalNo = ybIssueDetialService.findByCrystalNoAndIssueId(ybIssueDetialDto.getCrystalNo());
                    if (null == crystalNo) {
                        BeanUtils.copyProperties(ybIssueDetialDto, ybIssueDetial);
                        ybIssueDetial.setIssueId(dto.getId());
                        ybIssueDetialService.saveOrUpdate(ybIssueDetial);
                        if((null != ybIssueDetialDto.getDestination() && !ybIssueDetialDto.getDestination().equals("回收料")) || null == ybIssueDetialDto.getDestination()){
                            updatePlanProcessingOrder(ybIssueDetial.getCrystalNo());
                        }
                        ybIssueRecordService.deleteErrorRecord(ybIssueDetial.getCrystalNo());
                    } else if (null != crystalNo && null != ybIssueDetialDto.getId()
                            && null != ybIssueDetialDto.getIssueId()) {
                        BeanUtils.copyProperties(dto, ybIssueDetial);
                        ybIssueDetialService.saveOrUpdate(ybIssueDetial);
                    } else {
                        throw new RuntimeException("该单晶编号:" + crystalNo + "不是加工中的状态！");
                    }
                }
            }
            // 保存数量
            List<YbIssueDetial> list = ybIssueDetialService.findByIssueId(dto.getId());
            if (CollectionUtils.isNotEmpty(list))
                entity.setNum(list.size());
            ybIssueService.saveOrUpdate(entity);
            return ResultGenerator.success();
        } catch (Exception e) {
            return ResultGenerator.fail(e.getMessage());
        }
    }

    @ApiOperation(value = "更新圆棒发料状态")
    @PostMapping("/getStatus")
    public Result updateStatus(@RequestBody @Valid @ApiParam(value = "更新圆棒发料状态") YbIssueDto dto,
            BindingResult bindingResult) {
        if (bindingResult.hasErrors())
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        if (dto.getId() == null)
            return ResultGenerator.fail("id不能为空");
        YbIssue entity = ybIssueService.get(dto.getId());
        if (entity == null)
            return ResultGenerator.fail("原信息不存在");
        try {
            // 开方待进站
            ybIssueService.updateState(dto);
            YbIssue entityfromFto = fromDto(dto);
            BeanUtils.copyProperties(entityfromFto, entity, BeanUtil.getIgnoreProperties(entityfromFto, null, null));
            ybIssueService.saveOrUpdate(entity);
            return ResultGenerator.success();
        } catch (Exception e) {
            return ResultGenerator.fail(e.getMessage());
        }
    }

    @ApiOperation(value = "删除圆棒发料关联")
    @PostMapping("/delete")
    public Result remove(@ApiParam(value = "id集合,逗号分隔,如2,4", type = "query") @RequestParam Long id) {
        ybIssueService.delete(id);
        List<YbIssueDetial> byIssueId = ybIssueDetialService.findByIssueId(id);
        // 删除对应的单晶
        if (CollectionUtils.isNotEmpty(byIssueId)) {
            for (YbIssueDetial ybIssueDetial : byIssueId) {
                if (null != ybIssueDetial) {
                    ybIssueDetialService.delete(ybIssueDetial.getId());
                    updatePlanProcessingOrder1(ybIssueDetial.getCrystalNo());
                }
            }
        }

        return ResultGenerator.success();
    }

    @ApiOperation(value = "删除圆棒发料详情")
    @PostMapping("/deleteDetial")
    public Result deleteDetial(@ApiParam(value = "id集合,逗号分隔,如2,4", type = "query") @RequestParam Long[] id) {

        for (Long idParam : id) {
            YbIssueDetial ybIssueDetial = ybIssueDetialService.get(idParam);
            if (null != ybIssueDetial) {
                updatePlanProcessingOrder1(ybIssueDetial.getCrystalNo());
            }
            ybIssueDetialService.delete(idParam);
        }

        return ResultGenerator.success();
    }

    @ApiOperation(value = "批量创建圆棒发料关联")
    @PostMapping("/creations")
    public Result creations(@RequestBody @ApiParam(value = "MCS侧圆棒发料关联对象") McsYbIssueDto dto,
            BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        ybIssueService.creations(dto);
        return ResultGenerator.success();
    }

    @ApiOperation(value = "更新圆棒状态到开方待进站")
    @GetMapping("/updateStatusToKF")
    public Result updateStatusToKF(@ApiParam(value = "晶段编号", type = "query") @RequestParam String section) {
        if (StringUtils.isEmpty(section)) {
            return ResultGenerator.fail("入参晶编不能为空!");
        }
        try {
            // 开方待进站
            ybIssueService.updateState(section);
            return ResultGenerator.success();
        } catch (Exception e) {
            return ResultGenerator.fail(e.getMessage());
        }
    }

    public YbIssueDto toLazyDto(YbIssue entity) {
        return modelMapper.map(entity, YbIssueDto.class);
    }

    public YbIssueDetialDto toLazyDtos(YbIssueDetial entity) {
        return modelMapper.map(entity, YbIssueDetialDto.class);
    }

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

    public YbIssue fromDto(YbIssueDto dto) {
        return modelMapper.map(dto, YbIssue.class);
    }

    public void updatePlanProcessingOrder(String code) {
        PlanProcessingOrder byCode = planProcessingOrderService.findByCode(code);
        if (null != byCode) {
            byCode.setStatus(EnumValuesFactory.PlanProcessingOrderStatus.组托.getKey());
            planProcessingOrderService.saveOrUpdate(byCode);
        }
    }

    public void updatePlanProcessingOrder1(String code) {
        PlanProcessingOrder byCode = planProcessingOrderService.findByCode(code);
        if (null != byCode) {
            byCode.setStatus(EnumValuesFactory.PlanProcessingOrderStatus.加工中.getKey());
            planProcessingOrderService.saveOrUpdate(byCode);
        }
    }
}