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

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sw.mes.core.context.BaseContextHandler;
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.seed.dto.*;
import com.sw.mes.yb.seed.entity.SeedData;
import com.sw.mes.yb.seed.entity.SeedGroupBracketDetails;
import com.sw.mes.yb.seed.entity.SeedIQCInspection;
import com.sw.mes.yb.seed.entity.SeedSelfInspection;
import com.sw.mes.yb.seed.service.SeedGroupBracketDetailsService;
import com.sw.mes.yb.seed.service.SeedIQCInspectionService;
import com.sw.mes.yb.seed.service.SeedSelfInspectionService;
import com.sw.mes.yb.seed.service.SeedService;
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.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
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.Optional;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/seed/iqc")
@Slf4j
@Api(description = "籽晶iqc检测接口")
@Transactional
public class SeedIQCInspectionController {
    @Autowired
    ModelMapper modelMapper;
    @Autowired
    private SeedIQCInspectionService seedIQCInspectionService;
    @Autowired
    private SeedSelfInspectionService seedSelfInspectionService;
    @Autowired
    private SeedService seedService;
    @Autowired
    private SeedGroupBracketDetailsService seedGroupBracketDetailsService;

    @ApiOperation(value = "分页查询籽晶信息列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "rows", value = "行数", dataType = "integer", paramType = "query"),
            @ApiImplicitParam(name = "page", value = "页码", dataType = "integer", paramType = "query"),
    })
    @GetMapping("/listByPage")
    public Result<ResponsePage<SeedIQCInspectionDto>> listByPage(ServletRequest request, @ApiIgnore RequestPage requestPage) {
        Specification<SeedIQCInspection> specification = DynamicSpecifications.bySearchFilter(request, SeedIQCInspection.class);
        Page<SeedIQCInspection> selfInspections = seedIQCInspectionService.findByExample(specification, PageUtil.createPageable(requestPage));
        List<SeedIQCInspectionDto> dtos = selfInspections.getContent().stream().map(entity ->
                toLazyDto(entity)).collect(Collectors.toList());
        ResponsePage responsePage = new ResponsePage(dtos, selfInspections.getTotalElements());
        return ResultGenerator.success(responsePage);
    }

    @GetMapping("/qualified/listAll")
    @ApiOperation(value = "查询籽晶IQC检验合格/不合格的数据")
    public Result<List<SeedIQCInspectionDto>> qualified(Boolean isQualified) {
        List<SeedIQCInspection> selfInspections = seedIQCInspectionService.getQualified(isQualified);
        List<SeedIQCInspectionDto> dtos = selfInspections.stream().map(entity ->
                toLazyDto(entity)).collect(Collectors.toList());
        return ResultGenerator.success(dtos);
    }

    @GetMapping("/listAll")
    @ApiOperation(value = "查询籽晶IQC检验信息列表")
    public Result<List<SeedIQCInspectionDto>> listAll(ServletRequest request) {
        Specification<SeedIQCInspection> specification = DynamicSpecifications.bySearchFilter(request, SeedIQCInspection.class);
        List<SeedIQCInspection> selfInspections = seedIQCInspectionService.findByExampleSort(specification, null);
        List<SeedIQCInspectionDto> dtos = selfInspections.stream().map(entity ->
                toLazyDto(entity)).collect(Collectors.toList());
        return ResultGenerator.success(dtos);
    }

    @GetMapping("/{id}")
    @ApiOperation(value = "通过ID查询籽晶IQC检验信息")
    public Result<SeedIQCInspectionDto> getById(@PathVariable @ApiParam(value = "id") Long id) {
        SeedIQCInspection SeedIQCInspection = seedIQCInspectionService.get(id);
        if (ObjectUtils.isEmpty(SeedIQCInspection)) {
            return ResultGenerator.fail("未查到相关数据!");
        }
        return ResultGenerator.success(toEagerDto(SeedIQCInspection));
    }

    @ApiOperation(value = "创建籽晶IQC检验信息")
    @PostMapping("/create")
    public Result create(@RequestBody @Valid @ApiParam(value = "SeedIQCInspectionDto的对象") SeedIQCInspectionDto seedIQCInspectionDto
            , BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        SeedSelfInspection seedSelfInspection = seedSelfInspectionService.getBySeedCode(seedIQCInspectionDto.getSeedCode());
        if (null == seedSelfInspection) {
            return ResultGenerator.fail("该籽晶未进行自检,请确认数据!");
        }
        return seedIQCInspectionService.create(seedIQCInspectionDto);
    }

    @ApiOperation(value = "修改籽晶IQC检验信息")
    @PostMapping("/update")
    public Result update(@RequestBody @Valid @ApiParam(value = "SeedIQCInspectionDto的对象") SeedIQCInspectionDto SeedIQCInspectionDto
            , BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        SeedIQCInspection seedCode = seedIQCInspectionService.getBySeedCode(SeedIQCInspectionDto.getSeedCode());
        if (ObjectUtils.isEmpty(seedCode)) {
            return ResultGenerator.fail("该数据不存在!");
        }
        SeedIQCInspection SeedIQCInspection = fromDto(SeedIQCInspectionDto);
        SeedIQCInspection.setId(seedCode.getId());
        SeedIQCInspection.setUpdateBy(BaseContextHandler.getUsername());
        SeedIQCInspection.setUpdateDate(new Date());
        seedIQCInspectionService.saveOrUpdate(SeedIQCInspection);
        SeedData seedData = seedService.findByCode(seedCode.getSeedCode());
        if (!ObjectUtils.isEmpty(seedData)) {
            if (SeedIQCInspection.getIsQualified() == true) {
                seedData.setSelfQualified(true);
                seedData.setDetectionTime(SeedIQCInspection.getUpdateDate());
                seedService.saveOrUpdate(seedData);
            } else {
                seedData.setSelfQualified(false);
                seedData.setDetectionTime(SeedIQCInspection.getUpdateDate());
                seedService.saveOrUpdate(seedData);
            }
        }
        return ResultGenerator.success();
    }

    @ApiOperation(value = "批量修改籽晶IQC检验信息")
    @PostMapping("/batchUpdate")
    public Result batchUpdate(@RequestBody @Valid @ApiParam(value = "SeedIQCInspectionDto的对象") List<SeedIQCInspectionDto> SeedIQCInspectionDtos
            , BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        SeedIQCInspectionDtos.stream().forEach(seedIQCInspectionDto -> {
            SeedIQCInspection SeedIQCInspection = fromDto(seedIQCInspectionDto);
            SeedIQCInspection.setId(seedIQCInspectionDto.getId());
            SeedIQCInspection.setUpdateBy(BaseContextHandler.getUsername());
            SeedIQCInspection.setUpdateDate(new Date());
            seedIQCInspectionService.saveOrUpdate(SeedIQCInspection);
        });
        return ResultGenerator.success();
    }

    @ApiOperation(value = "删除籽晶IQC检验信息")
    @PostMapping("/delete")
    public Result remove(@ApiParam(value = "id集合,逗号分隔,如2,4", type = "query") @RequestParam Long[] ids) {
        for (Long id : ids) {
            seedIQCInspectionService.delete(id);
        }
        return ResultGenerator.success();
    }

    @GetMapping("/seedCode")
    @ApiOperation(value = "通过籽晶编码查询籽晶IQC检验信息")
    public Result<SeedIQCInspectionDto> getSeedCode(@RequestParam @ApiParam(value = "seedCode") String seedCode) {
        SeedSelfInspection seedSelfInspection = seedSelfInspectionService.getBySeedCode(seedCode);
        if (null == seedSelfInspection) {
            return ResultGenerator.fail("该籽晶未进行自检,请确认数据!");
        }
        SeedIQCInspection seedData = seedIQCInspectionService.getBySeedCode(seedCode);
        SeedIQCInspection seedDatas = new SeedIQCInspection();
        if (ObjectUtils.isEmpty(seedData)) {
            BeanUtils.copyProperties(seedSelfInspection, seedDatas, "id");
            return ResultGenerator.success(toEagerDto(seedDatas));
        }
        return ResultGenerator.success(toEagerDto(seedData));
    }

    @GetMapping("/seedBatchNo")
    @ApiOperation(value = "通过籽晶序列号查询籽晶IQC检验信息")
    public Result<SeedIQCInspectionDto> getSeedBatchNo(@RequestParam @ApiParam(value = "seedBatchNo") String seedBatchNo) {
        SeedIQCInspection seedData = seedIQCInspectionService.getBySeedBatchNo(seedBatchNo);
        return ResultGenerator.success(toEagerDto(seedData));
    }

    @GetMapping("/planCode")
    @ApiOperation(value = "通过籽晶计划单号查询籽晶IQC检验信息")
    public Result<List<SeedIQCInspection>> getByPlanCode(@RequestParam @ApiParam(value = "planCode") String planCode) {
        List<SeedIQCInspection> selfInspections = seedIQCInspectionService.getByPlanCode(planCode);
        return ResultGenerator.success(selfInspections);
    }

    @GetMapping("/batchNo")
    @ApiOperation(value = "通过序列号查询IQC合格/不合格检验信息")
    public Result<List<SeedIQCInspection>> getBatchNo(@RequestParam @ApiParam(value = "batchNo") String batchNo
            , @RequestParam @ApiParam(value = "isQualified") Boolean isQualified) {
        List<SeedIQCInspection> inspections = seedIQCInspectionService.getByBatchNo(batchNo, isQualified);
        return ResultGenerator.success(inspections);
    }

    @ApiOperation(value = "分页查询籽晶自检andIQC检测信息列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "rows", value = "行数", dataType = "integer", paramType = "query"),
            @ApiImplicitParam(name = "page", value = "页码", dataType = "integer", paramType = "query"),
    })
    @GetMapping("/listSelfIQCPage")
    public Result<ResponsePage<SelfIQCInspectionDto>> listSelfIQCPage(ServletRequest request, @ApiIgnore RequestPage requestPage) {
        Specification<SeedData> specification = DynamicSpecifications.bySearchFilter(request, SeedData.class);
        Page<SeedData> seedDataPage = seedService.findByExample(specification, PageUtil.createPageable(requestPage));
        List<String> seedDatas = seedDataPage.getContent().stream().map(entity -> {
            return entity.getSeedCode();
        }).collect(Collectors.toList());
        List<SeedIQCInspection> seedIQCInspections = seedIQCInspectionService.getIQCInspectionBySeedCodes(seedDatas);
        List<SeedSelfInspection> seedSelfInspections = seedSelfInspectionService.getSelfInspectionBySeedCode(seedDatas);
        List<SeedIQCInspectionDto> seedIQCInspectionDtos = seedIQCInspections.stream().map(entity ->
                toLazyDto(entity)).collect(Collectors.toList());
        List<SeedSelfInspectionDto> seedSelfInspectionDtos = seedSelfInspections.stream().map(entity ->
                toLazySelfDto(entity)).collect(Collectors.toList());
        List<SelfIQCInspectionDto> dtos = new ArrayList<>();
        List<SeedData> seedAll = seedDataPage.getContent();
        seedAll.stream().forEach(seedData -> {
            SelfIQCInspectionDto selfIQCInspectionDto = new SelfIQCInspectionDto();
            selfIQCInspectionDto.setSeedCode(seedData.getSeedCode());
            SeedDataDto lazySeedDto = toLazySeedDto(seedData);
            selfIQCInspectionDto.setSeedDataDto(lazySeedDto);
            Optional<SeedIQCInspectionDto> iqcInspectionDto = seedIQCInspectionDtos.stream().filter(entity ->
                    entity.getSeedCode().equals(seedData.getSeedCode())).findFirst();
            if (iqcInspectionDto.isPresent()) {
                selfIQCInspectionDto.setSeedIQCInspection(iqcInspectionDto.get());
            }
            Optional<SeedSelfInspectionDto> selfInspectionDto = seedSelfInspectionDtos.stream().filter(entity ->
                    entity.getSeedCode().equals(seedData.getSeedCode())).findFirst();
            if (selfInspectionDto.isPresent()) {
                selfIQCInspectionDto.setSeedSelfInspection(selfInspectionDto.get());
            }
            dtos.add(selfIQCInspectionDto);
        });
        ResponsePage responsePage = new ResponsePage(dtos, seedDataPage.getTotalElements());
        return ResultGenerator.success(responsePage);
    }


    @ApiOperation(value = "导出籽晶质检信息接口")
    @GetMapping("/exportExcel")
    public void export(ServletRequest request, HttpServletResponse response) {
        try {
            Specification<SeedData> specification = DynamicSpecifications.bySearchFilter(request, SeedData.class);
            List<SeedData> seedAll = seedService.findByExampleSort(specification, null);
            List<String> seedDatas = seedAll.stream().map(entity -> {
                return entity.getSeedCode();
            }).collect(Collectors.toList());
            List<SeedIQCInspection> seedIQCInspections = seedIQCInspectionService.getIQCInspectionBySeedCodes(seedDatas);
            List<SeedSelfInspection> seedSelfInspections = seedSelfInspectionService.getSelfInspectionBySeedCode(seedDatas);
            List<SeedIQCInspectionDto> seedIQCInspectionDtos = seedIQCInspections.stream().map(entity ->
                    toLazyDto(entity)).collect(Collectors.toList());
            List<SeedSelfInspectionDto> seedSelfInspectionDtos = seedSelfInspections.stream().map(entity ->
                    toLazySelfDto(entity)).collect(Collectors.toList());
            List<InspectionDto> dtos = new ArrayList<>();
            seedAll.stream().forEach(seedData -> {
                InspectionDto inspectionDto = new InspectionDto();
                BeanUtils.copyProperties(seedData, inspectionDto);
                Optional<SeedIQCInspectionDto> iqcInspectionDto = seedIQCInspectionDtos.stream().filter(entity ->
                        entity.getSeedCode().equals(seedData.getSeedCode())).findFirst();
                if (iqcInspectionDto.isPresent()) {
                    SeedIQCInspectionDto seedIQCInspectionDto = iqcInspectionDto.get();
                    inspectionDto.setIqcTaper(seedIQCInspectionDto.getTaper());
                    inspectionDto.setIqcTotalLength(seedIQCInspectionDto.getTotalLength());
                    inspectionDto.setIqcTheWeight(seedIQCInspectionDto.getTheWeight());
                    inspectionDto.setIqcTotalBigLength(seedIQCInspectionDto.getTotalBigLength());
                    inspectionDto.setIqcSmallLength(seedIQCInspectionDto.getSmallLength());
                    inspectionDto.setIqcSmallAverageDiameter(seedIQCInspectionDto.getSmallAverageDiameter());
                    inspectionDto.setIqcBigDiameterMin(seedIQCInspectionDto.getBigDiameterMin());
                    inspectionDto.setIqcSmallDiameterMin(seedIQCInspectionDto.getSmallDiameterMin());
                    inspectionDto.setIqcSmallDiameterMax(seedIQCInspectionDto.getSmallDiameterMax());
                    inspectionDto.setIqcBigDiameterMax(seedIQCInspectionDto.getBigDiameterMax());
                    inspectionDto.setIqcCoaxiality(seedIQCInspectionDto.getCoaxiality());
                    inspectionDto.setIqcSubfissure(seedIQCInspectionDto.getSubfissure());
                    inspectionDto.setIqcCreateBy(seedIQCInspectionDto.getCreateBy());
                    inspectionDto.setIqcIsQualified(seedIQCInspectionDto.getIsQualified());
                    inspectionDto.setIqcCreateDate(seedIQCInspectionDto.getCreateDate());

                }
                Optional<SeedSelfInspectionDto> selfInspectionDto = seedSelfInspectionDtos.stream().filter(entity ->
                        entity.getSeedCode().equals(seedData.getSeedCode())).findFirst();
                if (selfInspectionDto.isPresent()) {
                    BeanUtils.copyProperties(selfInspectionDto.get(), inspectionDto);
                }
                dtos.add(inspectionDto);
            });
            ExcelUtil.exportExcel(dtos, "导出籽晶质检信息接口", InspectionDto.class, response);
        } catch (Exception e) {
            throw new RuntimeException("导出籽晶质检导出失败，错误信息：" + e.getMessage());
        }
    }

    @ApiOperation(value = "导出籽晶IQC检信息接口")
    @GetMapping("/exportExcelOne")
    public void export1(ServletRequest request, HttpServletResponse response) {
        Specification<SeedIQCInspection> specification = DynamicSpecifications.bySearchFilter(request, SeedIQCInspection.class);
        List<SeedIQCInspection> byExampleSort = seedIQCInspectionService.findByExampleSort(specification, null);
        List<SeedIQCInspectionDto> dtos = byExampleSort.stream().map(entity ->
                toLazyDto(entity)).collect(Collectors.toList());
        ExcelUtil.exportExcel(dtos, "导出籽晶质检信息接口", SeedIQCInspectionDto.class, response);
    }

    public SeedIQCInspectionDto toLazyDto(SeedIQCInspection entity) {
        if (ObjectUtils.isEmpty(entity)) {
            return null;
        }
        return modelMapper.map(entity, SeedIQCInspectionDto.class);
    }

    public SeedIQCInspectionDto toEagerDto(SeedIQCInspection entity) {
        if (ObjectUtils.isEmpty(entity)) {
            return null;
        }
        SeedIQCInspectionDto dto = modelMapper.map(entity, SeedIQCInspectionDto.class);
        return dto;
    }

    public SeedDataDto toLazySeedDto(SeedData entity) {
        if (ObjectUtils.isEmpty(entity)) {
            return null;
        }
        return modelMapper.map(entity, SeedDataDto.class);
    }

    public SeedSelfInspectionDto toLazySelfDto(SeedSelfInspection entity) {
        return modelMapper.map(entity, SeedSelfInspectionDto.class);
    }

    public SeedIQCInspection fromDto(SeedIQCInspectionDto dto) {
        return modelMapper.map(dto, SeedIQCInspection.class);
    }
}
