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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.regular.entity.Regular;
import org.jeecg.modules.regular.entity.RegularDetail;
import org.jeecg.modules.regular.entity.RegularInput;
import org.jeecg.modules.regular.mapper.RegularDetailMapper;
import org.jeecg.modules.regular.mapper.RegularInputMapper;
import org.jeecg.modules.regular.mapper.RegularMapper;
import org.jeecg.modules.system.util.SecurityUtil;
import org.jeecg.modules.tool.entity.Tool;
import org.jeecg.modules.tool.mapper.ToolMapper;
import org.jeecg.modules.toolBorrowingRecord.entity.ToolBorrowingRecord;
import org.jeecg.modules.toolBorrowingRecord.mapper.ToolBorrowingRecordMapper;
import org.jeecg.modules.toolSheet.entity.ToolSheet;
import org.jeecg.modules.toolSheet.mapper.ToolSheetMapper;
import org.jeecg.modules.workOrder.entity.WorkOrder;
import org.jeecg.modules.workOrder.entity.WorkRecord;
import org.jeecg.modules.workOrder.mapper.WorkOrderMapper;
import org.jeecg.modules.workOrder.mapper.WorkRecordMapper;
import org.jeecg.modules.workOrder.model.WorkOrderDetailRecord;
import org.jeecg.modules.workOrder.service.IWorkRecordService;
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.stream.Collectors;

/**
 * @Description: 作业数据记录
 * @Author: jeecg-boot
 * @Date:   2025-02-20
 * @Version: V1.0
 */
@Service
@Slf4j
@AllArgsConstructor
public class WorkRecordServiceImpl extends ServiceImpl<WorkRecordMapper, WorkRecord> implements IWorkRecordService {
    private final WorkOrderMapper workOrderMapper;
    private final RegularInputMapper regularInputMapper;
    private final ToolBorrowingRecordMapper toolBorrowingRecordMapper;
    private final ToolSheetMapper toolSheetMapper;
    private final RegularDetailMapper regularDetailMapper;

    private final ToolMapper toolMapper;

    private final RegularMapper regularMapper;

