package handler_test

import (
	"bytes"
	"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"
)

// =============================================================================
// Theme Handler Tests - TDD approach
// =============================================================================

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

	db, err := gorm.Open(gormsqlite.New(gormsqlite.Config{
		DriverName: "sqlite",
		DSN:        "file:theme_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.ThemeConfig{}); err != nil {
		t.Fatalf("failed to migrate: %v", err)
	}

	themeRepo := repository.NewThemeConfigRepository(db)
	themeSvc := service.NewThemeService(themeRepo)

	return handler.NewThemeHandler(themeSvc), db
}

func TestThemeHandler_CreateTheme(t *testing.T) {
	h, _ := setupThemeTestEnv(t)

	t.Run("创建主题成功", func(t *testing.T) {
		w := httptest.NewRecorder()
		c, _ := gin.CreateTestContext(w)
		body := `{"name":"test-theme","primary_color":"#1976d2"}`
		c.Request = httptest.NewRequest("POST", "/api/v1/themes", bytes.NewReader([]byte(body)))
		c.Request.Header.Set("Content-Type", "application/json")

		h.CreateTheme(c)

		if w.Code != http.StatusCreated {
			t.Errorf("期望状态码 %d, 得到 %d", http.StatusCreated, 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"])
		}
	})

	t.Run("创建主题失败-缺少名称", func(t *testing.T) {
		w := httptest.NewRecorder()
		c, _ := gin.CreateTestContext(w)
		body := `{"primary_color":"#1976d2"}`
		c.Request = httptest.NewRequest("POST", "/api/v1/themes", bytes.NewReader([]byte(body)))
		c.Request.Header.Set("Content-Type", "application/json")

		h.CreateTheme(c)

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

func TestThemeHandler_ListThemes(t *testing.T) {
	h, _ := setupThemeTestEnv(t)

	t.Run("获取主题列表", func(t *testing.T) {
		w := httptest.NewRecorder()
		c, _ := gin.CreateTestContext(w)
		c.Request = httptest.NewRequest("GET", "/api/v1/themes", nil)

		h.ListThemes(c)

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

func TestThemeHandler_GetTheme(t *testing.T) {
	h, _ := setupThemeTestEnv(t)

	t.Run("获取主题失败-无效ID", func(t *testing.T) {
		w := httptest.NewRecorder()
		c, _ := gin.CreateTestContext(w)
		c.Params = gin.Params{{Key: "id", Value: "invalid"}}
		c.Request = httptest.NewRequest("GET", "/api/v1/themes/invalid", nil)

		h.GetTheme(c)

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

func TestThemeHandler_DeleteTheme(t *testing.T) {
	h, _ := setupThemeTestEnv(t)

	t.Run("删除主题失败-无效ID", func(t *testing.T) {
		w := httptest.NewRecorder()
		c, _ := gin.CreateTestContext(w)
		c.Params = gin.Params{{Key: "id", Value: "invalid"}}
		c.Request = httptest.NewRequest("DELETE", "/api/v1/themes/invalid", nil)

		h.DeleteTheme(c)

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