package service

import (
	"context"
	"errors"
	"regexp"

	"github.com/user-management-system/internal/domain"
	"github.com/user-management-system/internal/repository"
)

// ThemeService 主题服务
type ThemeService struct {
	themeRepo *repository.ThemeConfigRepository
}

// NewThemeService 创建主题服务
func NewThemeService(themeRepo *repository.ThemeConfigRepository) *ThemeService {
	return &ThemeService{themeRepo: themeRepo}
}

// CreateThemeRequest 创建主题请求
type CreateThemeRequest struct {
	Name           string `json:"name" binding:"required"`
	LogoURL        string `json:"logo_url"`
	FaviconURL     string `json:"favicon_url"`
	PrimaryColor   string `json:"primary_color"`
	SecondaryColor string `json:"secondary_color"`
	BackgroundColor string `json:"background_color"`
	TextColor      string `json:"text_color"`
	CustomCSS      string `json:"custom_css"`
	CustomJS       string `json:"custom_js"`
	IsDefault      bool   `json:"is_default"`
}

// UpdateThemeRequest 更新主题请求
type UpdateThemeRequest struct {
	LogoURL        string `json:"logo_url"`
	FaviconURL     string `json:"favicon_url"`
	PrimaryColor   string `json:"primary_color"`
	SecondaryColor string `json:"secondary_color"`
	BackgroundColor string `json:"background_color"`
	TextColor      string `json:"text_color"`
	CustomCSS      string `json:"custom_css"`
	CustomJS       string `json:"custom_js"`
	Enabled        *bool  `json:"enabled"`
	IsDefault      *bool  `json:"is_default"`
}

// CreateTheme 创建主题
func (s *ThemeService) CreateTheme(ctx context.Context, req *CreateThemeRequest) (*domain.ThemeConfig, error) {
	// 安全检查：禁止在 CustomCSS/CustomJS 中包含危险模式
	if err := validateCustomCSSJS(req.CustomCSS, req.CustomJS); err != nil {
		return nil, err
	}

	// 检查主题名称是否已存在
	existing, err := s.themeRepo.GetByName(ctx, req.Name)
	if err == nil && existing != nil {
		return nil, errors.New("主题名称已存在")
	}

	theme := &domain.ThemeConfig{
		Name:            req.Name,
		LogoURL:         req.LogoURL,
		FaviconURL:      req.FaviconURL,
		PrimaryColor:   req.PrimaryColor,
		SecondaryColor: req.SecondaryColor,
		BackgroundColor: req.BackgroundColor,
		TextColor:      req.TextColor,
		CustomCSS:      req.CustomCSS,
		CustomJS:       req.CustomJS,
		IsDefault:      req.IsDefault,
		Enabled:        true,
	}

	// 如果设置为默认，先清除其他默认
	if req.IsDefault {
		if err := s.clearDefaultThemes(ctx); err != nil {
			return nil, err
		}
	}

	if err := s.themeRepo.Create(ctx, theme); err != nil {
		return nil, err
	}

	return theme, nil
}

// UpdateTheme 更新主题
func (s *ThemeService) UpdateTheme(ctx context.Context, id int64, req *UpdateThemeRequest) (*domain.ThemeConfig, error) {
	// 安全检查：禁止在 CustomCSS/CustomJS 中包含危险模式
	if err := validateCustomCSSJS(req.CustomCSS, req.CustomJS); err != nil {
		return nil, err
	}

	theme, err := s.themeRepo.GetByID(ctx, id)
	if err != nil {
		return nil, errors.New("主题不存在")
	}

	if req.LogoURL != "" {
		theme.LogoURL = req.LogoURL
	}
	if req.FaviconURL != "" {
		theme.FaviconURL = req.FaviconURL
	}
	if req.PrimaryColor != "" {
		theme.PrimaryColor = req.PrimaryColor
	}
	if req.SecondaryColor != "" {
		theme.SecondaryColor = req.SecondaryColor
	}
	if req.BackgroundColor != "" {
		theme.BackgroundColor = req.BackgroundColor
	}
	if req.TextColor != "" {
		theme.TextColor = req.TextColor
	}
	if req.CustomCSS != "" {
		theme.CustomCSS = req.CustomCSS
	}
	if req.CustomJS != "" {
		theme.CustomJS = req.CustomJS
	}
	if req.Enabled != nil {
		theme.Enabled = *req.Enabled
	}
	if req.IsDefault != nil && *req.IsDefault {
		if err := s.clearDefaultThemes(ctx); err != nil {
			return nil, err
		}
		theme.IsDefault = true
	}

	if err := s.themeRepo.Update(ctx, theme); err != nil {
		return nil, err
	}

	return theme, nil
}