    @Override
    public IPage<WorkRecord> queryPages(Page<WorkRecord> page, QueryWrapper<WorkRecord> queryWrapper){
        IPage<WorkRecord> pageList = super.page(page, queryWrapper.eq("now_way",1));
//        pageList.getRecords().forEach(workRecord -> {
//
//        });
        return pageList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean nowWorkRecord(String recordId) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        if (null == sysUser) {
            log.error("用户不存在");
            throw new RuntimeException("非法用户");
        }
        WorkRecord workRecord = baseMapper.selectById(recordId);
        // 将指定作业数据记录置为高亮，此条数据接收来自工具上传的测量数据
        workRecord.setNowWay(1);
        return (baseMapper.updateById(workRecord)>0 &&
        baseMapper.update(null, new LambdaUpdateWrapper<WorkRecord>().set(WorkRecord::getNowWay,0).set(WorkRecord::getInspector, sysUser.getId())
                .eq(WorkRecord::getToolId,workRecord.getToolId()).eq(WorkRecord::getWorkOrder,workRecord.getWorkOrder())
                .ne(WorkRecord::getId,recordId))>0);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public WorkRecord againWorkRecord(String recordId) {
        WorkRecord oldRecord = baseMapper.selectById(recordId);
        // 将原始数据置为高亮（工具上传的数据）
        oldRecord.setNowWay(0);
        baseMapper.updateById(oldRecord);

        // 创建新的作业数据（再次测量的数据）
        WorkRecord newRecord = new WorkRecord();
        BeanUtil.copyProperties(oldRecord, newRecord);
        newRecord.setId(null); // 确保是新插入，而不是更新
        newRecord.setCollectNum(oldRecord.getCollectNum() + 1);
        newRecord.setNowWay(1);
        newRecord.setNumericValue(null);   // ⭐ 非常重要

        baseMapper.insert(newRecord);

        return newRecord;
    }

    @Override
    public List<WorkOrderDetailRecord> listWorkRecordByWorkOrder(String workOrder) {
        List<RegularDetail> regularDetails = regularDetailMapper.queryInputDetailByOrder(workOrder);

        List<WorkOrderDetailRecord> result = new ArrayList<>();
        regularDetails.forEach(regularDetail -> {
            // pid非空仅查询实际测量要求
            List<RegularInput> regularInputs = regularInputMapper.selectList(new LambdaQueryWrapper<RegularInput>().eq(RegularInput::getDetailId,regularDetail.getId()).isNotNull(RegularInput::getPid));
            if(regularInputs.isEmpty()) throw new RuntimeException("修程存在未配置的测量项点！");
            List<String> inputIds = regularInputs.stream().map(RegularInput::getId).toList();
            Map<String,RegularInput> inputMap = regularInputs.stream().collect(Collectors.toMap(RegularInput::getId,RegularInput->RegularInput));
            // 查询当前工单下的测量项
            List<WorkRecord> records = baseMapper.selectList(new LambdaQueryWrapper<WorkRecord>().in(WorkRecord::getRegularInputId,inputIds).eq(WorkRecord::getWorkOrder,workOrder).eq(WorkRecord::getNowWay,1));
            records.forEach(item -> {
                item.setMinValue(inputMap.get(item.getRegularInputId()).getMinValue());
                item.setMaxValue(inputMap.get(item.getRegularInputId()).getMaxValue());
                item.setToolTypeId(inputMap.get(item.getRegularInputId()).getToolId());
                item.setAvgCount(inputMap.get(item.getRegularInputId()).getAvgCount());
            });

            WorkOrderDetailRecord detailRecord = new WorkOrderDetailRecord();
            detailRecord.setDetailId(regularDetail.getId());
            detailRecord.setContent(regularDetail.getContent());
            detailRecord.setWorkRecordList(records);
            result.add(detailRecord);
        });
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<WorkOrderDetailRecord> initWorkRecord(WorkRecord workRecord) {
        if(workRecord.getInputIds().isEmpty()){
            return Collections.emptyList();
        }
        // workOrder、inspector、inputIds前端提供
        // 查询工单基础信息
        WorkOrder workOrder = workOrderMapper.selectById(workRecord.getWorkOrder());
        // 查询所有工具借用记录
        List<ToolSheet> toolSheetList = toolBorrowingRecordMapper.selectToolSheetByWorkOrder(workRecord.getWorkOrder());
        // 获取工具种类和具体工具的映射关系
        Map<String, String> toolMap = buildToolMapping(toolSheetList);

        //查询工单下所有测量项并创建工作记录
        List<WorkOrderDetailRecord> workDetailRecordList = createWorkRecords(workRecord, workOrder.getDeviceId(), toolMap);

        if(!workDetailRecordList.isEmpty()){
            return workDetailRecordList;
        }
        return Collections.emptyList();
    }

    /**
     * 构建工具映射关系，处理同种工具多个实例的情况
     * 当同种工具有多个实例时，映射值为null，表示需要工人手动选择
     *
     * @param toolSheetList 工具列表
     * @return 工具映射Map，key为工具ID，value为工具实例ID(同种工具有多个时为null)
     */
    private Map<String, String> buildToolMapping(List<ToolSheet> toolSheetList) {
        Map<String, String> toolMap = new HashMap<>();
        Map<String, Integer> toolCountMap = new HashMap<>();

        // 第一次遍历：统计每种工具的数量
        toolSheetList.forEach(toolSheet -> toolCountMap.merge(toolSheet.getToolId(), 1, Integer::sum));

        // 第二次遍历：构建映射关系
        toolSheetList.forEach(toolSheet -> {
            String toolTypeId = toolSheet.getToolId();
            // 如果同类型工具有多个，则置为null让工人手动选择
            if (toolCountMap.get(toolTypeId) > 1) {
                toolMap.putIfAbsent(toolTypeId, null);
            } else {
                toolMap.put(toolTypeId, toolSheet.getId());
            }
        });

        return toolMap;
    }

    /**
     * 查询工单下所有测量项并创建工作记录
     * @param template
     * @param deviceId
     * @param toolMap
     * @return
     */
    private List<WorkOrderDetailRecord> createWorkRecords(WorkRecord template, String deviceId, Map<String, String> toolMap) {
        //查询工单下所有测量项
        List<RegularInput> regularInputList = regularInputMapper
                .selectList(new LambdaQueryWrapper<RegularInput>().in(RegularInput::getId, template.getInputIds()));

        Map<String,List<RegularInput>> dddddd = regularInputList.stream().collect(Collectors.groupingBy(RegularInput::getDetailId));

        List<WorkOrderDetailRecord> workOrderDetailRecordList = new ArrayList<>();

        // 生成需要创建的工作记录列表
        dddddd.forEach((detailId,inputList) -> {
            RegularDetail regularDetail = regularDetailMapper.selectById(detailId);
            WorkOrderDetailRecord detailRecord = new WorkOrderDetailRecord();
            detailRecord.setDetailId(detailId);
            detailRecord.setContent(regularDetail.getContent());
            List<WorkRecord> workRecordList = new ArrayList<>();
            inputList.forEach(input -> {
                WorkRecord record = new WorkRecord();
                record.setWorkOrder(template.getWorkOrder());
                record.setDeviceId(deviceId);
                record.setRegularInputId(input.getId());
                record.setToolId(toolMap.get(input.getToolId()));
                record.setToolTypeId(input.getToolId());
                record.setUnit(input.getUnit());
                record.setMaxValue(input.getMaxValue());
                record.setMinValue(input.getMinValue());
                record.setAvgCount(input.getAvgCount());
                workRecordList.add(record);
            });
            super.saveBatch(workRecordList);
            detailRecord.setWorkRecordList(workRecordList);
            workOrderDetailRecordList.add(detailRecord);
        });

        return workOrderDetailRecordList;
    }

    /**
     * 小车根据工单和工具创建工具的测量项
     * @param template
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<WorkRecord> initWorkRecordTwo(WorkRecord template) throws Exception {
        // 校验工单
        WorkOrder workOrder = workOrderMapper.selectById(template.getWorkOrder());
        if (ObjectUtil.isEmpty(workOrder)) {
            throw new IllegalArgumentException("工单不存在！");
        }

        // 校验工具单
        ToolSheet toolSheet = toolSheetMapper.selectById(template.getToolId());
        if (ObjectUtil.isEmpty(toolSheet)) {
            throw new IllegalArgumentException("工具信息不存在！");
        }

        // 若已存在记录，直接返回
        List<WorkRecord> existingRecords = baseMapper.selectList(new LambdaQueryWrapper<WorkRecord>()
                .eq(WorkRecord::getWorkOrder, template.getWorkOrder()).eq(WorkRecord::getToolId, template.getToolId()));
        if (CollectionUtil.isNotEmpty(existingRecords)) {
            return existingRecords;
        }

        // 查询测量项
        List<RegularInput> inputs = regularInputMapper.queryInputByOrderAndTool(workOrder.getRegularId(), toolSheet.getToolId());
        if (CollectionUtil.isEmpty(inputs)) {
            return Collections.emptyList();
        }

        // 构建工作记录
        List<WorkRecord> newRecords = inputs.stream()
                .map(input -> {
                    WorkRecord record = new WorkRecord();
                    record.setWorkOrder(workOrder.getId());
                    record.setDeviceId(workOrder.getDeviceId());
                    record.setPartId(regularInputMapper.queryPartByDeviceAndInput(workOrder.getDeviceId(), input.getDetailId()));
                    record.setToolId(toolSheet.getToolId());
                    record.setRegularInputId(input.getId());
                    record.setUnit(input.getUnit());
                    return record;
                }).toList();

        return super.saveBatch(newRecords) ? newRecords : Collections.emptyList();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public RegularInput nowWorkRecordTwo(String recordId) {
        WorkRecord workRecord = baseMapper.selectById(recordId);
        // 将指定作业数据记录置为高亮，此条数据接收来自工具上传的测量数据
        workRecord.setNowWay(1);
        baseMapper.updateById(workRecord);
        baseMapper.update(null, new LambdaUpdateWrapper<WorkRecord>().set(WorkRecord::getNowWay,0)
                .eq(WorkRecord::getToolId,workRecord.getToolId()).eq(WorkRecord::getWorkOrder,workRecord.getWorkOrder())
                .ne(WorkRecord::getId,recordId));
        return regularInputMapper.selectById(workRecord.getRegularInputId());
    }

    @Override
    public WorkRecord insertWorkRecord(Map<String, Object> data) {
        String regularId = (String) data.get("regularId");
        String workOrderId = (String) data.get("workOrder");
        String content = (String) data.get("content");
        WorkRecord record = new WorkRecord();
        // 校验工单
        WorkOrder workOrder = workOrderMapper.selectById(workOrderId);

        // 先根据regularId 拿到 DeviceTypeId，然后再加上 content 去查询 RegularDetail 的 id，最后再根据 RegularDetail 的 id 查询 RegularInput 的 中的 toolId,在转换为toosheet中的id
        // 最终目的：根据输入值找到该测量对应的toolid 和 toolSheetId
        Regular regular = regularMapper.selectById(regularId);
        RegularDetail regularDetail = regularDetailMapper.selectOne(new LambdaQueryWrapper<RegularDetail>().eq(RegularDetail::getDeviceTypeId, regular.getDeviceTypeId())
                .eq(RegularDetail::getContent, content).eq(RegularDetail::getRegularId, regularId));
        RegularInput input = regularInputMapper.selectOne(new LambdaQueryWrapper<RegularInput>().eq(RegularInput::getDetailId, regularDetail.getId())
                .isNotNull(RegularInput::getPid));
        ToolSheet toolSheet = toolSheetMapper.selectOne(new LambdaQueryWrapper<ToolSheet>().eq(ToolSheet::getToolId, input.getToolId()).eq(ToolSheet::getNum,0));

        // 交验工具是否借用
        ToolBorrowingRecord toolBorrowingRecord = toolBorrowingRecordMapper.selectOne(
                new LambdaQueryWrapper<ToolBorrowingRecord>().eq(ToolBorrowingRecord::getToolId, toolSheet.getId())
                        .eq(ToolBorrowingRecord::getStatus, 0)
                        .eq(ToolBorrowingRecord::getWorkOrder, workOrderId));
        if (toolBorrowingRecord == null) {
            Tool tool = toolMapper.selectById(toolSheet.getToolId());
            log.error("工具：{} 未借用，请先借用！", tool.getName());
            return null;
        }
        // 创建工作记录对象并保存
        record.setWorkOrder(workOrderId);
        record.setDeviceId(workOrder.getDeviceId());
        record.setRegularInputId(input.getId());
        record.setInspector(workOrder.getExecutor());
        record.setToolId(toolSheet.getId());
        record.setUnit(input.getUnit());
        record.setNowWay(1);
        //允许一个工具测量多次
        baseMapper.update(null,new LambdaUpdateWrapper<WorkRecord>().set(WorkRecord::getNowWay,0)
                .eq(WorkRecord::getWorkOrder, workOrderId).eq(WorkRecord::getDeviceId, workOrder.getDeviceId())
                .eq(WorkRecord::getToolId, toolSheet.getId()));
//        WorkRecord workRecord = baseMapper.selectOne(new LambdaQueryWrapper<WorkRecord>().eq(WorkRecord::getWorkOrder, workOrderId).eq(WorkRecord::getDeviceId, workOrder.getDeviceId()).eq(WorkRecord::getToolId, toolSheet.getId()));
//        if (workRecord != null) {
//            log.error("该工具已存在工作记录，请勿重复插入！");
//            return null;
//        }
        super.save(record);

        return record;
    }

}
