package theme

import (
	"errors"
	"io/fs"
	"os"
	"path/filepath"
	"strings"

	"github.com/BurntSushi/toml"
	"github.com/charmbracelet/lipgloss"
	"github.com/muesli/termenv"
)

type Palette struct {
	Background      string
	Foreground      string
	GridLine        string
	CellBaseBG      string
	CellBaseFG      string
	CellFixedFG     string
	CellFixedBG     string
	CellSelectedBG  string
	CellSelectedFG  string
	CellDuplicateBG string
	CellConflictBG  string
	Accent          string
}

type Theme struct {
	Name    string
	Palette Palette
}

// Light defines a theme inspired by Solarized Light.
func Light() Theme {
	return Theme{
		Name: "solarized-light",
		Palette: Palette{
			Background:      "#fdf6e3", // base3
			Foreground:      "#586e75", // base01
			GridLine:        "#93a1a1", // base1
			CellBaseBG:      "",
			CellBaseFG:      "#586e75", // base01
			CellFixedFG:     "#839496", // base0
			CellFixedBG:     "",
			CellSelectedBG:  "#eee8d5", // base2
			CellSelectedFG:  "#586e75", // base01
			CellDuplicateBG: "#f5e8c1", // Slightly darker variant
			CellConflictBG:  "#ffe0e0", // Reddish conflict, still light
			Accent:          "#dc322f", // red
		},
	}
}

// Darcula returns a dark theme inspired by Darcula.
func Darcula() Theme {
	return Theme{
		Name: "dracula",
		Palette: Palette{
			Background:      "#282a36", // background
			Foreground:      "#f8f8f2", // foreground
			GridLine:        "#44475a", // current line
			CellBaseBG:      "",
			CellBaseFG:      "#f8f8f2", // foreground
			CellFixedFG:     "#6272a4", // comment
			CellFixedBG:     "",
			CellSelectedBG:  "#44475a", // current line
			CellSelectedFG:  "#f8f8f2", // foreground
			CellDuplicateBG: "#50fa7b", // green - using a highlight for duplicate
			CellConflictBG:  "#ff5555", // red
			Accent:          "#bd93f9", // purple
		},
	}
}

// DetectTheme automatically detects the terminal background and returns appropriate theme
func DetectTheme() Theme {
	if hasLightBackground() {
		return Light()
	}

	return Darcula()
}

// hasLightBackground attempts to detect if the terminal has a light background
func hasLightBackground() bool {
	// Primary detection using termenv
	if !termenv.HasDarkBackground() {
		return true
	}

	// Additional environment variable checks
	term := strings.ToLower(os.Getenv("TERM"))
	colorterm := strings.ToLower(os.Getenv("COLORTERM"))
	termProgram := strings.ToLower(os.Getenv("TERM_PROGRAM"))

	// Check for light theme indicators in environment variables
	lightIndicators := []string{"light", "bright", "white"}
	for _, indicator := range lightIndicators {
		if strings.Contains(term, indicator) ||
			strings.Contains(colorterm, indicator) ||
			strings.Contains(termProgram, indicator) {
			return true
		}
	}

	// Check iTerm2 profile
	if iterm2Profile := strings.ToLower(os.Getenv("ITERM_PROFILE")); iterm2Profile != "" {
		for _, indicator := range lightIndicators {
			if strings.Contains(iterm2Profile, indicator) {
				return true
			}
		}
	}

	return false
}

// AdaptiveColors provides theme-aware color mappings
type AdaptiveColors struct {
	theme Theme
}

func NewAdaptiveColors(t Theme) AdaptiveColors {
	return AdaptiveColors{theme: t}
}

// GetDifficultyColors returns colors for each difficulty level adapted to the theme
func (ac AdaptiveColors) GetDifficultyColors() map[string]string {
	if ac.theme.Name == "solarized-light" {
		// Solarized Light theme colors
		return map[string]string{
			"Easy":    "#2aa198", // cyan
			"Normal":  "#859900", // green
			"Hard":    "#cb4b16", // orange
			"Lunatic": "#6c71c4", // violet
			"Daily":   "#859900", // green
		}
	}
	// Dracula theme colors
	return map[string]string{
		"Easy":    "#8be9fd", // cyan
		"Normal":  "#50fa7b", // green
		"Hard":    "#ffb86c", // orange
		"Lunatic": "#bd93f9", // purple
		"Daily":   "#50fa7b", // green
	}
}

