package com.hotent.project.manager.impl;

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.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hotent.base.manager.impl.BaseManagerImpl;
import com.hotent.base.model.CommonResult;
import com.hotent.base.util.StringUtil;
import com.hotent.baseInfo.req.CostTaskSearchReq;
import com.hotent.constant.BaseConstant;
import com.hotent.constant.NodeConstant;
import com.hotent.constant.TaskStatusConstant;
import com.hotent.enterpriseDeclare.req.CostTaskPageReq;
import com.hotent.enterpriseDeclare.req.CostTaskReviewPageReq;
import com.hotent.project.dao.CostProjectTaskDao;
import com.hotent.project.manager.CostNoticeManager;
import com.hotent.project.manager.CostProjectApprovalManager;
import com.hotent.project.manager.CostProjectTaskManager;
import com.hotent.project.manager.CostProjectTaskProccessManager;
import com.hotent.project.model.CostProjectApproval;
import com.hotent.project.model.CostProjectTask;
import com.hotent.project.model.CostProjectTaskProccess;
import com.hotent.uc.api.model.IUser;
import com.hotent.uc.util.ContextUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;


/**
 * 项目任务表 服务实现类
 *
 * @author 超级管理员
 * @company 山西清众科技股份有限公司
 * @since 2025-10-03
 */
@Service
public class CostProjectTaskManagerImpl extends BaseManagerImpl<CostProjectTaskDao, CostProjectTask> implements CostProjectTaskManager {


    @Autowired
    private CostProjectTaskProccessManager costProjectTaskProccessManager;

    @Autowired
    private CostProjectTaskManager costProjectTaskManager;

    @Autowired
    private CostNoticeManager costNoticeManager;

    @Autowired
    private CostProjectApprovalManager costProjectApprovalManager;


    @Override
    public List<CostProjectTask> getTaskList(CostTaskSearchReq req) {
        LambdaQueryWrapper<CostProjectTask> queryWrapper = new LambdaQueryWrapper<>();
        if (ObjectUtil.isNotEmpty(req.getYear())) {
            queryWrapper.eq(CostProjectTask::getYear, req.getYear());
        }
        if (ObjectUtil.isNotEmpty(req.getProjectName())) {
            queryWrapper.like(CostProjectTask::getProjectName, req.getProjectName());
        }
        queryWrapper.eq(CostProjectTask::getIsDeleted, BaseConstant.NORMAL_STATUS);
        return this.list(queryWrapper);
    }

    @Override
    public IPage<CostProjectTask> pageListForReviewTask(CostTaskReviewPageReq req) {
        // 获取当前用户
        IUser currentUser = ContextUtil.getCurrentUser();
        String currentUserId = currentUser.getUserId();

        // 1. 先查询当前用户有权限的立项（负责人或项目组成员）
        LambdaQueryWrapper<CostProjectApproval> approvalQueryWrapper = new LambdaQueryWrapper<>();
        approvalQueryWrapper.eq(CostProjectApproval::getIsDeleted, "0");
        approvalQueryWrapper.and(wrapper -> wrapper
                .eq(CostProjectApproval::getLeaderId, currentUserId)
                .or(projectMembersWrapper -> {
                    projectMembersWrapper.like(CostProjectApproval::getProjectMembers, currentUserId);
                })
        );

        List<CostProjectApproval> accessibleApprovals = costProjectApprovalManager.list(approvalQueryWrapper);

        // 如果没有权限的立项，返回空结果
        if (accessibleApprovals.isEmpty()) {
            return new Page<>(req.getPageNum(), req.getPageSize());
        }

        // 提取有权限的立项ID列表
        List<String> accessibleProjectIds = accessibleApprovals.stream()
                .map(CostProjectApproval::getProjectId)
                .distinct()
                .collect(java.util.stream.Collectors.toList());

        // 2. 构建任务查询条件
        LambdaQueryWrapper<CostProjectTask> queryWrapper = new LambdaQueryWrapper<>();

        // 查询未删除的记录
        queryWrapper.eq(CostProjectTask::getIsDeleted, "0");

        // 查询根任务（pid为0）
        queryWrapper.eq(CostProjectTask::getPid, "0");

        // 只查询当前用户有权限的立项对应的任务
        queryWrapper.in(CostProjectTask::getProjectId, accessibleProjectIds);

        // 根据请求参数添加查询条件
        if (StringUtil.isNotEmpty(req.getProjectName())) {
            queryWrapper.like(CostProjectTask::getProjectName, req.getProjectName());
        }
        if (StringUtil.isNotEmpty(req.getStatus())) {
            queryWrapper.eq(CostProjectTask::getStatus, req.getStatus());
        }
        if (StringUtil.isNotEmpty(req.getCurrentNode())) {
            queryWrapper.eq(CostProjectTask::getCurrentNode, req.getCurrentNode());
        }

        // 按创建时间倒序排列
        queryWrapper.orderByDesc(CostProjectTask::getCreateTime);

        // 创建分页对象并执行查询
        Page<CostProjectTask> page = new Page<>(req.getPageNum(), req.getPageSize());
        IPage<CostProjectTask> result = costProjectTaskManager.page(page, queryWrapper);

        // 填充根任务的子任务列表和流程信息
        for (CostProjectTask rootTask : result.getRecords()) {
            // 查询子任务列表
            LambdaQueryWrapper<CostProjectTask> childQueryWrapper = new LambdaQueryWrapper<>();
            childQueryWrapper.eq(CostProjectTask::getPid, rootTask.getId())
                    .eq(CostProjectTask::getIsDeleted, "0")
                    .orderByAsc(CostProjectTask::getOrderNum);

            List<CostProjectTask> childTasks = costProjectTaskManager.list(childQueryWrapper);
            for (CostProjectTask childTask : childTasks) {
                childTask.setStatus(TaskStatusConstant.getStatusNameByCode(childTask.getStatus()));
            }
            rootTask.setChildTasks(childTasks);
            rootTask.setCurrentNodeName(NodeConstant.getNodeValueByKey(rootTask.getCurrentNode()));
        }

        return result;
    }