// DeleteTheme 删除主题
func (s *ThemeService) DeleteTheme(ctx context.Context, id int64) error {
	theme, err := s.themeRepo.GetByID(ctx, id)
	if err != nil {
		return errors.New("主题不存在")
	}

	if theme.IsDefault {
		return errors.New("不能删除默认主题")
	}

	return s.themeRepo.Delete(ctx, id)
}

// GetTheme 获取主题
func (s *ThemeService) GetTheme(ctx context.Context, id int64) (*domain.ThemeConfig, error) {
	return s.themeRepo.GetByID(ctx, id)
}

// ListThemes 获取所有已启用主题
func (s *ThemeService) ListThemes(ctx context.Context) ([]*domain.ThemeConfig, error) {
	return s.themeRepo.List(ctx)
}

// ListAllThemes 获取所有主题
func (s *ThemeService) ListAllThemes(ctx context.Context) ([]*domain.ThemeConfig, error) {
	return s.themeRepo.ListAll(ctx)
}

// GetDefaultTheme 获取默认主题
func (s *ThemeService) GetDefaultTheme(ctx context.Context) (*domain.ThemeConfig, error) {
	return s.themeRepo.GetDefault(ctx)
}

// SetDefaultTheme 设置默认主题
func (s *ThemeService) SetDefaultTheme(ctx context.Context, id int64) error {
	theme, err := s.themeRepo.GetByID(ctx, id)
	if err != nil {
		return errors.New("主题不存在")
	}

	if !theme.Enabled {
		return errors.New("不能将禁用的主题设为默认")
	}

	return s.themeRepo.SetDefault(ctx, id)
}

// GetActiveTheme 获取当前生效的主题
func (s *ThemeService) GetActiveTheme(ctx context.Context) (*domain.ThemeConfig, error) {
	theme, err := s.themeRepo.GetDefault(ctx)
	if err != nil {
		// 返回默认配置
		return domain.DefaultThemeConfig(), nil
	}
	return theme, nil
}

// clearDefaultThemes 清除所有默认主题标记
func (s *ThemeService) clearDefaultThemes(ctx context.Context) error {
	themes, err := s.themeRepo.ListAll(ctx)
	if err != nil {
		return err
	}
	for _, t := range themes {
		if t.IsDefault {
			t.IsDefault = false
			if err := s.themeRepo.Update(ctx, t); err != nil {
				return err
			}
		}
	}
	return nil
}

// validateCustomCSSJS 检查 CustomCSS 和 CustomJS 是否包含危险 XSS 模式
// 这不是完全净化，而是拒绝明显可造成 XSS 的模式
func validateCustomCSSJS(css, js string) error {
	// 危险模式列表
	dangerousPatterns := []struct {
		pattern *regexp.Regexp
		message string
	}{
		// Script 标签
		{regexp.MustCompile(`(?i)<script[^>]*>.*?</script>`), "CustomJS 禁止包含 <script> 标签"},
		{regexp.MustCompile(`(?i)javascript\s*:`), "CustomJS 禁止使用 javascript: 协议"},
		// 事件处理器
		{regexp.MustCompile(`(?i)on\w+\s*=`), "CustomJS 禁止使用事件处理器 (如 onerror, onclick)"},
		// Data URL
		{regexp.MustCompile(`(?i)data\s*:\s*text/html`), "禁止使用 data: URL 嵌入 HTML"},
		// CSS expression (IE)
		{regexp.MustCompile(`(?i)expression\s*\(`), "CustomCSS 禁止使用 CSS expression"},
		// CSS 中的 javascript
		{regexp.MustCompile(`(?i)url\s*\(\s*['"]?\s*javascript:`), "CustomCSS 禁止使用 javascript: URL"},
		// 嵌入的 <style> 标签
		{regexp.MustCompile(`(?i)<style[^>]*>.*?</style>`), "CustomCSS 禁止包含 <style> 标签"},
	}

	// 检查 JS
	for _, p := range dangerousPatterns {
		if p.pattern.MatchString(js) {
			return errors.New(p.message)
		}
	}

	// 检查 CSS
	for _, p := range dangerousPatterns {
		if p.pattern.MatchString(css) {
			return errors.New(p.message)
		}
	}

	return nil
}
