package lexicon

import (
	"encoding/json"
	"net/http"
	"net/url"

	"github.com/go-chi/chi/v5"
)

// Handler serves the word-lookup endpoint backed by a single shared Lexicon.
type Handler struct {
	Lex *Lexicon
}

// New constructs a Handler with a fresh (lazily-loaded) Lexicon.
func NewHandler() *Handler { return &Handler{Lex: New()} }

// Routes returns the router mounted at /api/word. The word is a path segment so
// "/api/word/happy" reads naturally; it's URL-decoded to tolerate the rare
// punctuated token.
func (h *Handler) Routes() chi.Router {
	r := chi.NewRouter()
	r.Get("/{word}", h.lookup)
	return r
}

// GlossRoutes returns the router mounted at /api/gloss — the lightweight
// Chinese-only lookup behind the inline hover/select gloss. It shares the
// Handler's Lexicon, so the datasets still load just once.
func (h *Handler) GlossRoutes() chi.Router {
	r := chi.NewRouter()
	r.Get("/{word}", h.gloss)
	return r
}

// lookup returns the definition + synonyms for one word. A word found in neither
// dataset still returns 200 with empty lists, so the popover can show a friendly
// "nothing found" rather than an error state.
func (h *Handler) lookup(w http.ResponseWriter, r *http.Request) {
	word := chi.URLParam(r, "word")
	if decoded, err := url.PathUnescape(word); err == nil {
		word = decoded
	}

	res, err := h.Lex.Lookup(word)
	if err != nil {
		w.Header().Set("Content-Type", "application/json")
		w.WriteHeader(http.StatusInternalServerError)
		_ = json.NewEncoder(w).Encode(map[string]string{"error": err.Error()})
		return
	}

	w.Header().Set("Content-Type", "application/json")
	// Word lookups are static for the life of the build; let the browser cache
	// them so repeated right-clicks on the same word are instant.
	w.Header().Set("Cache-Control", "public, max-age=86400")
	_ = json.NewEncoder(w).Encode(res)
}

// gloss returns just the Chinese translation for one word. Like lookup, a miss
// is a 200 with an empty gloss so the hover tooltip can quietly skip rather than
// error.
func (h *Handler) gloss(w http.ResponseWriter, r *http.Request) {
	word := chi.URLParam(r, "word")
	if decoded, err := url.PathUnescape(word); err == nil {
		word = decoded
	}

	res, err := h.Lex.Gloss(word)
	if err != nil {
		w.Header().Set("Content-Type", "application/json")
		w.WriteHeader(http.StatusInternalServerError)
		_ = json.NewEncoder(w).Encode(map[string]string{"error": err.Error()})
		return
	}

	w.Header().Set("Content-Type", "application/json")
	w.Header().Set("Cache-Control", "public, max-age=86400")
	_ = json.NewEncoder(w).Encode(res)
}
