package cn.iocoder.yudao.module.mes.service.zjtask;

import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.mes.controller.admin.feedingrecord.vo.FeedingRecordRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.ticketmanagement.vo.TicketManagementBatchUpdateReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.organization.OrganizationDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.plan.PlanDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.ticketmanagement.TicketManagementDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.zjitem.ZjItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.zjschema.ZjSchemaDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.zjtaskresults.ZjTaskResultsDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.zjtype.ZjTypeDO;
import cn.iocoder.yudao.module.mes.dal.mysql.zjitem.ZjItemMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.zjschema.ZjSchemaMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.zjtaskresults.ZjTaskResultsMapper;
import cn.iocoder.yudao.module.mes.service.plan.PlanService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;

import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import cn.iocoder.yudao.module.mes.controller.admin.zjtask.vo.*;
import cn.iocoder.yudao.module.mes.dal.dataobject.zjtask.ZjTaskDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.mes.dal.mysql.zjtask.ZjTaskMapper;

import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.UNAUTHORIZED;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;

/**
 * 质量管理-检验任务 Service 实现类
 *
 * @author 必硕科技
 */
@Service
@Validated
public class ZjTaskServiceImpl implements ZjTaskService {

    @Resource
    private ZjTaskMapper zjTaskMapper;

    @Resource
    private ZjSchemaMapper zjSchemaMapper;

    @Resource
    private ZjTaskResultsMapper zjTaskResultsMapper; // 检验结果Mapper

    @Resource
    private ZjItemMapper zjItemMapper; // 检验项目Mapper（用于关联查询方案下的项目）

    @Resource
    private PlanService planService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createZjTask(ZjTaskSaveReqVO createReqVO) {
        // 校验编码是否存在
        validateCodeOnly(createReqVO.getCode());
        // 插入
        ZjTaskDO zjTask = BeanUtils.toBean(createReqVO, ZjTaskDO.class);
        zjTaskMapper.insert(zjTask);


        // 2. 新增逻辑：根据检验方案关联的项目，创建对应的ZjTaskResult记录
        // 2.1 查询检验方案（获取关联的检验项目）
        ZjSchemaDO schemaDO = zjSchemaMapper.selectById(createReqVO.getSchemaId());
        if (schemaDO != null && StringUtils.hasText(schemaDO.getItem())) {
            // 2.2 拆分方案关联的项目ID（假设item字段存储的是逗号分隔的项目ID，如"1,2,3"）
            String[] itemIds = schemaDO.getItem().split(",");
            for (String itemIdStr : itemIds) {
                if (!StringUtils.hasText(itemIdStr)) {
                    continue;
                }
                Long itemId = Long.valueOf(itemIdStr);
                // 2.3 查询检验项目详情
                ZjItemDO itemDO = zjItemMapper.selectById(itemId);
                if (itemDO == null) {
                    continue; // 项目不存在则跳过
                }

                // 2.4 构建检验结果DO（关联当前新建的任务ID）
                ZjTaskResultsDO resultDO = ZjTaskResultsDO.builder()
                        .zjType(itemDO.getZjType()) // 复用检验项目的类型
                        .name(itemDO.getName()) // 复用检验项目的名称
                        .remark(itemDO.getRemark()) // 复用检验项目的备注
                        .tool(itemDO.getTool()) // 复用检验项目的作业方式
                        .standardVal(itemDO.getStandardVal()) // 复用检验项目的标准值
                        .unit(itemDO.getUnit()) // 复用检验项目的单位
                        .upperVal(itemDO.getUpperVal()) // 复用检验项目的上限值
                        .lowerVal(itemDO.getLowerVal()) // 复用检验项目的下限值
                        .zjResult(0) // 初始状态：待检测（0-待检测 1-通过 2-不通过）
                        .taskId(zjTask.getId()) // 关联当前新建的检验任务ID
                        // 设备ID等无默认值的字段可留空，后续更新
                        .build();
                // 2.5 插入检验结果记录
                zjTaskResultsMapper.insert(resultDO);
            }
        }
        // 返回
        return zjTask.getId();
    }