    @Override
    @Transactional
    public void createOrUpdate(CostProjectTask costProjectTask) {
        //新建或更新
        this.saveOrUpdate(costProjectTask);
    }

    @Override
    @Transactional
    public String saveTask(CostTaskPageReq costTaskPageReq) {

        // 1.校验内容是否填写完毕！todo

        // 2. 流程阶段变为资料初审
        CostProjectTaskProccess taskProccess = costProjectTaskProccessManager.getOne(
                new QueryWrapper<CostProjectTaskProccess>()
                        .eq("task_id", costTaskPageReq.getTaskId())
        );
        taskProccess.setCurrentNode(NodeConstant.clcs.getNodeKey());
        costProjectTaskProccessManager.updateById(taskProccess);

        // 3. 子流程状态改为审核中
        CostProjectTask task = this.getById(costTaskPageReq.getTaskId());
        task.setCurrentNode(NodeConstant.clcs.getNodeKey());
        task.setStatus(TaskStatusConstant.AUDITING.getStatusCode());
        this.updateById(task);

        return "任务提交成功，已进入材料初审阶段";
    }

    @Override
    public String doProcessBtn(CostTaskPageReq req) {

        CostProjectTask task = costProjectTaskManager.getById(req.getTaskId());
        String resultMessage = "";
        switch (req.getKey()) {
            case "1":
                // 补充材料
                resultMessage = supplementMaterial(task, req);
                break;
            case "2":
                // 中止
                resultMessage = suspendTask(task,req);
                break;
            case "3":
                // 通过
                resultMessage = completeTask(task);
                break;
            case "4":
                // 退回
                resultMessage = returnToSubmit(task,req);
                break;
            default:
                return "未知的操作类型";
        }
        return resultMessage;
    }

