package com.sundot.airport.check.service.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sundot.airport.check.domain.CheckProjectItem;
import com.sundot.airport.check.service.ICheckProjectItemService;
import com.sundot.airport.common.constant.Constants;
import com.sundot.airport.common.core.redis.RedisSerialGenerator;
import com.sundot.airport.common.domain.BaseRead;
import com.sundot.airport.common.enums.BaseReadTypeEnum;
import com.sundot.airport.common.enums.CheckProjectItemTypeEnum;
import com.sundot.airport.common.enums.CheckTaskStatusEnum;
import com.sundot.airport.common.service.IBaseReadService;
import com.sundot.airport.common.utils.DateUtils;
import com.sundot.airport.common.utils.SecurityUtils;
import com.sundot.airport.system.domain.vo.CheckProjectItemTreeVo;
import com.sundot.airport.system.domain.vo.CheckProjectItemVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.sundot.airport.check.mapper.CheckTaskMapper;
import com.sundot.airport.check.domain.CheckTask;
import com.sundot.airport.check.service.ICheckTaskService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 检查任务Service业务层处理
 *
 * @author ruoyi
 * @date 2025-09-07
 */
@Service
public class CheckTaskServiceImpl extends ServiceImpl<CheckTaskMapper, CheckTask> implements ICheckTaskService {
    @Autowired
    private CheckTaskMapper checkTaskMapper;

    @Autowired
    private ICheckProjectItemService checkProjectItemService;

    @Autowired
    private RedisSerialGenerator redisSerialGenerator;

    @Autowired
    private IBaseReadService baseReadService;

    /**
     * 查询检查任务
     *
     * @param id 检查任务主键
     * @return 检查任务
     */
    @Override
    public CheckTask selectCheckTaskById(Long id) {
        CheckTask result = checkTaskMapper.selectCheckTaskById(id);
        Date currentDate = DateUtils.getNowDate();
        if (currentDate.before(result.getCheckStartTime())) {
            result.setStatus(CheckTaskStatusEnum.PENDING_EXECUTION.getCode());
            result.setStatusDesc(CheckTaskStatusEnum.PENDING_EXECUTION.getDesc());
        } else if (currentDate.after(result.getCheckEndTime())) {
            result.setStatus(CheckTaskStatusEnum.COMPLETED.getCode());
            result.setStatusDesc(CheckTaskStatusEnum.COMPLETED.getDesc());
        } else {
            result.setStatus(CheckTaskStatusEnum.IN_PROGRESS.getCode());
            result.setStatusDesc(CheckTaskStatusEnum.IN_PROGRESS.getDesc());
        }
        //检查项明细列表
        CheckProjectItem checkProjectItem = new CheckProjectItem();
        checkProjectItem.setType(CheckProjectItemTypeEnum.CHECK_TASK.getCode());
        checkProjectItem.setSourceId(result.getId());
        List<CheckProjectItem> checkProjectItemList = checkProjectItemService.selectCheckProjectItemList(checkProjectItem);
        result.setCheckProjectItemList(checkProjectItemList);
        //检查项明细列表树形结构
        List<CheckProjectItemVo> checkProjectItemVoList = checkProjectItemList.stream().map(item -> {
            CheckProjectItemVo checkProjectItemVo = new CheckProjectItemVo();
            BeanUtil.copyProperties(item, checkProjectItemVo);
            return checkProjectItemVo;
        }).collect(Collectors.toList());
        result.setCheckProjectItemTreeVoList(convertToTree(checkProjectItemVoList));
        //已读处理
        doBaseRead(result);
        return result;
    }

    /**
     * 已读处理
     *
     * @param result
     */
    private void doBaseRead(CheckTask result) {
        BaseRead baseRead = new BaseRead();
        baseRead.setUserId(SecurityUtils.getLoginUser().getUserId());
        baseRead.setUserName(SecurityUtils.getLoginUser().getUsername());
        baseRead.setFormId(result.getId());
        baseRead.setFormCode(result.getTaskCode());
        baseRead.setFormName(result.getTaskName());
        baseRead.setType(BaseReadTypeEnum.CHECK_TASK.getCode());
        baseRead.setTypeDesc(BaseReadTypeEnum.CHECK_TASK.getDesc());
        baseReadService.insertOrUpdateBaseRead(baseRead);
    }