    private void validateCodeOnly(String code) {
        if (zjTaskMapper.exists(Wrappers.<ZjTaskDO>lambdaQuery()
                .eq(ZjTaskDO::getCode, code))) {
            throw exception(ZJ_TASK_CODE_EXISTS);
        }
    }

    @Override
    public void updateZjTask(ZjTaskSaveReqVO updateReqVO) {
        // 校验存在
        validateZjTaskExists(updateReqVO.getId());
        // 更新
        ZjTaskDO updateObj = BeanUtils.toBean(updateReqVO, ZjTaskDO.class);
        zjTaskMapper.updateById(updateObj);
    }

    @Override
    public void deleteZjTask(Long id) {
        // 校验存在
        validateZjTaskExists(id);
        // 删除
        zjTaskMapper.deleteById(id);
    }

    private void validateZjTaskExists(Long id) {
        if (zjTaskMapper.selectById(id) == null) {
            throw exception(ZJ_TASK_NOT_EXISTS);
        }
    }

    @Override
    public ZjTaskDO getZjTask(Long id) {
        return zjTaskMapper.selectById(id);
    }

    @Override
    public PageResult<ZjTaskDO> getZjTaskPage(ZjTaskPageReqVO pageReqVO) {
        PageResult<ZjTaskDO> pageResult = zjTaskMapper.selectPage(pageReqVO);
        Map<Long, PlanDO> planMap = planService.getPlanMap(convertSet(pageResult.getList(), ZjTaskDO::getTicket));
        return BeanUtils.toBean(pageResult, ZjTaskDO.class, zjTaskDO -> {
            MapUtils.findAndThen(planMap, zjTaskDO.getTicket(), planDO -> zjTaskDO.setTicketCode(planDO.getCode()));
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateZjTaskResultOnly(Long id, String result) {
        // 1. 校验任务存在
        ZjTaskDO zjTask = zjTaskMapper.selectById(id);
        if (zjTask == null) {
            throw exception(ZJ_TASK_NOT_EXISTS);
        }

        // 2. 获取当前登录用户信息（适配实际的LoginUser类结构）
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        if (loginUser == null) {
            throw exception(UNAUTHORIZED); // 抛出未登录异常，根据业务调整
        }
        Long currentUserId = loginUser.getId(); // 当前用户ID（直接从id字段获取）
        // 从info集合中获取用户名（nickname键），兼容空值
        String currentUserName = loginUser.getInfo() != null ? loginUser.getInfo().get(LoginUser.INFO_KEY_NICKNAME) : null;

        // 3. 构建更新对象，仅更新指定字段
        ZjTaskDO updateDO = new ZjTaskDO();
        updateDO.setId(id);
        updateDO.setResult(result);       // 检验结果
        updateDO.setStatus(1);            // 状态置为1（int型）
        updateDO.setExecuteTime(LocalDateTime.now()); // 执行时间为当前时间（推荐用LocalDateTime，适配框架时间类型）
        updateDO.setExecutorId(currentUserId); // 执行人ID（当前用户）
        updateDO.setExecutorName(currentUserName); // 执行人名称（当前用户昵称）

        // 4. 执行更新
        zjTaskMapper.updateById(updateDO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchUpdateJobStatus(ZjTaskBatchUpdateReqVO reqVO) {
        // 1. 解析ID列表
        List<Long> idList = parseIds(reqVO.getIds());
        if (idList.isEmpty()) {
            throw exception(ZJ_TASK_NOT_EXISTS);
        }
        // 2. 批量更新
        zjTaskMapper.batchUpdateJobStatus(idList, reqVO.getStatus(),reqVO.getCancelReason());
    }


    /**
     * 解析逗号分隔的ID字符串
     */
    private List<Long> parseIds(String ids) {
        if (com.alibaba.excel.util.StringUtils.isBlank(ids)) {
            return Collections.emptyList();
        }

        return Arrays.stream(ids.split(","))
                .map(String::trim)
                .filter(com.alibaba.excel.util.StringUtils::isNotBlank)
                .map(Long::valueOf)
                .distinct()
                .collect(Collectors.toList());
    }

}