package com.qqchen.deploy.backend.schedule.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.qqchen.deploy.backend.framework.utils.RedisUtil;
import com.qqchen.deploy.backend.schedule.dto.JobStatusDTO;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * 任务状态Redis服务
 * 
 * @author qichen
 */
@Slf4j
@Service
public class JobStatusRedisService {

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private ObjectMapper objectMapper;

    private static final String JOB_STATUS_KEY_PREFIX = "schedule:job:status:";
    private static final String ALL_STATUS_KEY = "schedule:job:status:all";
    private static final String VERSION_KEY = "schedule:job:status:version";
    private static final long STATUS_EXPIRE_SECONDS = 3600; // 1小时

    /**
     * 保存任务状态到Redis
     */
    public void saveJobStatus(Long jobId, JobStatusDTO status) {
        try {
            String key = JOB_STATUS_KEY_PREFIX + jobId;

            Map<String, Object> statusMap = new HashMap<>();
            statusMap.put("jobId", jobId);
            statusMap.put("jobName", status.getJobName() != null ? status.getJobName() : "");
            statusMap.put("status", status.getStatus());
            statusMap.put("progress", status.getProgress() != null ? status.getProgress() : 0);
            statusMap.put("currentStep", status.getCurrentStep() != null ? status.getCurrentStep() : "");
            statusMap.put("message", status.getMessage() != null ? status.getMessage() : "");
            statusMap.put("startTime", status.getStartTime() != null ? status.getStartTime().toString() : "");
            statusMap.put("updateTime", LocalDateTime.now().toString());

            // 保存到单独的key（1小时过期）
            redisUtil.hmset(key, statusMap, STATUS_EXPIRE_SECONDS);

            // 同时更新到all hash
            String statusJson = objectMapper.writeValueAsString(statusMap);
            redisUtil.hset(ALL_STATUS_KEY, jobId.toString(), statusJson);

            // 增加版本号
            redisUtil.incr(VERSION_KEY, 1);

            log.debug("保存任务状态到Redis: jobId={}, status={}", jobId, status.getStatus());

        } catch (Exception e) {
            log.error("保存任务状态到Redis失败: jobId={}", jobId, e);
        }
    }

    /**
     * 获取单个任务状态
     */
    public JobStatusDTO getJobStatus(Long jobId) {
        try {
            String key = JOB_STATUS_KEY_PREFIX + jobId;
            Map<Object, Object> statusMap = redisUtil.hmget(key);

            if (statusMap.isEmpty()) {
                return null;
            }

            return JobStatusDTO.builder()
                    .jobId(Long.parseLong(statusMap.get("jobId").toString()))
                    .jobName((String) statusMap.get("jobName"))
                    .status((String) statusMap.get("status"))
                    .progress(Integer.parseInt(statusMap.get("progress").toString()))
                    .currentStep((String) statusMap.get("currentStep"))
                    .message((String) statusMap.get("message"))
                    .updateTime((String) statusMap.get("updateTime"))
                    .build();

        } catch (Exception e) {
            log.error("从Redis获取任务状态失败: jobId={}", jobId, e);
            return null;
        }
    }

    /**
     * 批量获取所有任务状态
     */
    public Map<String, JobStatusDTO> getAllJobStatus() {
        try {
            Map<Object, Object> allStatus = redisUtil.hmget(ALL_STATUS_KEY);
            Map<String, JobStatusDTO> result = new HashMap<>();

            for (Map.Entry<Object, Object> entry : allStatus.entrySet()) {
                String jobId = entry.getKey().toString();
                String statusJson = entry.getValue().toString();

                @SuppressWarnings("unchecked")
                Map<String, Object> statusMap = objectMapper.readValue(statusJson, Map.class);

                JobStatusDTO dto = JobStatusDTO.builder()
                        .jobId(Long.parseLong(jobId))
                        .jobName((String) statusMap.get("jobName"))
                        .status((String) statusMap.get("status"))
                        .progress((Integer) statusMap.get("progress"))
                        .currentStep((String) statusMap.get("currentStep"))
                        .message((String) statusMap.get("message"))
                        .updateTime((String) statusMap.get("updateTime"))
                        .build();

                result.put(jobId, dto);
            }

            return result;

        } catch (Exception e) {
            log.error("从Redis批量获取任务状态失败", e);
            return new HashMap<>();
        }
    }

    /**
     * 获取当前状态版本号
     */
    public Long getStatusVersion() {
        Object version = redisUtil.get(VERSION_KEY);
        return version != null ? Long.parseLong(version.toString()) : 0L;
    }

    /**
     * 删除任务状态
     */
    public void deleteJobStatus(Long jobId) {
        String key = JOB_STATUS_KEY_PREFIX + jobId;
        redisUtil.del(key);
        redisUtil.hdel(ALL_STATUS_KEY, jobId.toString());
    }
}