    /**
     * 查询检查任务列表
     *
     * @param checkTask 检查任务
     * @return 检查任务
     */
    @Override
    public List<CheckTask> selectCheckTaskList(CheckTask checkTask) {
        List<CheckTask> result = checkTaskMapper.selectCheckTaskList(checkTask);
        if (CollUtil.isNotEmpty(result)) {
            Date currentDate = getDateWithoutTime(DateUtils.getNowDate());
            result.forEach(item -> {
                if (currentDate.before(item.getCheckStartTime())) {
                    item.setStatus(CheckTaskStatusEnum.PENDING_EXECUTION.getCode());
                    item.setStatusDesc(CheckTaskStatusEnum.PENDING_EXECUTION.getDesc());
                } else if (currentDate.after(item.getCheckEndTime())) {
                    item.setStatus(CheckTaskStatusEnum.COMPLETED.getCode());
                    item.setStatusDesc(CheckTaskStatusEnum.COMPLETED.getDesc());
                } else {
                    item.setStatus(CheckTaskStatusEnum.IN_PROGRESS.getCode());
                    item.setStatusDesc(CheckTaskStatusEnum.IN_PROGRESS.getDesc());
                }
            });
            //是否已读处理
            checkIsRead(result);
        }
        return result;
    }

    /**
     * 是否已读处理
     *
     * @param result 检查任务列表
     */
    private void checkIsRead(List<CheckTask> result) {
        List<Long> checkTaskIdlist = result.stream().map(CheckTask::getId).collect(Collectors.toList());
        BaseRead baseRead = new BaseRead();
        baseRead.setUserId(SecurityUtils.getLoginUser().getUserId());
        baseRead.setType(BaseReadTypeEnum.CHECK_TASK.getCode());
        List<BaseRead> baseReadList = baseReadService.selectBaseReadListByCondition(baseRead, checkTaskIdlist);
        if (CollUtil.isEmpty(baseReadList)) {
            result.forEach(item -> item.setRead(false));
            return;
        }
        List<Long> formIdList = baseReadList.stream().map(BaseRead::getFormId).collect(Collectors.toList());
        result.forEach(item -> {
            item.setRead(formIdList.contains(item.getId()));
        });
    }

