package com.ktg.iscs.service.impl;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ktg.common.core.domain.entity.SysDictData;
import com.ktg.common.core.text.Convert;
import com.ktg.common.utils.DictUtils;
import com.ktg.common.utils.bean.BeanUtils;
import com.ktg.iscs.domain.IsJobTicketPoints;
import com.ktg.iscs.domain.IsSop;
import com.ktg.iscs.domain.IsSopPoints;
import com.ktg.iscs.domain.IsSopUser;
import com.ktg.iscs.domain.dto.sop.AddSopDTO;
import com.ktg.iscs.domain.dto.sop.AddSopUserDTO;
import com.ktg.iscs.domain.dto.sop.PageSopDTO;
import com.ktg.iscs.domain.vo.points.PointDetailVO;
import com.ktg.iscs.domain.vo.sop.SopDetailVO;
import com.ktg.iscs.domain.vo.sop.SopPageVO;
import com.ktg.iscs.mapper.IsSopMapper;
import com.ktg.iscs.service.IIsIsolationPointService;
import com.ktg.iscs.service.IIsSopPointsService;
import com.ktg.iscs.service.IIsSopService;
import com.ktg.iscs.service.IIsSopUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * SOP信息Service业务层处理
 *
 * @author cgj
 * @date 2024-10-18
 */
@Service
public class IsSopServiceImpl extends ServiceImpl<IsSopMapper, IsSop> implements IIsSopService {
    @Autowired
    private IsSopMapper isSopMapper;
    @Autowired
    private IIsSopPointsService iIsSopPointsService;
    @Autowired
    private IIsIsolationPointService iIsIsolationPointService;
    @Autowired
    private IIsSopUserService iIsSopUserService;

    /**
     * 查询SOP信息
     *
     * @param sopId SOP信息主键
     * @return SOP信息
     */
    @Override
    public SopDetailVO selectIsSopBySopId(Long sopId) {
        // 1.查询基础数据
        SopDetailVO sopDetailVO = isSopMapper.selectIsSopBySopId(sopId);
        // SopDetailVO sopDetailVO = BeanUtils.toBean(isSop, SopDetailVO.class);
        // 2.查询sop隔离点关联数据
        List<IsSopPoints> isSopPoints = iIsSopPointsService.list(Wrappers.<IsSopPoints>lambdaQuery()
                .eq(IsSopPoints::getSopId, sopId));
        // 3.查询隔离点数据
        if (!isSopPoints.isEmpty()) {
            List<Long> pointIds = isSopPoints.stream().map(IsSopPoints::getPointId).collect(Collectors.toList());
            // List<IsIsolationPoint> isIsolationPoints = iIsIsolationPointService.listByIds(pointIds);
            List<PointDetailVO> pointDetailVOList = iIsIsolationPointService.getPointDetailList(pointIds);
            // 需要顺序，所以重新准备一个集合，上面方法变更了我的数据顺序
            ArrayList<PointDetailVO> pointDetailVOS = new ArrayList<>();
            for (IsSopPoints isSopPoint : isSopPoints) {
                for (PointDetailVO pointDetailVO : pointDetailVOList) {
                   if (pointDetailVO.getPointId().equals(isSopPoint.getPointId())) {
                       pointDetailVO.setPrePointId(isSopPoint.getPrePointId());
                       pointDetailVOS.add(pointDetailVO);
                   }
                }
            }
            // 3.1组合返回数据
            sopDetailVO.setPointDetailVOList(pointDetailVOS);
        }
        // 4.查询人员信息
        List<IsSopUser> sopUserList = iIsSopUserService.list(Wrappers.<IsSopUser>lambdaQuery()
                .eq(IsSopUser::getSopId, sopId));
        if (!sopUserList.isEmpty()) {
            sopDetailVO.setTicketUserDTOList(BeanUtils.toBean(sopUserList, AddSopUserDTO.class));
        }
        return sopDetailVO;
    }

    /**
     * 查询SOP信息列表
     *
     * @param isSop SOP信息
     * @return SOP信息
     */
    @Override
    public List<IsSop> selectIsSopList(IsSop isSop) {
        return isSopMapper.selectIsSopList(isSop);
    }

