/**
 * Copyright &copy; 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
 */
package com.jeeplus.flowable.controller;

import com.jeeplus.flowable.service.FlowArchiveService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
 * 流程数据归档控制器
 * 提供REST接口供XXL-Job或其他定时任务调用，触发历史数据从热表迁移到冷表
 *
 * @author jeeplus
 * @version 2024-01-01
 */
@Slf4j
@RestController
@RequestMapping("/flow/archive")
public class FlowArchiveController {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private FlowArchiveService flowArchiveService;

    /**
     * 触发数据归档迁移
     * 通过Java代码实现，将3个月前已结束的流程数据从热表迁移到冷表
     * XXL-Job配置: HTTP GET /flow/archive/trigger
     *
     * @return 迁移结果
     */
    @GetMapping("/trigger")
    public Map<String, Object> triggerArchive() {
        Map<String, Object> result = new HashMap<>();
        try {
            log.info("开始执行流程数据归档...");
            Map<String, Object> archiveResult = flowArchiveService.executeArchive();
            log.info("流程数据归档执行完成: {}", archiveResult);
            result.put("code", 200);
            result.put("msg", "归档执行成功");
            result.put("data", archiveResult);
        } catch (Exception e) {
            log.error("流程数据归档执行失败", e);
            result.put("code", 500);
            result.put("msg", "归档执行失败: " + e.getMessage());
        }
        return result;
    }

    /**
     * 查看归档统计信息
     */
    @GetMapping("/stats")
    public Map<String, Object> getArchiveStats() {
        Map<String, Object> result = new HashMap<>();
        try {
            Map<String, Object> stats = new HashMap<>();
            stats.put("hot_procinst", jdbcTemplate.queryForObject("SELECT COUNT(*) FROM act_hi_procinst", Integer.class));
            stats.put("archive_procinst", jdbcTemplate.queryForObject("SELECT COUNT(*) FROM act_hi_procinst_archive", Integer.class));
            stats.put("hot_actinst", jdbcTemplate.queryForObject("SELECT COUNT(*) FROM act_hi_actinst", Integer.class));
            stats.put("archive_actinst", jdbcTemplate.queryForObject("SELECT COUNT(*) FROM act_hi_actinst_archive", Integer.class));
            stats.put("hot_varinst", jdbcTemplate.queryForObject("SELECT COUNT(*) FROM act_hi_varinst", Integer.class));
            stats.put("archive_varinst", jdbcTemplate.queryForObject("SELECT COUNT(*) FROM act_hi_varinst_archive", Integer.class));
            stats.put("hot_taskinst", jdbcTemplate.queryForObject("SELECT COUNT(*) FROM act_hi_taskinst", Integer.class));
            stats.put("archive_taskinst", jdbcTemplate.queryForObject("SELECT COUNT(*) FROM act_hi_taskinst_archive", Integer.class));

            // 最近一次归档日志
            Map<String, Object> lastLog = null;
            try {
                lastLog = jdbcTemplate.queryForList("SELECT * FROM flow_archive_log ORDER BY archive_time DESC LIMIT 1").stream()
                        .findFirst().orElse(null);
            } catch (Exception ignored) {
                // flow_archive_log表可能还未创建
            }

            result.put("code", 200);
            result.put("stats", stats);
            result.put("lastArchiveLog", lastLog);
        } catch (Exception e) {
            result.put("code", 500);
            result.put("msg", "查询失败: " + e.getMessage());
        }
        return result;
    }
}