    /**
     * 新增检查任务
     *
     * @param checkTask 检查任务
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int insertCheckTask(CheckTask checkTask) {
        checkTask.setCreateTime(DateUtils.getNowDate());
        checkTask.setTaskCode(redisSerialGenerator.generate(Constants.CHECK_TASK_PREFIX));
        int result = checkTaskMapper.insertCheckTask(checkTask);
        //检查项明细列表
        checkTask.getCheckProjectItemList().forEach(checkProjectItem -> {
            checkProjectItem.setCreateBy(checkTask.getCreateBy());
            checkProjectItem.setCreateTime(DateUtils.getNowDate());
            checkProjectItem.setType(CheckProjectItemTypeEnum.CHECK_TASK.getCode());
            checkProjectItem.setTypeDesc(CheckProjectItemTypeEnum.CHECK_TASK.getInfo());
            checkProjectItem.setSourceId(checkTask.getId());
            checkProjectItemService.insertCheckProjectItem(checkProjectItem);
        });
        return result;
    }

    /**
     * 修改检查任务
     *
     * @param checkTask 检查任务
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateCheckTask(CheckTask checkTask) {
        checkTask.setUpdateTime(DateUtils.getNowDate());
        int result = checkTaskMapper.updateCheckTask(checkTask);
        //检查项明细列表先删除后增加
        CheckProjectItem checkProjectItemQuery = new CheckProjectItem();
        checkProjectItemQuery.setType(CheckProjectItemTypeEnum.CHECK_TASK.getCode());
        checkProjectItemQuery.setSourceId(checkTask.getId());
        List<CheckProjectItem> checkProjectItemListOld = checkProjectItemService.selectCheckProjectItemList(checkProjectItemQuery);
        checkProjectItemService.removeBatchByIds(checkProjectItemListOld);
        checkTask.getCheckProjectItemList().forEach(checkProjectItem -> {
            checkProjectItem.setId(null);
            checkProjectItem.setCreateBy(checkTask.getCreateBy());
            checkProjectItem.setCreateTime(DateUtils.getNowDate());
            checkProjectItem.setType(CheckProjectItemTypeEnum.CHECK_TASK.getCode());
            checkProjectItem.setTypeDesc(CheckProjectItemTypeEnum.CHECK_TASK.getInfo());
            checkProjectItem.setSourceId(checkTask.getId());
            checkProjectItemService.insertCheckProjectItem(checkProjectItem);
        });
        return result;
    }

    /**
     * 批量删除检查任务
     *
     * @param ids 需要删除的检查任务主键
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deleteCheckTaskByIds(Long[] ids) {
        int result = checkTaskMapper.deleteCheckTaskByIds(ids);
        for (Long id : ids) {
            CheckProjectItem checkProjectItemQuery = new CheckProjectItem();
            checkProjectItemQuery.setType(CheckProjectItemTypeEnum.CHECK_TASK.getCode());
            checkProjectItemQuery.setSourceId(id);
            List<CheckProjectItem> checkProjectItemListOld = checkProjectItemService.selectCheckProjectItemList(checkProjectItemQuery);
            checkProjectItemService.removeBatchByIds(checkProjectItemListOld);
        }
        return result;
    }

    /**
     * 删除检查任务信息
     *
     * @param id 检查任务主键
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deleteCheckTaskById(Long id) {
        int result = checkTaskMapper.deleteCheckTaskById(id);
        CheckProjectItem checkProjectItemQuery = new CheckProjectItem();
        checkProjectItemQuery.setType(CheckProjectItemTypeEnum.CHECK_TASK.getCode());
        checkProjectItemQuery.setSourceId(id);
        List<CheckProjectItem> checkProjectItemListOld = checkProjectItemService.selectCheckProjectItemList(checkProjectItemQuery);
        checkProjectItemService.removeBatchByIds(checkProjectItemListOld);
        return result;
    }

    /**
     * 查询检查任务未读数量
     *
     * @param checkTask 检查任务筛选条件
     * @return 检查任务未读数量
     */
    @Override
    public int unReadNum(CheckTask checkTask) {
        List<CheckTask> checkTaskList = checkTaskMapper.selectCheckTaskList(checkTask);
        if (CollUtil.isEmpty(checkTaskList)) {
            return 0;
        }
        //是否已读处理
        checkIsRead(checkTaskList);
        return (int) checkTaskList.stream().filter(item -> !item.isRead()).count();
    }

    /**
     * 查询检查任务列表web端
     *
     * @param checkTask 检查任务
     * @return 检查任务
     */
    @Override
    public List<CheckTask> selectCheckTaskListWeb(CheckTask checkTask) {
        List<CheckTask> result = checkTaskMapper.selectCheckTaskListWeb(checkTask);
        if (CollUtil.isNotEmpty(result)) {
            Date currentDate = getDateWithoutTime(DateUtils.getNowDate());
            result.forEach(item -> {
                if (currentDate.before(item.getCheckStartTime())) {
                    item.setStatus(CheckTaskStatusEnum.PENDING_EXECUTION.getCode());
                    item.setStatusDesc(CheckTaskStatusEnum.PENDING_EXECUTION.getDesc());
                } else if (currentDate.after(item.getCheckEndTime())) {
                    item.setStatus(CheckTaskStatusEnum.COMPLETED.getCode());
                    item.setStatusDesc(CheckTaskStatusEnum.COMPLETED.getDesc());
                } else {
                    item.setStatus(CheckTaskStatusEnum.IN_PROGRESS.getCode());
                    item.setStatusDesc(CheckTaskStatusEnum.IN_PROGRESS.getDesc());
                }
            });
            //是否已读处理
            checkIsRead(result);
        }
        return result;
    }

