package handler

import (
	"context"
	"time"

	"github.com/gofiber/fiber/v2"
	"github.com/redis/go-redis/v9"
	"go.uber.org/zap"
	"gorm.io/gorm"

	"github.com/break/junhong_cmp_fiber/pkg/response"
)

// HealthHandler 健康检查处理器
type HealthHandler struct {
	db     *gorm.DB
	redis  *redis.Client
	logger *zap.Logger
}

// NewHealthHandler 创建健康检查处理器实例
func NewHealthHandler(db *gorm.DB, redis *redis.Client, logger *zap.Logger) *HealthHandler {
	return &HealthHandler{
		db:     db,
		redis:  redis,
		logger: logger,
	}
}

// Check 健康检查
// GET /health
func (h *HealthHandler) Check(c *fiber.Ctx) error {
	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
	defer cancel()

	healthStatus := fiber.Map{
		"status":    "healthy",
		"timestamp": time.Now().Format(time.RFC3339),
		"services":  fiber.Map{},
	}

	services := healthStatus["services"].(fiber.Map)
	allHealthy := true

	// 检查 PostgreSQL
	sqlDB, err := h.db.DB()
	if err != nil {
		h.logger.Error("获取 PostgreSQL DB 实例失败", zap.Error(err))
		services["postgres"] = fiber.Map{
			"status": "down",
			"error":  err.Error(),
		}
		allHealthy = false
	} else {
		if err := sqlDB.PingContext(ctx); err != nil {
			h.logger.Error("PostgreSQL Ping 失败", zap.Error(err))
			services["postgres"] = fiber.Map{
				"status": "down",
				"error":  err.Error(),
			}
			allHealthy = false
		} else {
			// 获取连接池统计信息
			stats := sqlDB.Stats()
			services["postgres"] = fiber.Map{
				"status":             "up",
				"open_conns":         stats.OpenConnections,
				"in_use":             stats.InUse,
				"idle":               stats.Idle,
				"wait_count":         stats.WaitCount,
				"wait_duration":      stats.WaitDuration.String(),
				"max_idle_close":     stats.MaxIdleClosed,
				"max_lifetime_close": stats.MaxLifetimeClosed,
			}
		}
	}

	// 检查 Redis
	if err := h.redis.Ping(ctx).Err(); err != nil {
		h.logger.Error("Redis Ping 失败", zap.Error(err))
		services["redis"] = fiber.Map{
			"status": "down",
			"error":  err.Error(),
		}
		allHealthy = false
	} else {
		// 获取 Redis 信息
		poolStats := h.redis.PoolStats()
		services["redis"] = fiber.Map{
			"status":      "up",
			"hits":        poolStats.Hits,
			"misses":      poolStats.Misses,
			"timeouts":    poolStats.Timeouts,
			"total_conns": poolStats.TotalConns,
			"idle_conns":  poolStats.IdleConns,
			"stale_conns": poolStats.StaleConns,
		}
	}

	// 设置总体状态
	if !allHealthy {
		healthStatus["status"] = "degraded"
		h.logger.Warn("健康检查失败: 部分服务不可用")
	} else {
		h.logger.Info("健康检查成功: 所有服务正常")
	}

	// 统一使用 response.Success 返回，状态信息在 data.status 中标记
	// 健康检查端点本身能响应即视为成功，具体服务状态由 data.status 字段表示
	return response.Success(c, healthStatus)
}

// HealthCheck 简单健康检查(保持向后兼容)
func HealthCheck(c *fiber.Ctx) error {
	return response.Success(c, fiber.Map{
		"status":    "healthy",
		"timestamp": time.Now().Format(time.RFC3339),
	})
}
