package org.jeecg.modules.workOrder.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.jeecg.modules.workOrder.entity.WorkDivision;
import org.jeecg.modules.workOrder.entity.WorkDivisionSet;
import org.jeecg.modules.workOrder.entity.WorkOrder;
import org.jeecg.modules.workOrder.mapper.WorkDivisionMapper;
import org.jeecg.modules.workOrder.mapper.WorkDivisionSetMapper;
import org.jeecg.modules.workOrder.mapper.WorkOrderMapper;
import org.jeecg.modules.workOrder.service.IWorkDivisionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Description: 实际派工表
 * @Author: jeecg-boot
 * @Date:   2025-06-11
 * @Version: V1.0
 */
@Service
public class WorkDivisionServiceImpl extends ServiceImpl<WorkDivisionMapper, WorkDivision> implements IWorkDivisionService {

    @Autowired
    private WorkDivisionSetMapper workDivisionSetMapper;
    @Autowired
    private WorkOrderMapper workOrderMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saves(WorkDivision workDivision) {

        if (workDivision == null || workDivision.getWorkOrder() == null) {
            return false;
        }

        // 1️⃣ 校验工单状态
        WorkOrder workOrder = workOrderMapper.selectById(workDivision.getWorkOrder());
        if (workOrder == null) {
            throw new RuntimeException("工单不存在！");
        }
        if (!Arrays.asList(0, 1, 2).contains(workOrder.getStatus())) {
            throw new RuntimeException("此工单不可派工！");
        }

        List<WorkDivision.ExecutorItem> newList = Optional.ofNullable(workDivision.getExecutorList()).orElse(List.of());

        if (CollectionUtil.isEmpty(newList)) {
            throw new RuntimeException("请选择派工人员！");
        }

        // 2️⃣ 负责人校验
        long leaderCount = newList.stream()
                .filter(e -> Integer.valueOf(0).equals(e.getTorType()))
                .count();
        if (leaderCount > 1) {
            throw new RuntimeException("负责人只能指定一个执行人！");
        }

        // 3️⃣ 查询数据库已有派工
        List<WorkDivision> dbList = this.list(
                new LambdaQueryWrapper<WorkDivision>()
                        .eq(WorkDivision::getWorkOrder, workDivision.getWorkOrder())
        );

        // 4️⃣ 构造 Map（便于对比）
        Map<String, WorkDivision> dbMap = dbList.stream()
                .collect(Collectors.toMap(WorkDivision::getExecutor, Function.identity(), (a, b) -> a));
        Map<String, WorkDivision.ExecutorItem> newMap = newList.stream()
                .collect(Collectors.toMap(WorkDivision.ExecutorItem::getExecutor, Function.identity(), (a, b) -> a));

        List<WorkDivision> insertList = new ArrayList<>();
        List<WorkDivision> updateList = new ArrayList<>();
        List<String> deleteExecutorIds = new ArrayList<>();

        // 5️⃣ 新增 & 修改
        for (WorkDivision.ExecutorItem item : newList) {
            WorkDivision db = dbMap.get(item.getExecutor());
            if (db == null) {
                // ➕ 新增
                insertList.add(buildWorkDivision(workDivision, item.getExecutor(), item.getTorType()));
            } else if (!Objects.equals(db.getTorType(), item.getTorType())) {
                // ✏️ 修改 torType
                db.setTorType(item.getTorType());
                updateList.add(db);
            }
        }

        // 6️⃣ 删除
        for (WorkDivision db : dbList) {
            if (!newMap.containsKey(db.getExecutor())) {
                deleteExecutorIds.add(db.getExecutor());
            }
        }

        // 7️⃣ 执行数据库操作
        if (CollectionUtil.isNotEmpty(insertList)) {
            this.saveBatch(insertList);
        }
        if (CollectionUtil.isNotEmpty(updateList)) {
            this.updateBatchById(updateList);
        }
        if (CollectionUtil.isNotEmpty(deleteExecutorIds)) {
            this.remove(new LambdaQueryWrapper<WorkDivision>()
                    .eq(WorkDivision::getWorkOrder, workDivision.getWorkOrder()).in(WorkDivision::getExecutor, deleteExecutorIds));
        }

        // 8️⃣ 重新计算负责人
        String coordinatorId = newList.stream()
                .filter(e -> Integer.valueOf(0).equals(e.getTorType()))
                .map(WorkDivision.ExecutorItem::getExecutor)
                .findFirst()
                .orElse(null);

        // 9️⃣ 更新工单
        return workOrderMapper.update(null, new LambdaUpdateWrapper<WorkOrder>()
                .set(WorkOrder::getCoordinator, coordinatorId).set(WorkOrder::getStatus, 2).eq(WorkOrder::getId, workDivision.getWorkOrder())) > 0;
    }

    /**
     * 构造 WorkDivision 实体
     */
    private WorkDivision buildWorkDivision(WorkDivision base, String executor, Integer torType) {
        WorkDivision wd = new WorkDivision();
        wd.setDeviceId(base.getDeviceId());
        wd.setRegularId(base.getRegularId());
        wd.setPlanId(base.getPlanId());
        wd.setWorkOrder(base.getWorkOrder());
        wd.setExecutor(executor);
        wd.setTorType(torType);
        return wd;
    }
}
