package com.njcn.advance.service.govern.voltage.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.advance.enums.AdvanceResponseEnum;
import com.njcn.advance.mapper.govern.voltage.SgProductLineMapper;
import com.njcn.advance.pojo.dto.govern.voltage.ProductLineComputeData;
import com.njcn.advance.pojo.param.govern.voltage.SgProductLineParam;
import com.njcn.advance.pojo.po.govern.voltage.SgMachine;
import com.njcn.advance.pojo.po.govern.voltage.SgProductLine;
import com.njcn.advance.pojo.vo.govern.voltage.SgMachineVO;
import com.njcn.advance.pojo.vo.govern.voltage.SgProductLineVO;
import com.njcn.advance.pojo.vo.govern.voltage.SgSensitiveUnitVO;
import com.njcn.advance.service.govern.voltage.ISgMachineService;
import com.njcn.advance.service.govern.voltage.ISgProductLineService;
import com.njcn.advance.service.govern.voltage.ISgSensitiveUnitService;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.web.factory.PageFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

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

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hongawen
 * @since 2024-03-14
 */
@Service
@RequiredArgsConstructor
public class SgProductLineServiceImpl extends ServiceImpl<SgProductLineMapper, SgProductLine> implements ISgProductLineService {

    private final ISgMachineService machineService;

    private final ISgSensitiveUnitService sgSensitiveUnitService;


    /**
     * 因为理论上不会超过5条生产线，所以该分页其实也没有多大的必要
     * 根据业务用户id查询该用户下的所有生产线信息
     *
     * @param sgProductLineQueryParam 查询条件
     */
    @Override
    public Page<SgProductLineVO> sgProductLineListByUserId(SgProductLineParam.SgProductLineQueryParam sgProductLineQueryParam) {
        String userId = sgProductLineQueryParam.getUserId();
        QueryWrapper<SgProductLineVO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("sg_product_line.user_id", userId)
                .eq("sg_product_line.state", DataStateEnum.ENABLE.getCode())
                .orderByDesc("sg_product_line.create_time");
        Page<SgProductLineVO> data = this.baseMapper.page(new Page<>(PageFactory.getPageNum(sgProductLineQueryParam), PageFactory.getPageSize(sgProductLineQueryParam)), queryWrapper);
        List<SgProductLineVO> records = data.getRecords();
        //循环遍历处理下生产线总功率、设备损失、原料损失
        if (CollectionUtil.isNotEmpty(records)) {
            //根据生产线获取下面所有设备
            List<String> productLineIdList = records.stream().map(SgProductLineVO::getId).collect(Collectors.toList());
            LambdaQueryWrapper<SgMachine> sgMachineLambdaQueryWrapper = new LambdaQueryWrapper<>();
            sgMachineLambdaQueryWrapper.in(SgMachine::getProductLineId, productLineIdList)
                    .eq(SgMachine::getState, DataStateEnum.ENABLE.getCode());
            List<SgMachine> machineList = machineService.list(sgMachineLambdaQueryWrapper);
            //判断是否有设备数据，有的话，进行java分组，以生产线id为key
            Map<String, List<SgMachine>> stringListMap = machineList.stream().collect(Collectors.groupingBy(SgMachine::getProductLineId));
            for (SgProductLineVO sgProductLineVO : records) {
                String productLineId = sgProductLineVO.getId();
                List<SgMachine> machineListTemp = stringListMap.get(productLineId);
                if (CollectionUtil.isNotEmpty(machineListTemp)) {
                    //设备总损失
                    double machineLossSum = machineListTemp.stream().mapToDouble(SgMachine::getMachineLoss).sum();
                    sgProductLineVO.setMachineLoss(machineLossSum);
                    //原料总损失
                    double materialLossSum = machineListTemp.stream().mapToDouble(SgMachine::getMaterialLoss).sum();
                    sgProductLineVO.setMaterialLoss(materialLossSum);
                    //总功率
                    double machinePowerSum = machineListTemp.stream().mapToDouble(SgMachine::getMachinePower).sum();
                    sgProductLineVO.setMachinePower(machinePowerSum);
                }
            }
        }
        return data;
    }

    /**
     * 新增生产线
     *
     * @param sgProductLineParam 数据内容
     */
    @Override
    public String addProductLine(SgProductLineParam sgProductLineParam) {
        checkSgProductName(sgProductLineParam, false);
        SgProductLine sgProductLine = new SgProductLine();
        BeanUtil.copyProperties(sgProductLineParam, sgProductLine);
        //默认为正常状态
        sgProductLine.setState(DataStateEnum.ENABLE.getCode());
        this.save(sgProductLine);
        return sgProductLine.getId();
    }

