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

import com.sw.mes.core.annotation.Jinko;
import com.sw.mes.core.context.BaseContextHandler;
import com.sw.mes.core.entity.SearchFilter;
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.yb.production.dto.RecycledMaterialManageDto;
import com.sw.mes.yb.production.dto.SurplusInfoDto;
import com.sw.mes.yb.production.entity.RecycledMaterialManage;
import com.sw.mes.yb.production.entity.SurplusInfo;
import com.sw.mes.yb.production.enums.WorkIndexRangeEnum;
import com.sw.mes.yb.production.service.RecycledMaterialManageDetailService;
import com.sw.mes.yb.production.service.SurplusInfoService;
import com.sw.mes.yb.production.utils.RecycledBatchGenerator;
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.domain.Sort;
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.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


/**
 * @Author
 * @Description：
 * @Date: Create in
 * @Modified By:
 */
@Jinko(author = "yyl", value = "余料采集关联接口")
@RestController
@RequestMapping("/surplusInfo")
@Slf4j
@Api(description = "余料采集关联接口", value = "余料采集关联接口")
public class SurplusInfoController {
    @Autowired
    ModelMapper modelMapper;

    @Autowired
    private SurplusInfoService surplusInfoService;

    @Autowired
    private RecycledMaterialManageDetailService recycledMaterialManageDetailService;

    @Autowired
    private RecycledBatchGenerator recycledBatchGenerator;

