package cn.iocoder.yudao.module.system.controller.admin.biz.task;

import cn.iocoder.yudao.module.system.controller.admin.biz.vo.ExpenseOrderSaveVO;
import lombok.Data;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class TaskStatusManager {

    private final Map<String, TaskStatus> taskStatusMap = new ConcurrentHashMap<>();

    /**
     * 初始化任务状态
     */
    public String initTask(ExpenseOrderSaveVO saveVO) {
        String taskId = UUID.randomUUID().toString();
        TaskStatus status = new TaskStatus();
        status.setTaskId(taskId);
        status.setTenantId(saveVO.getTenantId());
        status.setBillingMonth(saveVO.getBillingMonth());
        status.setStatus("PROCESSING");
        status.setStartTime(System.currentTimeMillis());
        status.setProcessedCount(0);
        status.setTotalCount(0);
        status.setSuccessCount(0);
        status.setFailedCount(0);
        status.setSkippedCount(0);
        status.setConfirmCount(0);
        status.setDetails(new ArrayList<>());

        taskStatusMap.put(taskId, status);
        return taskId;
    }

    /**
     * 更新任务总数量
     */
    public void updateTotalCount(String taskId, int totalCount) {
        TaskStatus status = taskStatusMap.get(taskId);
        if (status != null) {
            status.setTotalCount(totalCount);
        }
    }

    /**
     * 添加处理详情
     */
    public void addProcessDetail(String taskId, Long elderId,String elderName, String result,String message) {
        TaskStatus status = taskStatusMap.get(taskId);
        if (status != null) {
            TaskProcessDetail detail = new TaskProcessDetail();
            detail.setElderId(elderId);
            detail.setElderName(elderName);
            detail.setResult(result); // SUCCESS, FAILED, SKIPPED, CONFIRM
            detail.setMessage(message);
            detail.setProcessTime(System.currentTimeMillis());
            // 更新计数
            status.setProcessedCount(status.getProcessedCount() + 1);
            switch (result) {
                case "SUCCESS":
                    status.setSuccessCount(status.getSuccessCount() + 1);
                    break;
                case "FAILED":
                    status.getDetails().add(detail);
                    status.setFailedCount(status.getFailedCount() + 1);
                    break;
                case "SKIPPED":
                    status.getDetails().add(detail);
                    status.setSkippedCount(status.getSkippedCount() + 1);
                    break;
                case "CONFIRM":
                    status.getDetails().add(detail);
                    status.setConfirmCount(status.getConfirmCount() + 1);
                    break;
            }
        }
    }

    /**
     * 完成任务
     */
    public void completeTask(String taskId) {
        TaskStatus status = taskStatusMap.get(taskId);
        if (status != null) {
            status.setStatus("COMPLETED");
            status.setEndTime(System.currentTimeMillis());
        }
    }

    /**
     * 任务失败
     */
    public void failTask(String taskId, String errorMessage) {
        TaskStatus status = taskStatusMap.get(taskId);
        if (status != null) {
            status.setStatus("FAILED");
            status.setErrorMessage(errorMessage);
            status.setEndTime(System.currentTimeMillis());
        }
    }

    /**
     * 获取任务状态
     */
    public TaskStatus getTaskStatus(String taskId) {
        return taskStatusMap.get(taskId);
    }

    /**
     * 清理过期任务（可选）
     */
    public void cleanupExpiredTasks() {
        long now = System.currentTimeMillis();
        taskStatusMap.entrySet().removeIf(entry -> {
            TaskStatus status = entry.getValue();
            return status.getEndTime() != null &&
                    (now - status.getEndTime()) > 24 * 60 * 60 * 1000; // 24小时
        });
    }

    @Data
    public static class TaskStatus {
        private String taskId;
        private Long tenantId;
        private String billingMonth;
        private String status; // PROCESSING, COMPLETED, FAILED
        private Long startTime;
        private Long endTime;
        private Integer totalCount;
        private Integer processedCount;
        private Integer successCount;
        private Integer failedCount;
        private Integer skippedCount;
        private Integer confirmCount;
        private String errorMessage;
        private List<TaskProcessDetail> details;
    }

    @Data
    public static class TaskProcessDetail {
        private Long elderId;
        private String elderName;
        private String result; // SUCCESS, FAILED, SKIPPED
        private String message;
        private Long processTime;
    }
}