    /**
     * 更新生产线
     *
     * @param updateParam 数据内容
     */
    @Override
    public boolean updateSgProductLine(SgProductLineParam.SgProductLineUpdateParam updateParam) {
        checkSgProductName(updateParam, true);
        SgProductLine sgProductLine = new SgProductLine();
        BeanUtil.copyProperties(updateParam, sgProductLine);
        return this.updateById(sgProductLine);
    }

    /**
     * 根据id逻辑删除生产线数据
     *
     * @param ids id集合
     */
    @Override
    public boolean deleteSgProductData(List<String> ids) {
        LambdaQueryWrapper<SgMachine> sgMachineLambdaQueryWrapper;
        for (String id : ids) {
            sgMachineLambdaQueryWrapper = new LambdaQueryWrapper<>();
            sgMachineLambdaQueryWrapper.eq(SgMachine::getProductLineId, id)
                    .eq(SgMachine::getState, DataStateEnum.ENABLE.getCode());
            int count = machineService.count(sgMachineLambdaQueryWrapper);
            if (count > 0) {
                throw new BusinessException(AdvanceResponseEnum.PRODUCT_HAS_MACHINE);
            } else {
                this.lambdaUpdate()
                        .set(SgProductLine::getState, DataStateEnum.DELETED.getCode())
                        .eq(SgProductLine::getId, id)
                        .update();
            }
        }
        return true;
    }

    /**
     * 根据用户id获取生产线信息
     *
     * @param userId 用户id
     */
    @Override
    public List<SgProductLineVO> querySgProductLineByUserId(String userId) {
        QueryWrapper<SgProductLineVO> sgProductLineVOQueryWrapper = new QueryWrapper<>();
        sgProductLineVOQueryWrapper.eq("sg_product_line.user_id", userId)
                .eq("sg_product_line.state", DataStateEnum.ENABLE.getCode())
                .orderByDesc("sg_product_line.create_time");
        return this.baseMapper.querySgProductLineByUserId(sgProductLineVOQueryWrapper);
    }

    /**
     * 根据生产线id获取待计算的损失的所有设备、元器件数据
     *
     * @param productLineId 生产线id
     */
    @Override
    public ProductLineComputeData assginProductLineComputeData(String productLineId) {
        ProductLineComputeData productLineComputeData = new ProductLineComputeData();
        SgProductLine sgProductLine = this.getById(productLineId);
        BeanUtil.copyProperties(sgProductLine, productLineComputeData);
        //获取该生产线下所有设备数据
        List<SgMachineVO> sgMachineVOList = machineService.listAllMachineByProductLineId(productLineId);
        if (CollectionUtil.isNotEmpty(sgMachineVOList)) {
            productLineComputeData.setMachineVOList(sgMachineVOList);
            //获取每个设备下的敏感元器件数据
            for (SgMachineVO sgMachineVO : sgMachineVOList) {
              List<SgSensitiveUnitVO> sgSensitiveUnitVOList =   sgSensitiveUnitService.listAllUnitByMachineId(sgMachineVO.getId());
              if(CollectionUtil.isNotEmpty(sgSensitiveUnitVOList)){
                  sgMachineVO.setSgSensitiveUnitList(sgSensitiveUnitVOList);
              }
            }
        }
        return productLineComputeData;
    }

    @Override
    public String getUserNameByProductId(String id) {
        return this.baseMapper.getUserNameByProductId(id);
    }

    /**
     * 校验参数，检查是否存在相同名称的生产线
     */
    private void checkSgProductName(SgProductLineParam sgProductLineParam, boolean isExcludeSelf) {
        LambdaQueryWrapper<SgProductLine> sgProductLineLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sgProductLineLambdaQueryWrapper
                .eq(SgProductLine::getName, sgProductLineParam.getName())
                .eq(SgProductLine::getUserId, sgProductLineParam.getUserId())
                .eq(SgProductLine::getState, DataStateEnum.ENABLE.getCode());
        //更新的时候，需排除当前记录
        if (isExcludeSelf) {
            if (sgProductLineParam instanceof SgProductLineParam.SgProductLineUpdateParam) {
                sgProductLineLambdaQueryWrapper.ne(SgProductLine::getId, ((SgProductLineParam.SgProductLineUpdateParam) sgProductLineParam).getId());
            }
        }
        int countByAccount = this.count(sgProductLineLambdaQueryWrapper);
        //大于等于1个则表示重复
        if (countByAccount >= 1) {
            throw new BusinessException(AdvanceResponseEnum.SG_PRODUCT_LINE_NAME_REPEAT);
        }
    }
}
