package com.fjhx.mes.service.production.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjhx.file.entity.ObsFile;
import com.fjhx.file.utils.ObsFileUtil;
import com.fjhx.item.entity.product.po.ProductInfo;
import com.fjhx.item.service.product.ProductInfoService;
import com.fjhx.mes.entity.applicable.po.ApplicableProducts;
import com.fjhx.mes.entity.production.dto.ProductionProcessesDto;
import com.fjhx.mes.entity.production.dto.ProductionProcessesSelectDto;
import com.fjhx.mes.entity.production.po.ProductionProcesses;
import com.fjhx.mes.entity.production.vo.ProductionProcessesVo;
import com.fjhx.mes.entity.technology.po.Technology;
import com.fjhx.mes.entity.technology.po.TechnologyProcessLine;
import com.fjhx.mes.entity.work.po.WorkOrder;
import com.fjhx.mes.mapper.production.ProductionProcessesMapper;
import com.fjhx.mes.service.applicable.ApplicableProductsService;
import com.fjhx.mes.service.production.ProductionProcessesService;
import com.fjhx.mes.service.technology.TechnologyProcessLineService;
import com.fjhx.mes.service.technology.TechnologyService;
import com.ruoyi.common.core.domain.BasePo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.wrapper.IWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


/**
 * <p>
 * 工序 服务实现类
 * </p>
 *
 * @author
 * @since 2023-03-28
 */
@Service
public class ProductionProcessesServiceImpl extends ServiceImpl<ProductionProcessesMapper, ProductionProcesses> implements ProductionProcessesService {

    @Autowired
    private ApplicableProductsService applicableProductsService;
    @Autowired
    private TechnologyService technologyService;
    @Autowired
    private TechnologyProcessLineService technologyProcessLineService;
    @Autowired
    private ProductInfoService productInfoService;


    @Override
    public Page<ProductionProcessesVo> getPage(ProductionProcessesSelectDto dto) {
        IWrapper<ProductionProcesses> wrapper = getWrapper();
        wrapper.like(ProductionProcesses::getName, dto.getKeyword());

        wrapper.orderByAsc("pp", ProductionProcesses::getCreateTime);
        wrapper.orderByAsc("pp", ProductionProcesses::getId);
        Page<ProductionProcessesVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);
        return page;
    }

    @Override
    public ProductionProcessesVo detail(Long id) {
        ProductionProcesses ProductionProcesses = this.getById(id);
        ProductionProcessesVo result = BeanUtil.toBean(ProductionProcesses, ProductionProcessesVo.class);
        return result;
    }

    @DSTransactional
    @Override
    public void add(ProductionProcessesDto productionProcessesDto) {
//        Assert.notEmpty(productionProcessesDto.getRoleId(),"角色id不能为空");
        List<ObsFile> fileList = productionProcessesDto.getFileList();
        if (ObjectUtil.isNotEmpty(fileList)) {
            ObsFile obsFile = productionProcessesDto.getFileList().get(0);
            productionProcessesDto.setFileName(obsFile.getFileName());
        }
        this.save(productionProcessesDto);
        ObsFileUtil.saveFile(productionProcessesDto.getFileList(), productionProcessesDto.getId());
    }

    @DSTransactional
    @Override
    public void edit(ProductionProcessesDto productionProcessesDto) {
        ProductionProcesses productionProcesses = this.getById(productionProcessesDto.getId());
        //修改对应产品价格
        List<Long> technologyIds = technologyProcessLineService.listObject(TechnologyProcessLine::getTechnologyId, q -> q
                .eq(TechnologyProcessLine::getTargetProcessesId, productionProcessesDto.getId())
        );
        if (ObjectUtil.isNotEmpty(technologyIds)) {
            List<Long> pIds = productInfoService.listObject(ProductInfo::getId, q -> q.in(ProductInfo::getTechnologyId, technologyIds));
            if (ObjectUtil.isNotEmpty(pIds)) {
                BigDecimal costPrice = productionProcesses.getCostPrice();
                BigDecimal newCostPrice = productionProcessesDto.getCostPrice();
                costPrice = costPrice == null ? BigDecimal.ZERO : costPrice;
                newCostPrice = newCostPrice == null ? BigDecimal.ZERO : newCostPrice;

                BigDecimal subtract = newCostPrice.subtract(costPrice);

                productInfoService.update(q -> q
                        .in(ProductInfo::getId, pIds)
                        .setSql("price = price + " + subtract)
                        .set(BasePo::getUpdateTime, new Date())
                        .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
                );
            }
        }


        List<ObsFile> fileList = productionProcessesDto.getFileList();
        if (fileList.size() > 0) {
            ObsFile obsFile = fileList.get(0);
            productionProcessesDto.setFileName(obsFile.getFileName());
        } else {
            productionProcessesDto.setFileName(null);
        }
        this.updateById(productionProcessesDto);
        baseMapper.updateFileName(productionProcessesDto.getId(), productionProcessesDto.getFileName());
        ObsFileUtil.editFile(productionProcessesDto.getFileList(), productionProcessesDto.getId());
    }

    @DSTransactional
    @Override
    public void delete(Long id) {
        //检查工序关联工艺
        List<Long> technologyIds = technologyProcessLineService.listObject(TechnologyProcessLine::getTechnologyId, q -> q
                .eq(TechnologyProcessLine::getTargetProcessesId, id)
        );
        if (ObjectUtil.isNotEmpty(technologyIds)) {
            List<String> strings = technologyService.listObject(Technology::getName, q -> q.in(Technology::getId, technologyIds));
            String collect = strings.stream().collect(Collectors.joining("，"));
            throw new ServiceException("该工序关联以下产线：" + collect + "禁止删除！");
        }

        this.removeById(id);
        ObsFileUtil.removeFile(id);
    }

    /**
     * 根据工单详细获取基本工序
     */
    @Override
    public List<ProductionProcesses> getBaseProductionProcessesList(WorkOrder workOrder) {
        ApplicableProducts applicableProducts = applicableProductsService.getOne(q -> q.eq(ApplicableProducts::getProductId, workOrder.getProductId()));
        if (ObjectUtil.isEmpty(applicableProducts)) {
            throw new ServiceException("未找到适用于该产品的工艺信息");
        }
        Technology technology = technologyService.getById(applicableProducts.getTechnologyId());
        if (ObjectUtil.isEmpty(technology)) {
            throw new ServiceException("工艺信息不存在");
        }
        String processRoute = technology.getProcessRoute();
        if (ObjectUtil.isEmpty(processRoute)) {
            throw new ServiceException("工艺线路为空");
        }
        String[] split = processRoute.split(",");
        //查询工序并自定义排序
        IWrapper<ProductionProcesses> wrapper = IWrapper.getWrapper();
        wrapper.in(ProductionProcesses::getId, split);
        wrapper.orderByAsc("FIELD( id, " + processRoute + ")");
        return this.list(wrapper);
    }

}