    /**
     * 新增SOP信息
     *
     * @param dto SOP信息
     * @return 结果
     */
    @Transactional
    @Override
    public Boolean insertIsSop(AddSopDTO dto) {
        // 断言校验
        Assert.isTrue(StringUtils.isNotBlank(dto.getSopName()), "SOP名称不可为空!");
        Assert.isTrue(StringUtils.isNotBlank(dto.getSopCode()), "SOP编号名称不可为空!");
        List<IsSop> list = list(Wrappers.<IsSop>lambdaQuery().eq(IsSop::getSopCode, dto.getSopCode()));
        Assert.isTrue(list.isEmpty(), "该SOP编号已被使用!");
        // 1.判断隔离点必选
        Assert.isFalse(dto.getPointsList().isEmpty(), "隔离点id不可为空!");
        // 2.开始新增sop数据
        IsSop isSop = BeanUtils.toBean(dto, IsSop.class);
        save(isSop);
        // 3.新增车间、区域、隔离点和sop的关联关系
        // TODO 批量新增
        for (IsJobTicketPoints isJobTicketPoints : dto.getPointsList()) {
            IsSopPoints isSopPoints = new IsSopPoints();
            isSopPoints.setSopId(isSop.getSopId());
            isSopPoints.setWorkareaId(dto.getWorkareaId());
            isSopPoints.setPointId(isJobTicketPoints.getPointId());
            isSopPoints.setPrePointId(isJobTicketPoints.getPrePointId());
            iIsSopPointsService.save(isSopPoints);
        }
        // 4.新增人员信息到模板
        if (!dto.getTicketUserDTOList().isEmpty()) {
            for (AddSopUserDTO addSopUserDTO : dto.getTicketUserDTOList()) {
                IsSopUser sopUser = BeanUtils.toBean(addSopUserDTO, IsSopUser.class);
                sopUser.setSopId(isSop.getSopId());
                if (null == addSopUserDTO.getUserId() || addSopUserDTO.getUserId() == 0) {
                    addSopUserDTO.setUserId(0L);
                }
                iIsSopUserService.save(sopUser);
            }
        }
        return true;
    }

    /**
     * 修改SOP信息
     *
     * @param dto SOP信息
     * @return 结果
     */
    @Transactional
    @Override
    public Boolean updateIsSop(AddSopDTO dto) {
        // 断言校验
        Assert.notNull(dto.getSopId(), "sopId不可为空!");
        Assert.isTrue(StringUtils.isNotBlank(dto.getSopName()), "SOP名称不可为空!");
        Assert.isTrue(StringUtils.isNotBlank(dto.getSopCode()), "SOP编号名称不可为空!");
        List<IsSop> list = list(Wrappers.<IsSop>lambdaQuery()
                .eq(IsSop::getSopCode, dto.getSopCode())
                .ne(IsSop::getSopId, dto.getSopId()));
        Assert.isTrue(list.isEmpty(), "该SOP编号已被使用!");
        // 1.判断隔离点必选
        Assert.isFalse(dto.getPointsList().isEmpty(), "隔离点id不可为空!");
        // 1.1检查区域有没有变，区域变了的话隔离点肯定变了，因为隔离点是从区域数据中解析的
        // IsSop sop = getById(dto.getSopId());
        // 2.开始检查隔离点有没有变更
        /*List<Long> poindList = dto.getPointsList().stream().map(IsJobTicketPoints::getPointId).collect(Collectors.toList());
        List<IsSopPoints> isSopPoints = iIsSopPointsService.list(Wrappers.<IsSopPoints>lambdaQuery()
                .eq(IsSopPoints::getSopId, dto.getSopId())
                .in(IsSopPoints::getPointId, poindList));*/
        // 2.1如果查出来变更了，开始执行删除，重新增加一轮 / 区域变更则点位必然改变，也需要删除
        // if (dto.getPointsList().size() != isSopPoints.size() || !sop.getWorkareaId().equals(dto.getWorkareaId())) {
        // 直接删除，点位变更前置节点属性啥的，无法检测，只能删了重新加一波
            iIsSopPointsService.remove(Wrappers.<IsSopPoints>lambdaQuery().eq(IsSopPoints::getSopId, dto.getSopId()));
            // TODO 批量新增
            for (IsJobTicketPoints isJobTicketPoints : dto.getPointsList()) {
                IsSopPoints newSopPoints = new IsSopPoints();
                newSopPoints.setSopId(dto.getSopId());
                newSopPoints.setWorkareaId(dto.getWorkareaId());
                newSopPoints.setPointId(isJobTicketPoints.getPointId());
                newSopPoints.setPrePointId(isJobTicketPoints.getPrePointId());
                iIsSopPointsService.save(newSopPoints);
            }
        // }
        // 3.新增人员信息到模板
        // 3.1先清除原先的人员数据
        iIsSopUserService.remove(Wrappers.<IsSopUser>lambdaQuery().eq(IsSopUser::getSopId, dto.getSopId()));
        if (!dto.getTicketUserDTOList().isEmpty()) {
            for (AddSopUserDTO addSopUserDTO : dto.getTicketUserDTOList()) {
                IsSopUser sopUser = BeanUtils.toBean(addSopUserDTO, IsSopUser.class);
                sopUser.setSopId(dto.getSopId());
                if (null == addSopUserDTO.getUserId() || addSopUserDTO.getUserId() == 0) {
                    addSopUserDTO.setUserId(0L);
                }
                iIsSopUserService.save(sopUser);
            }
        }
        // 4.开始执行更新操作
        IsSop isSop = BeanUtils.toBean(dto, IsSop.class);
        isSopMapper.updateById(isSop);
        return true;
    }