// GetGradientColors returns gradient color pairs adapted to the theme
func (ac AdaptiveColors) GetGradientColors() map[string][2]string {
	if ac.theme.Name == "solarized-light" {
		// Solarized Light theme gradients
		return map[string][2]string{
			"banner":   {"#6c71c4", "#b58900"}, // violet to yellow
			"easy":     {"#2aa198", "#268bd2"}, // cyan to blue
			"normal":   {"#859900", "#cb4b16"}, // green to orange
			"daily":    {"#859900", "#cb4b16"}, // green to orange
			"hard":     {"#dc322f", "#cb4b16"}, // red to orange
			"lunatic":  {"#6c71c4", "#d33682"}, // violet to magenta
			"complete": {"#859900", "#268bd2"}, // success green to blue
		}
	}
	// Dracula theme gradients
	return map[string][2]string{
		"banner":   {"#bd93f9", "#ff79c6"}, // purple to pink
		"easy":     {"#8be9fd", "#6272a4"}, // cyan to comment
		"normal":   {"#50fa7b", "#ffb86c"}, // green to orange
		"daily":    {"#50fa7b", "#ffb86c"}, // green to orange
		"hard":     {"#ffb86c", "#ff5555"}, // orange to red
		"lunatic":  {"#bd93f9", "#ff79c6"}, // purple to pink
		"complete": {"#50fa7b", "#ff79c6"}, // green to pink
	}
}

// GetAccentColors returns various accent colors adapted to the theme
func (ac AdaptiveColors) GetAccentColors() map[string]string {
	if ac.theme.Name == "solarized-light" {
		// Solarized Light theme accents
		return map[string]string{
			"selected": "#cb4b16", // orange
			"panel":    "#839496", // base0
			"success":  "#859900", // green
			"error":    "#dc322f", // red
		}
	}
	// Dracula theme accents
	return map[string]string{
		"selected": "#ff79c6", // pink
		"panel":    "#44475a", // current line
		"success":  "#50fa7b", // green
		"error":    "#ff5555", // red
	}
}

func BaseStyle(t Theme) lipgloss.Style {
	return lipgloss.NewStyle().Foreground(lipgloss.Color(t.Palette.Foreground)).Background(lipgloss.Color(t.Palette.Background))
}

// LoadCustomTheme loads a custom theme from ~/.termdoku/themes/
func LoadCustomTheme(name string) (Theme, error) {
	h, err := os.UserHomeDir()
	if err != nil {
		return Theme{}, err
	}

	themePath := filepath.Join(h, ".termdoku", "themes", name+".toml")
	data, err := os.ReadFile(themePath)
	if err != nil {
		if errors.Is(err, fs.ErrNotExist) {
			return Theme{}, errors.New("custom theme not found: " + name)
		}
		return Theme{}, err
	}

	var theme Theme
	if err := toml.Unmarshal(data, &theme); err != nil {
		return Theme{}, err
	}

	// Set name if not specified in file
	if theme.Name == "" {
		theme.Name = name
	}

	return theme, nil
}

// GetTheme returns the appropriate theme based on config or auto-detection
func GetTheme(configTheme string) Theme {
	switch configTheme {
	case "light":
		return Light()
	case "dark":
		return Darcula()
	case "auto", "":
		return DetectTheme()
	default:
		if theme, err := LoadCustomTheme(configTheme); err == nil {
			return theme
		}
		// Fall back to auto-detection
		return DetectTheme()
	}
}

// CreateExampleTheme creates an example custom theme file for users
func CreateExampleTheme() error {
	h, err := os.UserHomeDir()
	if err != nil {
		return err
	}

	themesDir := filepath.Join(h, ".termdoku", "themes")
	if err := os.MkdirAll(themesDir, 0o755); err != nil {
		return err
	}

	examplePath := filepath.Join(themesDir, "example.toml")

	// Don't overwrite if exists
	if _, err := os.Stat(examplePath); err == nil {
		return nil
	}

	// Example theme inspired by Monokai
	example := Theme{
		Name: "monokai-example",
		Palette: Palette{
			Background:      "#272822",
			Foreground:      "#f8f8f2",
			GridLine:        "#49483e",
			CellBaseBG:      "",
			CellBaseFG:      "#f8f8f2",
			CellFixedFG:     "#75715e",
			CellFixedBG:     "",
			CellSelectedBG:  "#3e3d32",
			CellSelectedFG:  "#f8f8f2",
			CellDuplicateBG: "#a6e22e", // Green for duplicates
			CellConflictBG:  "#f92672", // Pink/Red for conflicts
			Accent:          "#e6db74", // Yellow accent
		},
	}

	data, err := toml.Marshal(example)
	if err != nil {
		return err
	}

	return os.WriteFile(examplePath, data, 0o644)
}
