package com.mosquito.project.permission;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 审批流服务
 */
@Service
public class ApprovalFlowService {

    // 审批状态常量
    public static final String STATUS_PENDING = "PENDING";
    public static final String STATUS_APPROVED = "APPROVED";
    public static final String STATUS_REJECTED = "REJECTED";
    public static final String STATUS_PROCESSING = "PROCESSING";
    public static final String STATUS_CANCELLED = "CANCELLED";

    // 审批动作
    public static final String ACTION_SUBMIT = "SUBMIT";
    public static final String ACTION_APPROVE = "APPROVE";
    public static final String ACTION_REJECT = "REJECT";
    public static final String ACTION_TRANSFER = "TRANSFER";

    private final ApprovalFlowRepository flowRepository;
    private final ApprovalRecordRepository recordRepository;
    private final ApprovalHistoryRepository historyRepository;
    private final ObjectMapper objectMapper;

    public ApprovalFlowService(
            ApprovalFlowRepository flowRepository,
            ApprovalRecordRepository recordRepository,
            ApprovalHistoryRepository historyRepository,
            ObjectMapper objectMapper) {
        this.flowRepository = flowRepository;
        this.recordRepository = recordRepository;
        this.historyRepository = historyRepository;
        this.objectMapper = objectMapper;
    }

    /**
     * 提交审批申请
     */
    @Transactional
    public Map<String, Object> submitApproval(Long flowId, String bizType, Long bizId,
                                               String title, Long applicantId, String applyReason) {
        // 获取审批流程配置
        Optional<SysApprovalFlow> flowOpt = flowRepository.findById(flowId);
        if (!flowOpt.isPresent()) {
            throw new IllegalArgumentException("审批流程不存在: " + flowId);
        }

        SysApprovalFlow flow = flowOpt.get();
        if (!"ENABLED".equals(flow.getStatus())) {
            throw new IllegalArgumentException("审批流程已禁用");
        }

        // 检查是否已有待处理的审批
        List<SysApprovalRecord> existing = recordRepository.findByBizTypeAndBizId(bizType, bizId);
        for (SysApprovalRecord record : existing) {
            if (STATUS_PENDING.equals(record.getStatus()) || STATUS_PROCESSING.equals(record.getStatus())) {
                throw new IllegalArgumentException("该业务已存在待处理的审批申请");
            }
        }

        // 解析审批节点，获取第一个审批人
        Long firstApproverId = resolveFirstApprover(flow, applicantId);

        // 创建审批记录
        SysApprovalRecord record = new SysApprovalRecord();
        record.setFlowId(flowId);
        record.setBizType(bizType);
        record.setBizId(bizId);
        record.setCurrentNode(0);
        record.setApplicantId(applicantId);
        record.setCurrentApproverId(firstApproverId);
        record.setStatus(STATUS_PROCESSING);
        record.setCreatedAt(LocalDateTime.now());
        record.setUpdatedAt(LocalDateTime.now());

        record = recordRepository.save(record);

        // 记录审批历史
        SysApprovalHistory history = new SysApprovalHistory();
        history.setRecordId(record.getId());
        history.setNodeIndex(0);
        history.setApproverId(applicantId);
        history.setAction(ACTION_SUBMIT);
        history.setComment(applyReason);
        history.setCreatedAt(LocalDateTime.now());
        historyRepository.save(history);

        Map<String, Object> result = new HashMap<>();
        result.put("recordId", record.getId());
        result.put("status", record.getStatus());
        result.put("currentNode", record.getCurrentNode());
        result.put("currentApproverId", firstApproverId);
        return result;
    }

    /**
     * 通过触发事件提交审批
     */
    @Transactional
    public Map<String, Object> submitApprovalByEvent(String triggerEvent, String bizType, Long bizId,
                                                      String title, Long applicantId, String applyReason) {
        Optional<SysApprovalFlow> flowOpt = flowRepository.findByTriggerEventAndStatus(triggerEvent, "ENABLED");
        if (!flowOpt.isPresent()) {
            throw new IllegalArgumentException("未找到触发事件对应的审批流程: " + triggerEvent);
        }
        return submitApproval(flowOpt.get().getId(), bizType, bizId, title, applicantId, applyReason);
    }

