package com.moka.gdtauto.controller;

import com.moka.gdtauto.common.Result;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.sql.DataSource;
import java.sql.Connection;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

/**
 * 健康检查控制器
 * 提供系统健康状态检查和详细监控信息
 * 
 * @author moka
 * @since 2026-02-03
 */
@Slf4j
@Tag(name = "系统监控", description = "系统健康检查和监控相关接口")
@RestController
@RequestMapping
public class HealthController {

    @Autowired(required = false)
    private DataSource dataSource;
    
    @Autowired(required = false)
    private RedisConnectionFactory redisConnectionFactory;
    
    @Value("${spring.application.name:gdt-auto}")
    private String appName;
    
    @Value("${spring.application.version:v1.0.0}")
    private String appVersion;

    @Operation(
        summary = "健康检查",
        description = "检查应用服务是否正常运行，返回OK表示服务正常"
    )
    @GetMapping("/health")
    public String health() {
        return "OK";
    }
    
    @Operation(
        summary = "详细健康检查",
        description = "获取详细的系统健康状态信息，包括数据库、Redis、JVM等"
    )
    @GetMapping("/health/detail")
    public Result<Map<String, Object>> healthDetail() {
        Map<String, Object> healthInfo = new HashMap<>();
        
        try {
            // 应用基本信息
            healthInfo.put("appName", appName);
            healthInfo.put("version", appVersion);
            healthInfo.put("timestamp", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            
            // 数据库健康检查
            healthInfo.put("database", checkDatabase());
            
            // Redis健康检查
            healthInfo.put("redis", checkRedis());
            
            // JVM信息
            healthInfo.put("jvm", getJvmInfo());
            
            // 系统状态
            healthInfo.put("status", "UP");
            healthInfo.put("message", "系统运行正常");
            
            log.info("健康检查完成: 系统运行正常");
            return Result.success(healthInfo);
            
        } catch (Exception e) {
            log.error("健康检查失败", e);
            healthInfo.put("status", "DOWN");
            healthInfo.put("message", "系统异常: " + e.getMessage());
            return Result.success(healthInfo);
        }
    }
    
    /**
     * 检查数据库连接
     */
    private Map<String, Object> checkDatabase() {
        Map<String, Object> dbInfo = new HashMap<>();
        
        try {
            if (dataSource != null) {
                try (Connection conn = dataSource.getConnection()) {
                    dbInfo.put("status", "UP");
                    dbInfo.put("message", "数据库连接正常");
                    dbInfo.put("url", conn.getMetaData().getURL());
                }
            } else {
                dbInfo.put("status", "UNKNOWN");
                dbInfo.put("message", "未配置数据源");
            }
        } catch (Exception e) {
            dbInfo.put("status", "DOWN");
            dbInfo.put("message", "数据库连接异常: " + e.getMessage());
        }
        
        return dbInfo;
    }
    
    /**
     * 检查Redis连接
     */
    private Map<String, Object> checkRedis() {
        Map<String, Object> redisInfo = new HashMap<>();
        
        try {
            if (redisConnectionFactory != null) {
                redisConnectionFactory.getConnection().ping();
                redisInfo.put("status", "UP");
                redisInfo.put("message", "Redis连接正常");
            } else {
                redisInfo.put("status", "UNKNOWN");
                redisInfo.put("message", "未配置Redis");
            }
        } catch (Exception e) {
            redisInfo.put("status", "DOWN");
            redisInfo.put("message", "Redis连接异常: " + e.getMessage());
        }
        
        return redisInfo;
    }
    
    /**
     * 获取JVM信息
     */
    private Map<String, Object> getJvmInfo() {
        Map<String, Object> jvmInfo = new HashMap<>();
        
        Runtime runtime = Runtime.getRuntime();
        jvmInfo.put("totalMemory", runtime.totalMemory());
        jvmInfo.put("freeMemory", runtime.freeMemory());
        jvmInfo.put("maxMemory", runtime.maxMemory());
        jvmInfo.put("usedMemory", runtime.totalMemory() - runtime.freeMemory());
        jvmInfo.put("availableProcessors", runtime.availableProcessors());
        jvmInfo.put("javaVersion", System.getProperty("java.version"));
        jvmInfo.put("javaVendor", System.getProperty("java.vendor"));
        jvmInfo.put("osName", System.getProperty("os.name"));
        jvmInfo.put("osVersion", System.getProperty("os.version"));
        
        return jvmInfo;
    }
}
