package http

import (
	"context"
	"fmt"
	"net/http"

	"golang.org/x/text/language"

	"source.toby3d.me/toby3d/home/internal/common"
	"source.toby3d.me/toby3d/home/internal/domain"
	"source.toby3d.me/toby3d/home/internal/site"
)

type Handler struct {
	sites site.UseCase
}

func NewHandler(sites site.UseCase) *Handler {
	return &Handler{sites: sites}
}

func (h *Handler) Handle(ctx context.Context, head string) (*domain.Site, http.Handler, error) {
	lang := domain.NewLanguage(head)

	site, err := h.sites.Do(ctx, lang)
	if err != nil {
		return nil, nil, fmt.Errorf("cannot handle site: %w", err)
	}

	if !site.IsMultiLingual() || head != "" {
		return site, nil, nil
	}

	supported := make([]language.Tag, len(site.Languages))
	for i := range site.Languages {
		supported[i] = language.Make(site.Languages[i].Lang())
	}

	if site.DefaultLanguage != domain.LanguageUnd {
		supported = append([]language.Tag{language.Make(site.DefaultLanguage.Code())}, supported...)
	}

	return site, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		requested, _, _ := language.ParseAcceptLanguage(r.Header.Get(common.HeaderAcceptLanguage))
		if len(requested) == 0 {
			requested = append(requested, language.English)
		}

		matched, _, _ := language.NewMatcher(supported).Match(requested...)

		http.Redirect(w, r, "/"+domain.NewLanguage(matched.String()).Lang()+"/", http.StatusSeeOther)
	}), nil
}
