package theme

import (
	"database/sql"
	"fmt"
)

type ThemeService struct {
	db *sql.DB
}

func NewThemeService(db *sql.DB) *ThemeService {
	return &ThemeService{db: db}
}

func (s *ThemeService) SeedBuiltins() error {
	for _, t := range BuiltinThemes {
		_, err := s.db.Exec(
			`INSERT OR IGNORE INTO themes (name, foreground, background, cursor,
			 black, red, green, yellow, blue, magenta, cyan, white,
			 bright_black, bright_red, bright_green, bright_yellow, bright_blue,
			 bright_magenta, bright_cyan, bright_white, selection_bg, selection_fg, is_builtin)
			 VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,1)`,
			t.Name, t.Foreground, t.Background, t.Cursor,
			t.Black, t.Red, t.Green, t.Yellow, t.Blue, t.Magenta, t.Cyan, t.White,
			t.BrightBlack, t.BrightRed, t.BrightGreen, t.BrightYellow, t.BrightBlue,
			t.BrightMagenta, t.BrightCyan, t.BrightWhite, t.SelectionBg, t.SelectionFg,
		)
		if err != nil {
			return fmt.Errorf("seed theme %s: %w", t.Name, err)
		}
	}
	return nil
}

func (s *ThemeService) List() ([]Theme, error) {
	rows, err := s.db.Query(
		`SELECT id, name, foreground, background, cursor,
		 black, red, green, yellow, blue, magenta, cyan, white,
		 bright_black, bright_red, bright_green, bright_yellow, bright_blue,
		 bright_magenta, bright_cyan, bright_white,
		 COALESCE(selection_bg,''), COALESCE(selection_fg,''), is_builtin
		 FROM themes ORDER BY is_builtin DESC, name`)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var themes []Theme
	for rows.Next() {
		var t Theme
		if err := rows.Scan(&t.ID, &t.Name, &t.Foreground, &t.Background, &t.Cursor,
			&t.Black, &t.Red, &t.Green, &t.Yellow, &t.Blue, &t.Magenta, &t.Cyan, &t.White,
			&t.BrightBlack, &t.BrightRed, &t.BrightGreen, &t.BrightYellow, &t.BrightBlue,
			&t.BrightMagenta, &t.BrightCyan, &t.BrightWhite,
			&t.SelectionBg, &t.SelectionFg, &t.IsBuiltin); err != nil {
			return nil, err
		}
		themes = append(themes, t)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return themes, nil
}

func (s *ThemeService) GetByName(name string) (*Theme, error) {
	var t Theme
	err := s.db.QueryRow(
		`SELECT id, name, foreground, background, cursor,
		 black, red, green, yellow, blue, magenta, cyan, white,
		 bright_black, bright_red, bright_green, bright_yellow, bright_blue,
		 bright_magenta, bright_cyan, bright_white,
		 COALESCE(selection_bg,''), COALESCE(selection_fg,''), is_builtin
		 FROM themes WHERE name = ?`, name,
	).Scan(&t.ID, &t.Name, &t.Foreground, &t.Background, &t.Cursor,
		&t.Black, &t.Red, &t.Green, &t.Yellow, &t.Blue, &t.Magenta, &t.Cyan, &t.White,
		&t.BrightBlack, &t.BrightRed, &t.BrightGreen, &t.BrightYellow, &t.BrightBlue,
		&t.BrightMagenta, &t.BrightCyan, &t.BrightWhite,
		&t.SelectionBg, &t.SelectionFg, &t.IsBuiltin)
	if err != nil {
		return nil, fmt.Errorf("get theme %s: %w", name, err)
	}
	return &t, nil
}