    /**
     * 批量删除SOP信息
     *
     * @param sopIds 需要删除的SOP信息主键
     * @return 结果
     */
    @Transactional
    @Override
    public Boolean deleteIsSopBySopIds(String sopIds) {
        // 1.断言判断
        Assert.notBlank(sopIds, "请选择需要删除的数据!");
        // 2.删除主数据
        Long[] longIds = Convert.toLongArray(sopIds);
        isSopMapper.deleteIsSopBySopIds(longIds);
        // 3.同时删除is_sop_points关联数据
        /*List<IsSopPoints> isSopPointsList = iIsSopPointsService.list(Wrappers.<IsSopPoints>lambdaQuery()
                .in(IsSopPoints::getSopId, longIds));
        Set<Long> recordIds = isSopPointsList.stream().map(IsSopPoints::getRecordId).collect(Collectors.toSet());
        if (!recordIds.isEmpty()) {
            String rids = StringUtils.join(recordIds.toArray(), ",");
            iIsSopPointsService.deleteIsSopPointsByRecordIds(rids);
        }*/
        iIsSopPointsService.remove(Wrappers.<IsSopPoints>lambdaQuery()
                .in(IsSopPoints::getSopId, longIds));
        // 4.同时删除is_sop_user关联数据
        iIsSopUserService.remove(Wrappers.<IsSopUser>lambdaQuery()
                .in(IsSopUser::getSopId, longIds));
        return true;
    }

    /**
     * 删除SOP信息信息
     *
     * @param sopId SOP信息主键
     * @return 结果
     */
    @Override
    public int deleteIsSopBySopId(Long sopId) {
        return isSopMapper.deleteIsSopBySopId(sopId);
    }

    @Override
    public Page<SopPageVO> getIsSopPage(Page<IsSop> page, PageSopDTO dto) {
        return isSopMapper.getIsSopPage(page, dto);
    }

    @Override
    public Boolean updateIsSopIndex(IsSop isSop) {
        Assert.notNull(isSop.getSopId(), "主键id不可为空！");
        Assert.notNull(isSop.getSopIndex(), "排序数据不可为空！");
        update(Wrappers.<IsSop>lambdaUpdate()
                .eq(IsSop::getSopId, isSop.getSopId())
                .set(IsSop::getSopIndex, isSop.getSopIndex()));
        return true;
    }

    @Override
    public List<SysDictData> selectSopTypeByMachineryId(Long machineryId) {
        ArrayList<SysDictData> sysDictDatas = new ArrayList<>();
        List<IsSop> list = list(Wrappers.<IsSop>lambdaQuery().eq(IsSop::getMachineryId, machineryId));
        if (!list.isEmpty()) {
            List<String> collect = list.stream().map(IsSop::getSopType).collect(Collectors.toList());
            if (!collect.isEmpty()) {
                // 使用 HashSet 去重
                Set<String> set = new HashSet<>(collect);
                ArrayList<String> strings = new ArrayList<>(set);
                for (String s : strings) {
                    String sopType = DictUtils.getDictLabel("sop_type", s);
                    SysDictData sysDictData = new SysDictData();
                    sysDictData.setDictLabel(sopType);
                    sysDictData.setDictValue(s);
                    sysDictData.setDictType("sop_type");
                    sysDictDatas.add(sysDictData);
                }
            }
        }
        return sysDictDatas;
    }

}