    /**
     * 处理审批
     */
    @Transactional
    public Map<String, Object> handleApproval(Long recordId, String action, Long operatorId, String comment) {
        Optional<SysApprovalRecord> recordOpt = recordRepository.findById(recordId);
        if (!recordOpt.isPresent()) {
            throw new IllegalArgumentException("审批记录不存在: " + recordId);
        }

        SysApprovalRecord record = recordOpt.get();
        if (!STATUS_PROCESSING.equals(record.getStatus())) {
            throw new IllegalArgumentException("审批记录状态不是处理中: " + record.getStatus());
        }

        // 验证审批人权限
        if (!operatorId.equals(record.getCurrentApproverId())) {
            throw new IllegalArgumentException("您不是当前审批人，无权处理此审批");
        }

        // 获取流程配置
        Optional<SysApprovalFlow> flowOpt = flowRepository.findById(record.getFlowId());
        if (!flowOpt.isPresent()) {
            throw new IllegalArgumentException("审批流程配置不存在");
        }
        SysApprovalFlow flow = flowOpt.get();

        // 解析节点配置
        List<Map<String, Object>> nodes = parseNodes(flow.getNodes());
        int currentNode = record.getCurrentNode();

        // 记录审批历史
        SysApprovalHistory history = new SysApprovalHistory();
        history.setRecordId(recordId);
        history.setNodeIndex(currentNode);
        history.setApproverId(operatorId);
        history.setAction(action);
        history.setComment(comment);
        history.setCreatedAt(LocalDateTime.now());
        historyRepository.save(history);

        Map<String, Object> result = new HashMap<>();

        if (ACTION_APPROVE.equals(action)) {
            // 批准 - 检查是否还有下一个节点
            if (currentNode + 1 >= nodes.size()) {
                // 审批完成
                record.setStatus(STATUS_APPROVED);
                record.setUpdatedAt(LocalDateTime.now());
                recordRepository.save(record);
                result.put("status", STATUS_APPROVED);
                result.put("message", "审批已通过");
            } else {
                // 进入下一个节点
                int nextNode = currentNode + 1;
                Long nextApproverId = resolveNextApprover(nodes, nextNode, record);
                record.setCurrentNode(nextNode);
                record.setCurrentApproverId(nextApproverId);
                record.setUpdatedAt(LocalDateTime.now());
                recordRepository.save(record);
                result.put("status", STATUS_PROCESSING);
                result.put("currentNode", nextNode);
                result.put("currentApproverId", nextApproverId);
                result.put("message", "已提交给下一审批人");
            }
        } else if (ACTION_REJECT.equals(action)) {
            // 拒绝
            record.setStatus(STATUS_REJECTED);
            record.setUpdatedAt(LocalDateTime.now());
            recordRepository.save(record);
            result.put("status", STATUS_REJECTED);
            result.put("message", "审批已拒绝");
        } else if (ACTION_TRANSFER.equals(action)) {
            // 转交
            // 转交目标ID在comment中传递，格式: "transfer:userId"
            if (comment != null && comment.startsWith("transfer:")) {
                Long transferToId = Long.parseLong(comment.substring(9));
                record.setCurrentApproverId(transferToId);
                record.setUpdatedAt(LocalDateTime.now());
                recordRepository.save(record);
                result.put("status", STATUS_PROCESSING);
                result.put("currentApproverId", transferToId);
                result.put("message", "已转交给其他审批人");
            } else {
                throw new IllegalArgumentException("转交操作需要指定目标审批人，格式: transfer:userId");
            }
        } else {
            throw new IllegalArgumentException("无效的审批动作: " + action);
        }

        return result;
    }

    /**
     * 获取待审批列表
     */
    public List<SysApprovalRecord> getPendingApprovals(Long userId) {
        return recordRepository.findPendingByApproverId(userId);
    }

    /**
     * 获取已审批列表（我审批过的）
     */
    public List<SysApprovalRecord> getApprovedList(Long userId) {
        return recordRepository.findProcessedByApplicantId(userId);
    }

    /**
     * 获取我发起的审批
     */
    public List<SysApprovalRecord> getMyApplications(Long userId) {
        return recordRepository.findByApplicantId(userId);
    }

