package com.sw.mes.yb.seed.service.impl;

import com.sw.mes.base.factory.material.entity.Unit;
import com.sw.mes.base.factory.material.service.UnitService;
import com.sw.mes.base.factory.product.entity.ProductModel;
import com.sw.mes.base.factory.product.service.ProductModelService;
import com.sw.mes.core.api.system.StoreFeignClients;
import com.sw.mes.core.api.system.YbFeignClients;
import com.sw.mes.core.base.BaseServiceImpl;
import com.sw.mes.core.context.BaseContextHandler;
import com.sw.mes.core.dto.store.WarehouseInputBillBo;
import com.sw.mes.core.dto.store.WarehouseInputBillDetailBo;
import com.sw.mes.core.dto.store.WarehouseOutputBillBo;
import com.sw.mes.core.dto.store.WarehouseOutputBillDetailBo;
import com.sw.mes.core.enums.SeedStoreStatusEnum;
import com.sw.mes.core.exception.BusinessException;
import com.sw.mes.core.response.Result;
import com.sw.mes.core.response.ResultGenerator;
import com.sw.mes.yb.seed.dao.SeedGroupBracketDao;
import com.sw.mes.yb.seed.dto.SeedGroupBracketDetailsDto;
import com.sw.mes.yb.seed.dto.SeedGroupBracketDto;
import com.sw.mes.yb.seed.entity.SeedData;
import com.sw.mes.yb.seed.entity.SeedGroupBracket;
import com.sw.mes.yb.seed.entity.SeedGroupBracketDetails;
import com.sw.mes.yb.seed.enums.InputBillStatusEnum;
import com.sw.mes.yb.seed.service.SeedGroupBracketDetailsService;
import com.sw.mes.yb.seed.service.SeedGroupBracketService;
import com.sw.mes.yb.seed.service.SeedService;
import com.sw.mes.yb.seed.utils.CodeSender;
import com.sw.mes.yb.seed.utils.SeedBatchNoGenerator;
import org.modelmapper.ModelMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class SeedGroupBracketServiceImpl extends BaseServiceImpl<SeedGroupBracket> implements SeedGroupBracketService {
    private SeedGroupBracketDao dao;
    @Autowired
    ModelMapper modelMapper;
    @Autowired
    private SeedGroupBracketDetailsService seedGroupBracketDetailsService;
    @Autowired
    private SeedGroupBracketService seedGroupBracketService;
    @Autowired
    private SeedService seedService;
    @Autowired
    private ProductModelService productModelService;
    @Autowired
    private UnitService unitService;
    @Autowired
    private StoreFeignClients storeFeignClients;
    @Autowired
    private SeedBatchNoGenerator seedBatchNoGenerator;

    @Autowired
    public void setDao(SeedGroupBracketDao dao) {
        this.dao = dao;
        super.setBaseDao(dao);
    }

    @Override
    public SeedGroupBracket findCode(String code) {
        return dao.findCode(code);
    }

    @Override
    public SeedGroupBracketDto findGroupBracketByCode(String code) {
        SeedGroupBracket seedGroupBracket = dao.findCode(code);
        SeedGroupBracketDto seedGroupBracketDto = toEagerDto(seedGroupBracket);
        List<SeedGroupBracketDetailsDto> seedGroupBracketDetailsDtos = new ArrayList<>();
        List<SeedGroupBracketDetails> seedGroupBracketDetails = seedGroupBracketDetailsService.findParentId(seedGroupBracket.getId());
        seedGroupBracketDetails.forEach(entity -> {
            SeedGroupBracketDetailsDto seedGroupBracketDetailsDto = new SeedGroupBracketDetailsDto();
            BeanUtils.copyProperties(entity, seedGroupBracketDetailsDto);
            seedGroupBracketDetailsDtos.add(seedGroupBracketDetailsDto);
        });
        seedGroupBracketDto.setDetailsDtos(seedGroupBracketDetailsDtos);
        return seedGroupBracketDto;
    }

    @Override
    public SeedGroupBracket findBillCode(String billCode) {
        return dao.findBillCode(billCode);
    }

    @Override
    public SeedGroupBracketDto findByIds(Long id) {
        SeedGroupBracket seedGroupBracket = dao.getOne(id);
        if (null == seedGroupBracket) {
            throw new BusinessException("为获取到组托数据!");
        }
        List<SeedGroupBracketDetails> seedGroupBracketDetails = seedGroupBracketDetailsService.findParentId(seedGroupBracket.getId());
        if (null == seedGroupBracketDetails || seedGroupBracketDetails.size() < 1) {
            throw new BusinessException("为获取到组托明细数据!");
        }
        SeedGroupBracketDto seedGroupBracketDto = new SeedGroupBracketDto();
        List<SeedGroupBracketDetailsDto> detailsDtos = new ArrayList<>();
        BeanUtils.copyProperties(seedGroupBracket, seedGroupBracketDto);
        seedGroupBracketDetails.forEach(entity -> {
            SeedGroupBracketDetailsDto seedGroupBracketDetailsDto = new SeedGroupBracketDetailsDto();
            BeanUtils.copyProperties(entity, seedGroupBracketDetailsDto);
            detailsDtos.add(seedGroupBracketDetailsDto);
        });
        seedGroupBracketDto.setDetailsDtos(detailsDtos);
        return seedGroupBracketDto;
    }

    @Override
    public Result createWarehouseInputBill(SeedGroupBracketDto seedGroupBracketDto) {
        WarehouseInputBillBo warehouseInputBillBo = new WarehouseInputBillBo();
        warehouseInputBillBo.setCreateUserName(BaseContextHandler.getUsername());
        warehouseInputBillBo.setCreateUserId(BaseContextHandler.getUserID());
        warehouseInputBillBo.setType(InputBillStatusEnum.籽晶入库.getValue());
        warehouseInputBillBo.setAutomaticOut(false);
        warehouseInputBillBo.setAutoAudit(true);
        warehouseInputBillBo.setWorkOrderNo(seedGroupBracketDto.getDetailsDtos().get(0).getPlanCode());
        if (seedGroupBracketDto.getWorkShopCode().equals("SXLJ2015")) {
            warehouseInputBillBo.setWarehouseCode("P32F");
        } else {
            warehouseInputBillBo.setWarehouseCode("P31F");
        }
        ProductModel productModel = productModelService.findByCode(seedGroupBracketDto.getMaterialCode());
        if (ObjectUtils.isEmpty(productModel)) {
            return ResultGenerator.fail("该主数据不存在!");
        }
        Unit unit = unitService.get(productModel.getUnit().getId());
        List<WarehouseInputBillDetailBo> inputBillDetails = new ArrayList<>();
        WarehouseInputBillDetailBo warehouseInputBillDetailBo = new WarehouseInputBillDetailBo();
        int count = seedGroupBracketDto.getDetailsDtos().size();
        warehouseInputBillDetailBo.setCount(new BigDecimal(count));
        warehouseInputBillDetailBo.setMaterialModelId(Long.valueOf(String.valueOf(seedGroupBracketDto.getMaterialId())));
        warehouseInputBillDetailBo.setMaterialModelCode(seedGroupBracketDto.getMaterialCode());
        warehouseInputBillDetailBo.setMaterialModelName(seedGroupBracketDto.getMaterialName());
        warehouseInputBillDetailBo.setMaterialTypeName(seedGroupBracketDto.getMaterialType());
        warehouseInputBillDetailBo.setBatchNo(seedGroupBracketDto.getSeedDayBatchNo());
        warehouseInputBillDetailBo.setWorkOrderNo(seedGroupBracketDto.getDetailsDtos().get(0).getPlanCode());
        if (!ObjectUtils.isEmpty(unit)) {
            warehouseInputBillDetailBo.setUnitName(unit.getName());
        }
        warehouseInputBillDetailBo.setCreateUserId(warehouseInputBillBo.getCreateUserId());
        warehouseInputBillDetailBo.setCreateUserName(warehouseInputBillBo.getCreateUserName());
        warehouseInputBillDetailBo.setSupplier(productModel.getSupplier());
        warehouseInputBillDetailBo.setSpecification(productModel.getSpecification());
        warehouseInputBillDetailBo.setMaterialTh(productModel.getNumberOfDrawings());
        warehouseInputBillDetailBo.setSerialNo(seedGroupBracketDto.getCode());
        if (!StringUtils.isEmpty(productModel.getUnit().getName())) {
            warehouseInputBillDetailBo.setUnitName(productModel.getUnit().getName());
        }
        warehouseInputBillDetailBo.setMaterialTypeName("籽晶");
        if (seedGroupBracketDto.getWorkShopCode().equals("SXLJ2015")) {
            warehouseInputBillDetailBo.setWarehouseCode("P32F");
            warehouseInputBillDetailBo.setWarehouseName("籽晶现场2仓");
        } else {
            warehouseInputBillDetailBo.setWarehouseCode("P31F");
            warehouseInputBillDetailBo.setWarehouseName("籽晶现场1仓");
        }
        inputBillDetails.add(warehouseInputBillDetailBo);
        warehouseInputBillBo.setInputBillDetails(inputBillDetails);
        Result result = storeFeignClients.inputApply(warehouseInputBillBo);
        if (!result.getCode().equals(200)) {
            return ResultGenerator.fail("籽晶线边仓入库失败!");
        }
        SeedGroupBracket seedGroupBracket = new SeedGroupBracket();
        BeanUtils.copyProperties(seedGroupBracketDto, seedGroupBracket);
        seedGroupBracket.setStatus("待入库");
        seedGroupBracketService.saveOrUpdate(seedGroupBracket);
        seedGroupBracketDto.getDetailsDtos().forEach(details -> {
            SeedGroupBracketDetails seedGroupBracketDetails = new SeedGroupBracketDetails();
            BeanUtils.copyProperties(details, seedGroupBracketDetails);
            seedGroupBracketDetails.setStatus(seedGroupBracket.getStatus());
            seedGroupBracketDetailsService.saveOrUpdate(seedGroupBracketDetails);
        });
        return ResultGenerator.success(result.getData());
    }

    @Override
    public Result create(SeedGroupBracketDto seedGroupBracketDto) {
        SeedGroupBracket seedGroupBracketCode = this.findCode(seedGroupBracketDto.getCode());
        if (!ObjectUtils.isEmpty(seedGroupBracketCode)) {
            return ResultGenerator.fail("该数据已存在!");
        }
        SeedData seedData = seedService.findByBatch(seedGroupBracketDto.getBatchNo());
        SeedGroupBracket seedGroupBracket = fromDto(seedGroupBracketDto);
        seedGroupBracket.setCode(CodeSender.getNumber(4));
        seedGroupBracket.setCount(seedGroupBracketDto.getDetailsDtos().size());
        seedGroupBracket.setCreateBy(BaseContextHandler.getUsername());
        seedGroupBracket.setCreateDate(new Date());
        seedGroupBracket.setSeedDayBatchNo(seedBatchNoGenerator.generator(seedData));
        if (!ObjectUtils.isEmpty(seedData)) {
            seedGroupBracket.setDopant(seedData.getDopant());
            seedGroupBracket.setMaterialCode(seedData.getMaterialCode());
            seedGroupBracket.setMaterialId(seedData.getMaterialId());
            seedGroupBracket.setMaterialModel(seedData.getMaterialModel());
            seedGroupBracket.setMaterialType(seedData.getMaterialType());
            seedGroupBracket.setMaterialName(seedData.getMaterialName());
        }
        seedGroupBracket.setStatus(SeedStoreStatusEnum.待出库.getName());
        this.saveOrUpdate(seedGroupBracket);
        seedGroupBracketDto.getDetailsDtos().stream().forEach(dto -> {
            SeedGroupBracketDetails seedGroupBracketDetails = new SeedGroupBracketDetails();
            BeanUtils.copyProperties(dto, seedGroupBracketDetails, "id");
            seedGroupBracketDetails.setParentId(seedGroupBracket.getId());
            seedGroupBracketDetails.setStatus(SeedStoreStatusEnum.待出库.getName());
            seedGroupBracketDetailsService.saveOrUpdate(seedGroupBracketDetails);
            SeedData seed = seedService.findByCode(dto.getSeedCode());
            seed.setGroupBracket(1);
            seedService.saveOrUpdate(seed);
        });
        return ResultGenerator.success();
    }

    @Override
    public Result update(SeedGroupBracketDto seedGroupBracketDto) {
        SeedGroupBracket seedGroupBracketCode = this.findCode(seedGroupBracketDto.getCode());
        if (ObjectUtils.isEmpty(seedGroupBracketCode)) {
            return ResultGenerator.fail("该数据不存在!");
        }
        if (!seedGroupBracketCode.getStatus().equals(SeedStoreStatusEnum.待出库.getName())) {
            return ResultGenerator.fail("该数据状态不可编辑!");
        }
        SeedGroupBracket seedGroupBracket = fromDto(seedGroupBracketDto);
        seedGroupBracket.setCount(seedGroupBracketDto.getDetailsDtos().size());
        seedGroupBracket.setCreateBy(BaseContextHandler.getUsername());
        seedGroupBracket.setCreateDate(new Date());
        seedGroupBracket.setId(seedGroupBracketDto.getId());
        seedGroupBracket.setStatus(SeedStoreStatusEnum.待出库.getName());
        this.saveOrUpdate(seedGroupBracket);
        //先删除之前数据
        List<SeedGroupBracketDetails> details = seedGroupBracketDetailsService.findParentId(seedGroupBracketDto.getId());
        details.stream().forEach(entity -> {
            seedGroupBracketDetailsService.delete(entity.getId());
        });
        seedGroupBracketDto.getDetailsDtos().stream().forEach(dto -> {
            SeedGroupBracketDetails seedGroupBracketDetails = new SeedGroupBracketDetails();
            BeanUtils.copyProperties(dto, seedGroupBracketDetails, "id");
            seedGroupBracketDetails.setParentId(seedGroupBracket.getId());
            seedGroupBracketDetails.setStatus("待出库");
            seedGroupBracketDetailsService.saveOrUpdate(seedGroupBracketDetails);
        });
        return ResultGenerator.success();
    }

    WarehouseOutputBillBo newOutputBill(SeedGroupBracketDto seedGroupBracketDto) {
        WarehouseOutputBillBo warehouseOutputBillBo = new WarehouseOutputBillBo();
        warehouseOutputBillBo.setCreateUserName(BaseContextHandler.getUsername());
        warehouseOutputBillBo.setCreateUserId(BaseContextHandler.getUserID());
        warehouseOutputBillBo.setType("籽晶出库");
        warehouseOutputBillBo.setAutoAudit(false);
        List<WarehouseOutputBillDetailBo> warehouseOutputBillDetailBos = new ArrayList<>();
        WarehouseOutputBillDetailBo warehouseOutputBillDetailBo = new WarehouseOutputBillDetailBo();
        int count = seedGroupBracketDto.getDetailsDtos().size();
        if (seedGroupBracketDto.getWorkShopCode().equals("SXLJ2015")) {
            warehouseOutputBillDetailBo.setWarehouseCode("P32F");
            warehouseOutputBillDetailBo.setWarehouseName("籽晶现场2仓");
        } else {
            warehouseOutputBillDetailBo.setWarehouseCode("P31F");
            warehouseOutputBillDetailBo.setWarehouseName("籽晶现场1仓");
        }
        warehouseOutputBillDetailBo.setMaterialModelCode(seedGroupBracketDto.getMaterialCode());
        warehouseOutputBillDetailBo.setMaterialModelId(Long.valueOf(String.valueOf(seedGroupBracketDto.getMaterialId())));
        warehouseOutputBillDetailBo.setMaterialModelName(seedGroupBracketDto.getMaterialName());
        warehouseOutputBillDetailBo.setBatchNo(seedGroupBracketDto.getSeedDayBatchNo());
        warehouseOutputBillDetailBo.setOutputCount(new BigDecimal(count));
        warehouseOutputBillDetailBo.setRequireCount(new BigDecimal(count));
        warehouseOutputBillDetailBo.setCreateUserId(warehouseOutputBillBo.getCreateUserId());
        warehouseOutputBillDetailBo.setCreateUserName(warehouseOutputBillBo.getCreateUserName());
        warehouseOutputBillDetailBos.add(warehouseOutputBillDetailBo);
        warehouseOutputBillBo.setOutputBillDetails(warehouseOutputBillDetailBos);
        return warehouseOutputBillBo;
    }

    public SeedGroupBracket fromDto(SeedGroupBracketDto dto) {
        SeedGroupBracket seedGroupBracket = new SeedGroupBracket();
        BeanUtils.copyProperties(dto, seedGroupBracket);
        return seedGroupBracket;
    }

    public SeedGroupBracketDto toEagerDto(SeedGroupBracket entity) {
        SeedGroupBracketDto seedGroupBracketDto = new SeedGroupBracketDto();
        BeanUtils.copyProperties(entity, seedGroupBracketDto);
        return seedGroupBracketDto;
    }
}
