package com.ktg.iscs.service.impl;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ktg.common.utils.SecurityUtils;
import com.ktg.common.utils.bean.BeanUtils;
import com.ktg.iscs.domain.*;
import com.ktg.iscs.domain.dto.step.IsJobTicketStepDTO;
import com.ktg.iscs.domain.vo.hardwareApi.JobTicketVO;
import com.ktg.iscs.domain.vo.step.IsJobTicketStepVO;
import com.ktg.iscs.mapper.IsJobTicketStepMapper;
import com.ktg.iscs.service.*;
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.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 作业票执行步骤Service业务层处理
 *
 * @author cgj
 * @date 2024-12-23
 */
@Service
public class IsJobTicketStepServiceImpl extends ServiceImpl<IsJobTicketStepMapper, IsJobTicketStep> implements IIsJobTicketStepService {

    @Autowired
    private IsJobTicketStepMapper isJobTicketStepMapper;
    @Autowired
    private IIsJobTicketPointsService iIsJobTicketPointsService;
    @Autowired
    private IIsJobTicketUserService iIsJobTicketUserService;
    @Autowired
    private IIsJobTicketService iIsJobTicketService;
    @Autowired
    private IIsSystemAttributeService isSystemAttributeService;
    @Autowired
    private IIsTicketOperLogService isTicketOperLogService;
    @Autowired
    private IIsJobTicketService isJobTicketService;


    @Transactional
    @Override
    public Boolean updateJobStep(IsJobTicketStepDTO dto) {
        Assert.notNull(dto.getStepId(), "步骤Id不可为空!");
        Assert.notNull(dto.getStepStatus(), "状态不可为空!");
        // 1.检查上一步骤有没有检查完成
        IsJobTicketStep jobTicketStep = getById(dto.getStepId());
        if (jobTicketStep.getStepIndex() - 1 > 0) {
            IsJobTicketStep one = getOne(Wrappers.<IsJobTicketStep>lambdaQuery()
                    .eq(IsJobTicketStep::getTicketId, jobTicketStep.getTicketId())
                    .eq(IsJobTicketStep::getStepIndex, jobTicketStep.getStepIndex() - 1));
            Assert.isFalse("0".equals(one.getStepStatus()), "请先执行上一步！");
        }
        IsJobTicket jobTicket = isJobTicketService.getById(jobTicketStep.getTicketId());
        // 3.如果这个状态是第三步，需要设定上锁人，则开始作业票
        if (jobTicketStep.getStepIndex().equals(3)) {
            List<IsJobTicketUser> list = iIsJobTicketUserService.list(Wrappers.<IsJobTicketUser>lambdaQuery()
                    .eq(IsJobTicketUser::getTicketId, jobTicketStep.getTicketId())
                    .eq(IsJobTicketUser::getUserRole, isSystemAttributeService.getIsSystemAttributeByKey("role.jtlocker").getSysAttrValue()));
            Assert.isFalse(list.isEmpty(), "请先设定上锁人！");
            iIsJobTicketService.update(Wrappers.<IsJobTicket>lambdaUpdate()
                    .eq(IsJobTicket::getTicketId, jobTicketStep.getTicketId())
                    .set(IsJobTicket::getTicketStartTime, new Date())
                    .set(IsJobTicket::getTicketStatus, "1"));
        }
        // 6.如果这个状态是第六步，需要设定至少一个共锁人
        if (jobTicketStep.getStepIndex().equals(6)) {
            List<IsJobTicketUser> list = iIsJobTicketUserService.list(Wrappers.<IsJobTicketUser>lambdaQuery()
                    .eq(IsJobTicketUser::getTicketId, jobTicketStep.getTicketId())
                    .eq(IsJobTicketUser::getUserRole, isSystemAttributeService.getIsSystemAttributeByKey("role.jtcolocker").getSysAttrValue()));
            Assert.isFalse(list.isEmpty(), "请至少设定一个共锁人！");
        }
        // 更新步骤状态
        update(Wrappers.<IsJobTicketStep>lambdaUpdate().eq(IsJobTicketStep::getStepId, dto.getStepId())
                .set(IsJobTicketStep::getStepStatus, dto.getStepStatus()));
        // 操作确认
        isTicketOperLogService.addLog2(jobTicket.getTicketId(), jobTicket.getTicketName(), jobTicketStep.getAndroidStepContent(), SecurityUtils.getUserId(), SecurityUtils.getLoginUser().getUser().getNickName());
        return true;
    }