    /**
     * 获取审批记录详情
     */
    public Map<String, Object> getRecordById(Long recordId) {
        Optional<SysApprovalRecord> recordOpt = recordRepository.findById(recordId);
        if (!recordOpt.isPresent()) {
            return null;
        }

        SysApprovalRecord record = recordOpt.get();
        Map<String, Object> result = new HashMap<>();
        result.put("id", record.getId());
        result.put("flowId", record.getFlowId());
        result.put("bizType", record.getBizType());
        result.put("bizId", record.getBizId());
        result.put("currentNode", record.getCurrentNode());
        result.put("applicantId", record.getApplicantId());
        result.put("status", record.getStatus());
        result.put("currentApproverId", record.getCurrentApproverId());
        result.put("createdAt", record.getCreatedAt());
        result.put("updatedAt", record.getUpdatedAt());

        // 获取流程信息
        Optional<SysApprovalFlow> flowOpt = flowRepository.findById(record.getFlowId());
        if (flowOpt.isPresent()) {
            SysApprovalFlow flow = flowOpt.get();
            result.put("flowName", flow.getFlowName());
            result.put("flowCode", flow.getFlowCode());
        }

        // 获取审批历史
        List<SysApprovalHistory> histories = historyRepository.findByRecordIdOrderByNodeIndexDesc(recordId);
        result.put("history", histories);

        return result;
    }

    /**
     * 获取审批历史
     */
    public List<SysApprovalHistory> getApprovalHistory(Long recordId) {
        return historyRepository.findByRecordIdOrderByNodeIndexDesc(recordId);
    }

    /**
     * 取消审批
     */
    @Transactional
    public boolean cancelApproval(Long recordId, Long operatorId) {
        Optional<SysApprovalRecord> recordOpt = recordRepository.findById(recordId);
        if (!recordOpt.isPresent()) {
            throw new IllegalArgumentException("审批记录不存在: " + recordId);
        }

        SysApprovalRecord record = recordOpt.get();
        if (!operatorId.equals(record.getApplicantId())) {
            throw new IllegalArgumentException("只有申请人可以取消审批");
        }

        if (!STATUS_PROCESSING.equals(record.getStatus())) {
            throw new IllegalArgumentException("只有处理中的审批可以取消");
        }

        record.setStatus(STATUS_CANCELLED);
        record.setUpdatedAt(LocalDateTime.now());
        recordRepository.save(record);
        return true;
    }

    /**
     * 获取所有审批流程配置
     */
    public List<SysApprovalFlow> getAllFlows() {
        return flowRepository.findAll();
    }

    /**
     * 获取启用的审批流程
     */
    public List<SysApprovalFlow> getEnabledFlows() {
        return flowRepository.findByStatus("ENABLED");
    }

    /**
     * 解析节点配置JSON
     */
    @SuppressWarnings("unchecked")
    private List<Map<String, Object>> parseNodes(String nodesJson) {
        try {
            return objectMapper.readValue(nodesJson, List.class);
        } catch (JsonProcessingException e) {
            throw new IllegalArgumentException("审批节点配置解析失败", e);
        }
    }

    /**
     * 解析第一个审批人
     */
    private Long resolveFirstApprover(SysApprovalFlow flow, Long applicantId) {
        List<Map<String, Object>> nodes = parseNodes(flow.getNodes());
        if (nodes.isEmpty()) {
            throw new IllegalArgumentException("审批流程节点配置为空");
        }
        return resolveApproverFromNode(nodes.get(0), applicantId);
    }

    /**
     * 解析下一个审批人
     */
    private Long resolveNextApprover(List<Map<String, Object>> nodes, int nodeIndex, SysApprovalRecord record) {
        if (nodeIndex >= nodes.size()) {
            return null;
        }
        return resolveApproverFromNode(nodes.get(nodeIndex), record.getApplicantId());
    }

    /**
     * 从节点配置中解析审批人
     */
    @SuppressWarnings("unchecked")
    private Long resolveApproverFromNode(Map<String, Object> node, Long applicantId) {
        String approverType = (String) node.get("approverType");
        if ("SELF".equals(approverType)) {
            return applicantId;
        } else if ("ROLE".equals(approverType)) {
            // 根据角色ID查找用户（这里需要UserRoleService，暂时返回null）
            return null;
        } else if ("DEPARTMENT_HEAD".equals(approverType)) {
            // 查找部门负责人（需要DepartmentService，暂时返回null）
            return null;
        } else if ("SPECIFIC".equals(approverType)) {
            // 指定用户
            Object approverId = node.get("approverId");
            if (approverId != null) {
                return ((Number) approverId).longValue();
            }
        }
        // 默认返回null，需要手动分配
        return null;
    }
}
