package handler_test

import (
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/gin-gonic/gin"
	"github.com/user-management-system/internal/api/handler"
	"github.com/user-management-system/internal/domain"
	"github.com/user-management-system/internal/repository"
	"github.com/user-management-system/internal/service"
	gormsqlite "gorm.io/driver/sqlite"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
)

// =============================================================================
// Stats Handler Tests - TDD approach
// =============================================================================

func setupStatsTestEnv(t *testing.T) (*handler.StatsHandler, *gorm.DB) {
	t.Helper()
	gin.SetMode(gin.TestMode)

	db, err := gorm.Open(gormsqlite.New(gormsqlite.Config{
		DriverName: "sqlite",
		DSN:        "file:stats_test?mode=memory&cache=shared",
	}), &gorm.Config{
		Logger: logger.Default.LogMode(logger.Silent),
	})
	if err != nil {
		t.Fatalf("failed to connect database: %v", err)
	}

	if err := db.AutoMigrate(&domain.User{}, &domain.Role{}, &domain.LoginLog{}); err != nil {
		t.Fatalf("failed to migrate: %v", err)
	}

	userRepo := repository.NewUserRepository(db)
	loginLogRepo := repository.NewLoginLogRepository(db)
	statsSvc := service.NewStatsService(userRepo, loginLogRepo)

	return handler.NewStatsHandler(statsSvc), db
}

func TestStatsHandler_GetDashboard(t *testing.T) {
	h, db := setupStatsTestEnv(t)

	// 创建测试用户
	db.Create(&domain.User{Username: "user1", Status: domain.UserStatusActive})
	db.Create(&domain.User{Username: "user2", Status: domain.UserStatusInactive})

	t.Run("获取仪表盘统计成功", func(t *testing.T) {
		w := httptest.NewRecorder()
		c, _ := gin.CreateTestContext(w)
		c.Request = httptest.NewRequest("GET", "/api/v1/admin/stats/dashboard", nil)

		h.GetDashboard(c)

		if w.Code != http.StatusOK {
			t.Errorf("期望状态码 %d, 得到 %d", http.StatusOK, w.Code)
		}

		var resp map[string]interface{}
		if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
			t.Fatalf("解析响应失败: %v", err)
		}

		if resp["code"].(float64) != 0 {
			t.Errorf("期望 code=0, 得到 %v", resp["code"])
		}

		// data 可能是 map 或 nil
		if resp["data"] != nil {
			data := resp["data"].(map[string]interface{})
			if data["total_users"] == nil {
				t.Log("total_users 为空，但响应成功")
			}
		}
	})
}

func TestStatsHandler_GetUserStats(t *testing.T) {
	h, db := setupStatsTestEnv(t)

	// 创建不同状态的用户
	db.Create(&domain.User{Username: "active_user", Status: domain.UserStatusActive})
	db.Create(&domain.User{Username: "inactive_user", Status: domain.UserStatusInactive})
	db.Create(&domain.User{Username: "locked_user", Status: domain.UserStatusLocked})

	t.Run("获取用户统计成功", func(t *testing.T) {
		w := httptest.NewRecorder()
		c, _ := gin.CreateTestContext(w)
		c.Request = httptest.NewRequest("GET", "/api/v1/admin/stats/users", nil)

		h.GetUserStats(c)

		if w.Code != http.StatusOK {
			t.Errorf("期望状态码 %d, 得到 %d", http.StatusOK, w.Code)
		}

		var resp map[string]interface{}
		if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
			t.Fatalf("解析响应失败: %v", err)
		}

		if resp["code"].(float64) != 0 {
			t.Errorf("期望 code=0, 得到 %v", resp["code"])
		}
	})
}