    @Override
    public List<IsJobTicketStepVO> selectStepsByTicketId(Long ticketId) {
        Assert.notNull(ticketId, "作业票id不能为空!");
        List<IsJobTicketStep> stepList = list(Wrappers.<IsJobTicketStep>lambdaQuery().eq(IsJobTicketStep::getTicketId, ticketId));
        Assert.isFalse(stepList.isEmpty(), "该作业票步骤已丢失，请检查数据！");
        List<IsJobTicketStepVO> stepVOList = BeanUtils.toBean(stepList, IsJobTicketStepVO.class);
        // 1.获取需要分析的数据
        List<IsJobTicketPoints> pointList = iIsJobTicketPointsService.list(Wrappers.<IsJobTicketPoints>lambdaQuery()
                .eq(IsJobTicketPoints::getTicketId, ticketId));
        List<IsJobTicketUser> userList = iIsJobTicketUserService.list(Wrappers.<IsJobTicketUser>lambdaQuery()
                .eq(IsJobTicketUser::getTicketId, ticketId)
                .ne(IsJobTicketUser::getUserRole, isSystemAttributeService.getIsSystemAttributeByKey("role.jtlocker").getSysAttrValue()));
        // 1.1读取第三步的计数
        int oneLockNum = pointList.size();
        int oneUserNum = userList.size();
        stepVOList.get(2).setLockNum(oneLockNum).setUserNum(oneUserNum);
        // 1.2读取第五步的计数
        int twoLockNum = (int) pointList.stream()
                .filter(o -> o.getPointStatus() != null && Integer.parseInt(o.getPointStatus()) >= 1).count();
        int twoUserNum = (int) userList.stream()
                .filter(o -> o.getJobStatus() != null && Integer.parseInt(o.getJobStatus()) >= 4).count();
        stepVOList.get(4).setLockNum(twoLockNum).setUserNum(twoUserNum);
        // 1.3读取第八步的计数
        int threeLockNum = (int) pointList.stream()
                .filter(o -> o.getPointStatus() != null && Integer.parseInt(o.getPointStatus()) == 2).count();
        int threeUserNum = (int) userList.stream()
                .filter(o -> o.getJobStatus() != null && Integer.parseInt(o.getJobStatus()) == 5).count();
        stepVOList.get(7).setLockNum(threeLockNum).setUserNum(threeUserNum).setConflictJobNum(0);
        // 2读取第八步的作业票干扰，判断该作业票点位被哪些额外作业票锁定了
        // 2.1获取被其他作业票锁定的隔离点
        if (!pointList.isEmpty()) {
            List<Long> pointIds = pointList.stream().map(IsJobTicketPoints::getPointId).collect(Collectors.toList());
            List<IsJobTicketPoints> conflictPoints = iIsJobTicketPointsService.list(Wrappers.<IsJobTicketPoints>lambdaQuery()
                    .in(IsJobTicketPoints::getPointId, pointIds)
                    .ne(IsJobTicketPoints::getTicketId, ticketId)
                    .eq(IsJobTicketPoints::getPointStatus, 1));
            if (!conflictPoints.isEmpty()) {
                // int conflictJobNum = (int) conflictPoints.stream().map(IsJobTicketPoints::getTicketId).distinct().count();
                // stepVOList.get(7).setConflictJobNum(conflictJobNum);
                List<Long> ticketIds = conflictPoints.stream().map(IsJobTicketPoints::getTicketId).distinct().collect(Collectors.toList());
                List<IsJobTicket> list = iIsJobTicketService.list(Wrappers.<IsJobTicket>lambdaQuery()
                        .in(IsJobTicket::getTicketId, ticketIds)
                        .lt(IsJobTicket::getTicketStatus, 5));
                stepVOList.get(7).setConflictJobNum(list.isEmpty() ? 0 : list.size());
            }
        }
        return stepVOList;
    }

    @Override
    public List<JobTicketVO> getStepEight(Long ticketId) {
        Assert.notNull(ticketId, "作业票id不可为空！");
        List<IsJobTicketPoints> pointList = iIsJobTicketPointsService.list(Wrappers.<IsJobTicketPoints>lambdaQuery()
                .eq(IsJobTicketPoints::getTicketId, ticketId));
        List<JobTicketVO> jobTicketVOS = new ArrayList<>();
        // 2.1获取被其他作业票锁定的隔离点
        if (!pointList.isEmpty()) {
            List<Long> pointIds = pointList.stream().map(IsJobTicketPoints::getPointId).collect(Collectors.toList());
            List<IsJobTicketPoints> conflictPoints = iIsJobTicketPointsService.list(Wrappers.<IsJobTicketPoints>lambdaQuery()
                    .in(IsJobTicketPoints::getPointId, pointIds)
                    .ne(IsJobTicketPoints::getTicketId, ticketId)
                    .eq(IsJobTicketPoints::getPointStatus, 1));
            if (!conflictPoints.isEmpty()) {
                List<Long> collect = conflictPoints.stream().map(IsJobTicketPoints::getTicketId).distinct().collect(Collectors.toList());
                if (!collect.isEmpty()) {
                    jobTicketVOS = BeanUtils.toBean(iIsJobTicketService.listByIds(collect), JobTicketVO.class);
                }
            }
        }
        return jobTicketVOS;
    }
}