    @ApiOperation(value = "分页查询余料采集，余料采集关联列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "rows", value = "行数", dataType = "integer", paramType = "query"),
            @ApiImplicitParam(name = "page", value = "页码", dataType = "integer", paramType = "query"),
    })
    @GetMapping("/listByPage")
    public Result<ResponsePage<SurplusInfoDto>> listByPage(ServletRequest request, @ApiIgnore RequestPage requestPage) {
        Specification<SurplusInfo> specification = DynamicSpecifications.bySearchFilter(request, SurplusInfo.class);
        requestPage.setOrderField("createTime");
        requestPage.setOrderDirection(RequestPage.ORDER_DIRECTION_DESC);
        Page<SurplusInfo> page = surplusInfoService.findByExample(specification, PageUtil.createPageable(requestPage));
        List<SurplusInfoDto> dtos = page.getContent().stream()
                .map(entity -> toLazyDto(entity))
                .collect(Collectors.toList());
        ResponsePage responsePage = new ResponsePage(dtos, page.getTotalElements());
        return ResultGenerator.success(responsePage);
    }

    @Jinko(author = "yyl", value = "硅料加工记录-单晶余料采集记录-导出")
    @ApiOperation(value = "硅料加工记录-单晶余料采集记录-导出")
    @GetMapping("/export")
    public void export(ServletRequest request, HttpServletResponse response) {
        try {
            Specification<SurplusInfo> specification = DynamicSpecifications.bySearchFilter(request, SurplusInfo.class);
            List<SurplusInfo> list = surplusInfoService.findByExampleSort(specification, Sort.by(new Sort.Order(Sort.Direction.DESC, "createTime")));
            List<SurplusInfoDto> dtos = list.stream().map(entity -> toLazyDto(entity))
                    .collect(Collectors.toList());
            EasyExcelUtils.write(response, SurplusInfoDto.class, "单晶余料采集记录", "单晶余料采集记录", dtos);
        } catch (Exception e) {
            throw new RuntimeException("导出单晶余料采集记录失败，错误信息：" + e.getMessage());
        }
    }

    @ApiOperation(value = "获取所有余料采集信息")
    @GetMapping("/listAll")
    public Result<List<SurplusInfoDto>> listAll(ServletRequest request) {
        Specification<SurplusInfo> specification = DynamicSpecifications.bySearchFilter(request, SurplusInfo.class);
        List<SurplusInfo> surplusInfos = surplusInfoService.findByExampleSort(specification, null);
        List<SurplusInfoDto> surplusInfoDtos = surplusInfos.stream()
                .map(surplusInfo -> toLazyDto(surplusInfo))
                .collect(Collectors.toList());
        return ResultGenerator.success(surplusInfoDtos);
    }

    @ApiOperation(value = "余料采集信息关联详细信息")
    @GetMapping("/{id}")
    public Result<SurplusInfoDto> get(@PathVariable @ApiParam(value = "余料采集信息关联id") Long id) {
        SurplusInfo surplusInfo = surplusInfoService.get(id);
        if (null == surplusInfo) {
            return ResultGenerator.fail("该余料采集信息不存在");
        }
        return ResultGenerator.success(toEagerDto(surplusInfo));
    }

    @ApiOperation(value = "创建余料采集信息")
    @PostMapping("/create")
    public Result create(@RequestBody @Valid @ApiParam(value = "余料采集信息对象") SurplusInfoDto surplusInfoDto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        SurplusInfo surplusInfo;
        try {
            surplusInfo = surplusInfoService.saveData(surplusInfoDto);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultGenerator.fail(e.getMessage());
        }
        return ResultGenerator.success(surplusInfo);
    }

    @ApiOperation(value = "更新余料采集信息")
    @PostMapping("/update")
    public Result update(@RequestBody @Valid @ApiParam(value = "余料采集信息") SurplusInfoDto dto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        if (dto.getId() == null) {
            return ResultGenerator.fail("id不能为空");
        }
        SurplusInfo entity = surplusInfoService.get(dto.getId());
        if (entity == null) {
            return ResultGenerator.fail("原信息不存在");
        }
        try {
            SurplusInfo entityfromFto = fromDto(dto);
            BeanUtils.copyProperties(entityfromFto, entity, BeanUtil.getIgnoreProperties(entityfromFto, null, null));
            entity.setUpdateBy(BaseContextHandler.getUsername());
            entity.setUpdateTime(new Date());
            surplusInfoService.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 Integer[] ids) {
        for (Integer id : ids) {
            surplusInfoService.delete(id);
        }
        return ResultGenerator.success();
    }

    @ApiOperation(value = "通过炉台号查询最近的一条余料数据")
    @GetMapping("/queryLimitInfoByDeviceNo")
    public Result<SurplusInfo> queryLimitInfoByDeviceNo(@RequestParam String deviceNo) {
        SurplusInfo surplusInfo = surplusInfoService.queryLimitInfoByDeviceNo(deviceNo);
        if (null == surplusInfo) {
            return ResultGenerator.fail("该炉台无余料数据");
        }
        return ResultGenerator.success(surplusInfo);
    }

    @ApiOperation(value = "通过回收料条码号查询余料数据")
    @GetMapping("/queryLimitInfoBySurplusCode")
    public Result<SurplusInfoDto> queryLimitInfoBySurplusCode(@RequestParam String surplusCode) {
        SurplusInfo surplusInfo = surplusInfoService.queryLimitInfoBySurplusCode(surplusCode);
        if (null == surplusInfo) {
            return ResultGenerator.fail("该编号单晶余料数据不存在");
        }
        List<String> surplusCodes = new ArrayList<>();
        surplusCodes.add(surplusCode);
        List<String> usedRecycleNos = recycledMaterialManageDetailService.getDetailByRecycleNos(surplusCodes);
        if (usedRecycleNos != null && !usedRecycleNos.isEmpty() && usedRecycleNos.size() > 0) {
            return ResultGenerator.fail("余料编码:" + surplusCode + "已被组托!");
        }
        SurplusInfoDto surplusInfoDto = toEagerDto(surplusInfo);
        if (StringUtils.isNotBlank(surplusInfo.getArea()) && surplusInfo.getArea().length() > 5) {
            surplusInfoDto.setWorkShop(surplusInfo.getArea().substring(4, 5));
        } else {
            throw new BusinessException("数据异常,工单[" + surplusInfo.getWorkOrderNo() + "]:不存在成本中心!");
        }
        return ResultGenerator.success(surplusInfoDto);
    }

    @ApiOperation(value = "通过回收料条码号查询余料历史数据")
    @GetMapping("/queryHistoryInfoBySurplusCode")
    public Result<SurplusInfoDto> queryInfoBySurplusCode(@RequestParam String surplusCode) {
        SurplusInfo surplusInfo = surplusInfoService.queryLimitInfoBySurplusCode(surplusCode);
        if (null == surplusInfo) {
            return ResultGenerator.fail("该编号单晶余料数据不存在");
        }
        SurplusInfoDto surplusInfoDto = toEagerDto(surplusInfo);
        return ResultGenerator.success(surplusInfoDto);
    }

    @ApiOperation(value = "无条码单晶余料生成虚拟条码号")
    @GetMapping("/buildVirtuallySurplusBatchNo")
    public Result<String> buildVirtuallySurplusBatchNo(@RequestParam String workOrderNo, @RequestParam String workShop) {
        String str = recycledBatchGenerator.buildVirtuallySurplusBatchNo(workOrderNo + workShop);
        SurplusInfo oldSurplusInfo = surplusInfoService.queryLimitInfoBySurplusCode(str);
        //暂时做一次校验处理
        if (null != oldSurplusInfo) {
            str = recycledBatchGenerator.buildVirtuallySurplusBatchNo(workOrderNo + workShop);
        }
        return ResultGenerator.success(str);
    }

    public SurplusInfoDto toLazyDto(SurplusInfo entity) {
        return modelMapper.map(entity, SurplusInfoDto.class);
    }

    public SurplusInfoDto toEagerDto(SurplusInfo entity) {
        SurplusInfoDto dto = modelMapper.map(entity, SurplusInfoDto.class);
        if (StringUtils.isNotBlank(entity.getArea()) && entity.getArea().length() > 5) {
            dto.setWorkShop(entity.getArea().substring(WorkIndexRangeEnum.车间号.getBeginIndex(), WorkIndexRangeEnum.车间号.getEndIndex()));
        }
        return dto;
    }

    public SurplusInfo fromDto(SurplusInfoDto dto) {
        return modelMapper.map(dto, SurplusInfo.class);
    }


}
