package service_test

import (
	"context"
	"testing"

	"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 Service Tests - TDD approach
// =============================================================================

func setupThemeServiceTestEnv(t *testing.T) (*service.ThemeService, *gorm.DB) {
	t.Helper()

	db, err := gorm.Open(gormsqlite.New(gormsqlite.Config{
		DriverName: "sqlite",
		DSN:        "file:theme_svc_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)
	return service.NewThemeService(themeRepo), db
}

func TestThemeService_CreateTheme(t *testing.T) {
	svc, _ := setupThemeServiceTestEnv(t)
	ctx := context.Background()

	t.Run("创建主题成功", func(t *testing.T) {
		req := &service.CreateThemeRequest{
			Name:         "test-theme",
			PrimaryColor: "#1976d2",
		}
		theme, err := svc.CreateTheme(ctx, req)
		if err != nil {
			t.Fatalf("CreateTheme failed: %v", err)
		}
		if theme.Name != "test-theme" {
			t.Errorf("期望 Name=test-theme, 得到 %s", theme.Name)
		}
		if theme.PrimaryColor != "#1976d2" {
			t.Errorf("期望 PrimaryColor=#1976d2, 得到 %s", theme.PrimaryColor)
		}
	})

	t.Run("创建主题失败-危险脚本", func(t *testing.T) {
		req := &service.CreateThemeRequest{
			Name:     "dangerous-theme",
			CustomJS: "<script>alert('xss')</script>",
		}
		_, err := svc.CreateTheme(ctx, req)
		if err == nil {
			t.Error("期望返回错误但没有")
		}
	})

	t.Run("创建主题失败-事件处理器", func(t *testing.T) {
		req := &service.CreateThemeRequest{
			Name:     "dangerous-theme-2",
			CustomJS: "onclick='alert(1)'",
		}
		_, err := svc.CreateTheme(ctx, req)
		if err == nil {
			t.Error("期望返回错误但没有")
		}
	})

	t.Run("创建主题失败-名称重复", func(t *testing.T) {
		req := &service.CreateThemeRequest{
			Name: "test-theme",
		}
		_, err := svc.CreateTheme(ctx, req)
		if err == nil {
			t.Error("期望返回错误但没有")
		}
	})
}

func TestThemeService_ListThemes(t *testing.T) {
	svc, _ := setupThemeServiceTestEnv(t)
	ctx := context.Background()

	// 创建测试数据
	svc.CreateTheme(ctx, &service.CreateThemeRequest{Name: "theme1"})
	svc.CreateTheme(ctx, &service.CreateThemeRequest{Name: "theme2"})

	t.Run("获取主题列表", func(t *testing.T) {
		themes, err := svc.ListThemes(ctx)
		if err != nil {
			t.Fatalf("ListThemes failed: %v", err)
		}
		if len(themes) < 2 {
			t.Errorf("期望至少2个主题, 得到 %d", len(themes))
		}
	})
}

func TestThemeService_GetDefaultTheme(t *testing.T) {
	svc, _ := setupThemeServiceTestEnv(t)
	ctx := context.Background()

	t.Run("获取默认主题-无数据时返回默认配置", func(t *testing.T) {
		theme, err := svc.GetDefaultTheme(ctx)
		// 无数据时应返回错误或默认配置
		if err != nil && theme == nil {
			// 这是预期行为
			return
		}
		if theme != nil && theme.Name == "default" {
			// 返回了默认配置
			return
		}
		t.Log("GetDefaultTheme 行为正常")
	})
}

func TestThemeService_GetActiveTheme(t *testing.T) {
	svc, _ := setupThemeServiceTestEnv(t)
	ctx := context.Background()

	t.Run("获取活动主题", func(t *testing.T) {
		theme, err := svc.GetActiveTheme(ctx)
		if err != nil {
			t.Fatalf("GetActiveTheme failed: %v", err)
		}
		if theme == nil {
			t.Error("主题不应为空")
		}
	})
}

func TestThemeService_DeleteTheme(t *testing.T) {
	svc, _ := setupThemeServiceTestEnv(t)
	ctx := context.Background()

	t.Run("删除不存在的主题", func(t *testing.T) {
		err := svc.DeleteTheme(ctx, 9999)
		if err == nil {
			t.Error("期望返回错误但没有")
		}
	})

	t.Run("删除主题成功", func(t *testing.T) {
		theme, _ := svc.CreateTheme(ctx, &service.CreateThemeRequest{Name: "to-delete"})
		err := svc.DeleteTheme(ctx, theme.ID)
		if err != nil {
			t.Errorf("删除主题失败: %v", err)
		}
	})

	t.Run("删除默认主题失败", func(t *testing.T) {
		theme, _ := svc.CreateTheme(ctx, &service.CreateThemeRequest{Name: "default-theme", IsDefault: true})
		err := svc.DeleteTheme(ctx, theme.ID)
		if err == nil {
			t.Error("期望返回错误但没有")
		}
	})
}

func TestThemeService_SetDefaultTheme(t *testing.T) {
	svc, _ := setupThemeServiceTestEnv(t)
	ctx := context.Background()

	t.Run("设置不存在的主题为默认", func(t *testing.T) {
		err := svc.SetDefaultTheme(ctx, 9999)
		if err == nil {
			t.Error("期望返回错误但没有")
		}
	})

	t.Run("设置禁用的主题为默认失败", func(t *testing.T) {
		theme, _ := svc.CreateTheme(ctx, &service.CreateThemeRequest{Name: "disabled-theme"})
		// 禁用主题
		disabled := false
		svc.UpdateTheme(ctx, theme.ID, &service.UpdateThemeRequest{Enabled: &disabled})

		err := svc.SetDefaultTheme(ctx, theme.ID)
		if err == nil {
			t.Error("期望返回错误但没有")
		}
	})
}

func TestThemeService_GetTheme(t *testing.T) {
	svc, _ := setupThemeServiceTestEnv(t)
	ctx := context.Background()

	t.Run("获取存在的主题", func(t *testing.T) {
		created, _ := svc.CreateTheme(ctx, &service.CreateThemeRequest{Name: "get-theme-test"})
		theme, err := svc.GetTheme(ctx, created.ID)
		if err != nil {
			t.Fatalf("GetTheme failed: %v", err)
		}
		if theme.Name != "get-theme-test" {
			t.Errorf("期望 Name=get-theme-test, 得到 %s", theme.Name)
		}
	})

	t.Run("获取不存在的主题", func(t *testing.T) {
		_, err := svc.GetTheme(ctx, 9999)
		if err == nil {
			t.Error("期望返回错误但没有")
		}
	})
}

func TestThemeService_ListAllThemes(t *testing.T) {
	svc, _ := setupThemeServiceTestEnv(t)
	ctx := context.Background()

	// 创建测试数据
	svc.CreateTheme(ctx, &service.CreateThemeRequest{Name: "all-theme1"})
	svc.CreateTheme(ctx, &service.CreateThemeRequest{Name: "all-theme2"})

	t.Run("获取所有主题", func(t *testing.T) {
		themes, err := svc.ListAllThemes(ctx)
		if err != nil {
			t.Fatalf("ListAllThemes failed: %v", err)
		}
		if len(themes) < 2 {
			t.Errorf("期望至少2个主题, 得到 %d", len(themes))
		}
	})
}

func TestThemeService_UpdateTheme(t *testing.T) {
	svc, _ := setupThemeServiceTestEnv(t)
	ctx := context.Background()

	t.Run("更新主题成功", func(t *testing.T) {
		created, _ := svc.CreateTheme(ctx, &service.CreateThemeRequest{Name: "update-theme-test"})
		updated, err := svc.UpdateTheme(ctx, created.ID, &service.UpdateThemeRequest{
			PrimaryColor: "#ff0000",
		})
		if err != nil {
			t.Fatalf("UpdateTheme failed: %v", err)
		}
		if updated.PrimaryColor != "#ff0000" {
			t.Errorf("期望 PrimaryColor=#ff0000, 得到 %s", updated.PrimaryColor)
		}
	})

	t.Run("更新不存在的主题", func(t *testing.T) {
		_, err := svc.UpdateTheme(ctx, 9999, &service.UpdateThemeRequest{})
		if err == nil {
			t.Error("期望返回错误但没有")
		}
	})

	t.Run("更新主题带危险CSS", func(t *testing.T) {
		created, _ := svc.CreateTheme(ctx, &service.CreateThemeRequest{Name: "update-dangerous"})
		_, err := svc.UpdateTheme(ctx, created.ID, &service.UpdateThemeRequest{
			CustomCSS: "<script>alert('xss')</script>",
		})
		if err == nil {
			t.Error("期望返回错误但没有")
		}
	})
}
