package handlers

import (
	"net/http"
	"net/url"
	"strconv"
	"strings"

	pscatalog "git.ma-al.com/goc_marek/ps_shop/internal/prestashop/catalog"
	pscookie "git.ma-al.com/goc_marek/ps_shop/internal/prestashop/cookie"
	psroutes "git.ma-al.com/goc_marek/ps_shop/internal/prestashop/routes"
)

func loadMenu(req *http.Request, catalog *pscatalog.Service, route *psroutes.CategoryRoute, languageID int64, shopID int64) ([]pscatalog.MenuItem, error) {
	if catalog == nil || route == nil {
		return nil, nil
	}
	menu, err := catalog.GetCategoryMenu(req.Context(), languageID, shopID)
	if err != nil {
		return nil, err
	}
	assignMenuLinks(req, route, menu)
	return menu, nil
}

func assignMenuLinks(req *http.Request, route *psroutes.CategoryRoute, items []pscatalog.MenuItem) {
	langPrefix := requestLanguagePrefix(req)
	for i := range items {
		items[i].URL = route.BuildPath(psroutes.CategoryURLData{
			ID:             items[i].ID,
			Slug:           items[i].Slug,
			LanguagePrefix: langPrefix,
		})
		if len(items[i].Children) > 0 {
			assignMenuLinks(req, route, items[i].Children)
		}
	}
}

func loadHeaderLocale(req *http.Request, catalog *pscatalog.Service, session *pscookie.SessionContext, languageID int64) (pscatalog.HeaderLocaleData, error) {
	if catalog == nil || req == nil {
		return pscatalog.HeaderLocaleData{}, nil
	}

	var currencyID int64
	countryISO := ""
	if session != nil {
		currencyID = int64Default(session.CurrencyID, 0)
		countryISO = strings.TrimSpace(session.Values["iso_code_country"])
	}

	locale, err := catalog.GetHeaderLocale(req.Context(), languageID, currencyID, countryISO)
	if err != nil {
		return pscatalog.HeaderLocaleData{}, err
	}
	assignLanguageSwitchLinks(req, &locale)
	assignMarketSwitchLinks(req, &locale)
	return locale, nil
}

func assignLanguageSwitchLinks(req *http.Request, locale *pscatalog.HeaderLocaleData) {
	if req == nil || req.URL == nil || locale == nil || len(locale.Languages) == 0 {
		return
	}

	basePath := stripLanguagePrefix(req.URL.Path, locale.Languages)
	rawQuery := req.URL.RawQuery
	for i := range locale.Languages {
		code := strings.ToLower(strings.TrimSpace(locale.Languages[i].Code))
		path := "/" + code
		if basePath != "/" {
			path += basePath
		}
		if rawQuery != "" {
			path += "?" + rawQuery
		}
		locale.Languages[i].URL = path
	}
}

func assignMarketSwitchLinks(req *http.Request, locale *pscatalog.HeaderLocaleData) {
	if req == nil || req.URL == nil || locale == nil || len(locale.Countries) == 0 {
		return
	}

	for i := range locale.Countries {
		marketCode := strings.ToUpper(strings.TrimSpace(locale.Countries[i].Code))
		if marketCode == "" || locale.Countries[i].CurrencyID == 0 {
			continue
		}
		query := req.URL.Query()
		query.Set("market", strconv.FormatInt(locale.Countries[i].ID, 10)+":"+marketCode+":"+strconv.FormatInt(locale.Countries[i].CurrencyID, 10))
		locale.Countries[i].URL = rebuildURL(req.URL.Path, query)
	}
}

func requestLanguagePrefix(req *http.Request) string {
	if req == nil || req.URL == nil {
		return ""
	}
	path := strings.Trim(req.URL.Path, "/")
	if path == "" {
		return ""
	}
	first := path
	if idx := strings.IndexByte(path, '/'); idx >= 0 {
		first = path[:idx]
	}
	first = strings.TrimSpace(first)
	if len(first) < 2 || len(first) > 5 {
		return ""
	}
	return "/" + first
}

func stripLanguagePrefix(path string, languages []pscatalog.LocaleOption) string {
	if path == "" {
		return "/"
	}
	codes := make(map[string]struct{}, len(languages))
	for _, language := range languages {
		code := strings.ToLower(strings.TrimSpace(language.Code))
		if code != "" {
			codes[code] = struct{}{}
		}
	}

	trimmed := strings.Trim(path, "/")
	if trimmed == "" {
		return "/"
	}
	parts := strings.Split(trimmed, "/")
	if _, ok := codes[strings.ToLower(parts[0])]; ok {
		parts = parts[1:]
	}
	if len(parts) == 0 {
		return "/"
	}
	return "/" + strings.Join(parts, "/")
}

func rebuildURL(path string, query url.Values) string {
	if path == "" {
		path = "/"
	}
	encoded := query.Encode()
	if encoded == "" {
		return path
	}
	return path + "?" + encoded
}