    /**
     * 查询检查任务列表web端
     *
     * @param checkTask 检查任务
     * @return 检查任务
     */
    @Override
    public List<CheckTask> selectCheckTaskListBrigadeWeb(CheckTask checkTask) {
        List<CheckTask> result = checkTaskMapper.selectCheckTaskListBrigadeWeb(checkTask);
        if (CollUtil.isNotEmpty(result)) {
            Date currentDate = getDateWithoutTime(DateUtils.getNowDate());
            result.forEach(item -> {
                if (currentDate.before(item.getCheckStartTime())) {
                    item.setStatus(CheckTaskStatusEnum.PENDING_EXECUTION.getCode());
                    item.setStatusDesc(CheckTaskStatusEnum.PENDING_EXECUTION.getDesc());
                } else if (currentDate.after(item.getCheckEndTime())) {
                    item.setStatus(CheckTaskStatusEnum.COMPLETED.getCode());
                    item.setStatusDesc(CheckTaskStatusEnum.COMPLETED.getDesc());
                } else {
                    item.setStatus(CheckTaskStatusEnum.IN_PROGRESS.getCode());
                    item.setStatusDesc(CheckTaskStatusEnum.IN_PROGRESS.getDesc());
                }
            });
            //是否已读处理
            checkIsRead(result);
        }
        return result;
    }

    /**
     * 转换为树形结构
     */
    public List<CheckProjectItemTreeVo> convertToTree(List<CheckProjectItemVo> itemList) {
        if (CollUtil.isEmpty(itemList)) {
            return Collections.emptyList();
        }
        List<CheckProjectItemTreeVo> result = new ArrayList<>();

        // 第一层分组：按一级分类
        Map<String, List<CheckProjectItemVo>> levelOneMap = itemList.stream()
                .collect(Collectors.groupingBy(CheckProjectItemVo::getCategoryCodeOne));


        // 处理一级分类
        for (Map.Entry<String, List<CheckProjectItemVo>> levelOneEntry : levelOneMap.entrySet()) {
            String levelOneCode = levelOneEntry.getKey();
            List<CheckProjectItemVo> levelOneItems = levelOneEntry.getValue();

            // 获取一级分类名称（取第一个元素的名称）
            String levelOneName = levelOneItems.get(0).getCategoryNameOne();

            // 创建一级节点
            CheckProjectItemTreeVo levelOneNode = new CheckProjectItemTreeVo();
            levelOneNode.setCode(levelOneCode);
            levelOneNode.setName(levelOneName);

            // 第二层分组：按二级分类
            Map<String, List<CheckProjectItemVo>> levelTwoMap = levelOneItems.stream()
                    .collect(Collectors.groupingBy(CheckProjectItemVo::getCategoryCodeTwo));

            List<CheckProjectItemTreeVo> levelTwoNodes = new ArrayList<>();

            // 处理二级分类
            for (Map.Entry<String, List<CheckProjectItemVo>> levelTwoEntry : levelTwoMap.entrySet()) {
                String levelTwoCode = levelTwoEntry.getKey();
                List<CheckProjectItemVo> levelTwoItems = levelTwoEntry.getValue();

                // 获取二级分类名称（取第一个元素的名称）
                String levelTwoName = levelTwoItems.get(0).getCategoryNameTwo();

                // 创建二级节点
                CheckProjectItemTreeVo levelTwoNode = new CheckProjectItemTreeVo();
                levelTwoNode.setCode(levelTwoCode);
                levelTwoNode.setName(levelTwoName);

                // 处理检查项目
                List<CheckProjectItemTreeVo> projectNodes = levelTwoItems.stream()
                        .map(item -> {
                            CheckProjectItemTreeVo projectNode = new CheckProjectItemTreeVo();
                            projectNode.setCode(item.getProjectCode());
                            projectNode.setName(item.getProjectName());
                            projectNode.setList(null); // 项目没有子节点
                            return projectNode;
                        })
                        .collect(Collectors.toList());

                levelTwoNode.setList(projectNodes);
                levelTwoNodes.add(levelTwoNode);
            }

            levelOneNode.setList(levelTwoNodes);
            result.add(levelOneNode);
        }
        return result;
    }

    /**
     * 获取日期的零时零分零秒
     *
     * @param date 日期
     * @return 零时零分零秒
     */
    private Date getDateWithoutTime(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

}