    /**
     * 通过，只修改状态，节点变化需要等待所有子任务完成。
     */
    private String completeTask(CostProjectTask task) {
        NodeConstant nextNode = NodeConstant.getNextNode(task.getCurrentNode());
        if (nextNode == null){
            return "当前节点无法通过";
        }
        // 将当前任务置为办结
        String nextNodeStatus = nextNode.getNodeKey();
        task.setStatus(TaskStatusConstant.COMPLETED.getStatusCode());
        task.setCurrentNode(nextNodeStatus);
        costProjectTaskManager.updateById(task);

        // 材料初审通过通知
        String title = nextNodeStatus+"通过";
        String auditedUnit = task.getAuditedUnitName() == null ? "" : task.getAuditedUnitName();
        String projectName = task.getProjectName() == null ? "" : task.getProjectName();
        String year = task.getYear() == null ? "" : task.getYear();
        String content = String.format("%s%s%s%s。", year, projectName, auditedUnit,title);
        String enterpriseId = task.getAuditedUnitId() == null ? "" : task.getAuditedUnitId();
        String noticeSource = "系统";
        String sendTarget = task.getCreateBy() == null ? "" : task.getCreateBy();
        costNoticeManager.sendNotice(task.getProjectId(), "1", title, content, enterpriseId, noticeSource, sendTarget);


        // 检查同一父任务下是否所有子任务均已办结；若是，父任务节点流转
        List<CostProjectTask> siblingTasks = costProjectTaskManager.list(
                new LambdaQueryWrapper<CostProjectTask>()
                        .eq(CostProjectTask::getPid, task.getPid())
                        .eq(CostProjectTask::getIsDeleted, "0")
        );

        boolean allSiblingsCompleted = true;
        for (CostProjectTask s : siblingTasks) {
            if (!TaskStatusConstant.COMPLETED.getStatusCode().equals(s.getStatus())) {
                allSiblingsCompleted = false;
                break;
            }
        }

        if (allSiblingsCompleted) {
            CostProjectTask parentTask = costProjectTaskManager.getById(task.getPid());
            if (parentTask != null) {
                CostProjectTaskProccess parentProccess = costProjectTaskProccessManager.getOne(
                        new LambdaQueryWrapper<CostProjectTaskProccess>()
                                .eq(CostProjectTaskProccess::getTaskId, parentTask.getId())
                );
                // 将父任务流转到下一步
                parentTask.setCurrentNode(NodeConstant.getNextNode(task.getCurrentNode()).getNodeKey());
                costProjectTaskManager.updateById(parentTask);
                if (parentProccess != null) {
                    parentProccess.setCurrentNode(NodeConstant.getNextNode(task.getCurrentNode()).getNodeKey());
                    costProjectTaskProccessManager.updateById(parentProccess);
                }
            }
        }

        return title;
    }

    /**
     * 退回，填写退回原因 修改状态
     */
    private String returnToSubmit(CostProjectTask task,CostTaskPageReq req) {
        NodeConstant nextNode = NodeConstant.getNextNode(task.getCurrentNode());
        if (nextNode == null){
            return "当前节点无法通过";
        }
        // 将当前任务置为办结
        String nextNodeStatus = nextNode.getNodeKey();
        // 通知内容组装
        String title = nextNodeStatus+"退回";
        String enterpriseId = task.getAuditedUnitId() == null ? "" : task.getAuditedUnitId();
        String noticeSource = "系统";
        String sendTarget = task.getCreateBy() == null ? "" : task.getCreateBy();
        costNoticeManager.sendNotice(task.getProjectId(), "1", title, req.getContent(), enterpriseId, noticeSource, sendTarget);

        // 更新任务的当前节点和状态
        task.setCurrentNode(nextNodeStatus);
        task.setStatus(TaskStatusConstant.WAIT_SUBMIT.getStatusCode());
        costProjectTaskManager.updateById(task);

        return title;
    }

    /**
     * 中止，填写中止原因 只修改状态
     */
    private String suspendTask(CostProjectTask task,CostTaskPageReq req) {
        NodeConstant nextNode = NodeConstant.getNextNode(task.getCurrentNode());
        if (nextNode == null){
            return "当前节点无法通过";
        }
        // 将当前任务置为办结
        String nextNodeStatus = nextNode.getNodeKey();

        // 更新任务状态为中止
        task.setStatus(TaskStatusConstant.SUSPENDED.getStatusCode());
        costProjectTaskManager.updateById(task);

        // 通知内容组装
        String title = nextNodeStatus+"中止";
        String enterpriseId = task.getAuditedUnitId() == null ? "" : task.getAuditedUnitId();
        String noticeSource = "系统";
        String sendTarget = task.getCreateBy() == null ? "" : task.getCreateBy();
        costNoticeManager.sendNotice(task.getProjectId(), "1", title, req.getContent(), enterpriseId, noticeSource, sendTarget);

        // 更新流程阶段为中止
        CostProjectTaskProccess taskProccess = costProjectTaskProccessManager.getOne(
                new LambdaQueryWrapper<CostProjectTaskProccess>()
                        .eq(CostProjectTaskProccess::getTaskId, task.getId())
        );
        if (taskProccess != null) {
            costProjectTaskProccessManager.updateById(taskProccess);
        }

        return title;
    }

    /**
     * 补充材料，仅发送通知，不修改任务状态或节点
     */
    private String supplementMaterial(CostProjectTask task, CostTaskPageReq req) {
        // 通知内容组装
        String title = "补充材料通知";
        String enterpriseId = task.getAuditedUnitId() == null ? "" : task.getAuditedUnitId();
        String noticeSource = "系统";
        String sendTarget = task.getCreateBy() == null ? "" : task.getCreateBy();
        costNoticeManager.sendNotice(task.getProjectId(), "1", title, req.getContent(), enterpriseId, noticeSource, sendTarget);

        return "补充材料通知已发送";
    }

}
