package main

import (
	"html/template"
	"net/http"
	"strings"
	"time"
)

type UserSettings struct {
	Theme          string
	SiteLanguage   string
	SearchLanguage string
	SafeSearch     string
	IsThemeDark    bool
}

func loadUserSettings(w http.ResponseWriter, r *http.Request) UserSettings {
	var settings UserSettings
	saveRequired := false

	// Load theme
	if cookie, err := r.Cookie("theme"); err == nil {
		settings.Theme = cookie.Value
	} else {
		settings.Theme = "dark"
		saveRequired = true
	}

	// Determine if the selected theme is dark
	settings.IsThemeDark = settings.Theme == "dark" || settings.Theme == "night" || settings.Theme == "black" || settings.Theme == "latte"

	// Load site language
	if cookie, err := r.Cookie("site_language"); err == nil {
		settings.SiteLanguage = cookie.Value
	} else {
		// If no site language is set, use Accept-Language or default to "en"
		acceptLang := r.Header.Get("Accept-Language")
		if acceptLang != "" {
			settings.SiteLanguage = normalizeLangCode(strings.Split(acceptLang, ",")[0])
		} else {
			settings.SiteLanguage = "en" // Default language
		}
		saveRequired = true
	}

	// Load search language (can be empty)
	if cookie, err := r.Cookie("search_language"); err == nil {
		settings.SearchLanguage = cookie.Value
	}

	// Load safe search
	if cookie, err := r.Cookie("safe"); err == nil {
		settings.SafeSearch = cookie.Value
	} else {
		settings.SafeSearch = ""
		saveRequired = true
	}

	if saveRequired {
		saveUserSettings(w, settings)
	}

	return settings
}

func saveUserSettings(w http.ResponseWriter, settings UserSettings) {
	expiration := time.Now().Add(90 * 24 * time.Hour)

	http.SetCookie(w, &http.Cookie{
		Name:     "theme",
		Value:    settings.Theme,
		Path:     "/",
		Expires:  expiration,
		Secure:   true,
		SameSite: http.SameSiteStrictMode,
	})
	http.SetCookie(w, &http.Cookie{
		Name:     "site_language",
		Value:    settings.SiteLanguage,
		Path:     "/",
		Expires:  expiration,
		Secure:   true,
		SameSite: http.SameSiteStrictMode,
	})
	http.SetCookie(w, &http.Cookie{
		Name:     "search_language",
		Value:    settings.SearchLanguage,
		Path:     "/",
		Expires:  expiration,
		Secure:   true,
		SameSite: http.SameSiteStrictMode,
	})
	http.SetCookie(w, &http.Cookie{
		Name:     "safe",
		Value:    settings.SafeSearch,
		Path:     "/",
		Expires:  expiration,
		Secure:   true,
		SameSite: http.SameSiteStrictMode,
	})

	printDebug("settings saved: %v", settings)
}

func handleSaveSettings(w http.ResponseWriter, r *http.Request) {
	if r.Method == "POST" {
		// Load current settings
		settings := loadUserSettings(w, r)

		// Update only the settings that were submitted in the form
		if theme := r.FormValue("theme"); theme != "" {
			settings.Theme = theme
		}

		// Update site language if provided
		if siteLang := r.FormValue("site_lang"); siteLang != "" {
			settings.SiteLanguage = siteLang
		} else {
			// If site_lang is empty, try to get from Accept-Language header
			acceptLang := r.Header.Get("Accept-Language")
			if acceptLang != "" {
				settings.SiteLanguage = strings.Split(acceptLang, ",")[0]
			}
		}

		// Update search language if provided
		if searchLang := r.FormValue("search_lang"); searchLang != "" {
			settings.SearchLanguage = searchLang
		}

		// Update safe search if provided
		if safe := r.FormValue("safe"); safe != "" {
			settings.SafeSearch = safe
		}

		// Save the updated settings
		saveUserSettings(w, settings)

		// Redirect back to the previous page or settings page
		http.Redirect(w, r, r.FormValue("past"), http.StatusSeeOther)
	}
}

func handleSettings(w http.ResponseWriter, r *http.Request) {
	// Load user settings
	settings = loadUserSettings(w, r)

	data := struct {
		LanguageOptions   []LanguageOption
		CurrentSiteLang   string
		CurrentSearchLang string
		Theme             string
		Safe              string
		IsThemeDark       bool
	}{
		LanguageOptions:   languageOptions,
		CurrentSiteLang:   settings.SiteLanguage,
		CurrentSearchLang: settings.SearchLanguage,
		Theme:             settings.Theme,
		Safe:              settings.SafeSearch,
		IsThemeDark:       settings.IsThemeDark,
	}

	printDebug("Rendering settings with data: %+v", data)

	tmpl, err := template.New("settings.html").Funcs(template.FuncMap{"translate": Translate}).ParseFiles("templates/settings.html")
	if err != nil {
		printErr("Error parsing template: %s", err)
		http.Error(w, "Internal Server Error", 500)
		return
	}

	err = tmpl.Execute(w, data)
	if err != nil {
		printErr("Error executing template: %s", err)
		http.Error(w, "Internal Server Error", 500)
		return
	}
}

// Helper function to normalize language codes
func normalizeLangCode(lang string) string {
	lang = strings.ToLower(lang)

	// First, check if the language code is already valid
	if isValidLangCode(lang) {
		return lang
	}

	// Strip regional codes (e.g., en-US -> en)
	if strings.Contains(lang, "-") {
		lang = strings.Split(lang, "-")[0]
	}

	// Re-check if the normalized version is valid
	if isValidLangCode(lang) {
		return lang
	}

	// If the language is not recognized, default to "en"
	return "en"
}

// Helper function to check if a language code exists in the language options
func isValidLangCode(lang string) bool {
	for _, opt := range languageOptions {
		if opt.Code == lang {
			return true
		}
	}
	return false
}