package httpapi

import (
	"bytes"
	"crypto/sha256"
	"encoding/hex"
	"io/fs"
	"net/http"

	"git.vakhrushev.me/av/jellybit/web"
)

// assetVersion — короткий хеш изменяемых ассетов (css/js) для cache-busting.
// Шрифты и вендор адресуются по неизменному имени, их версионировать не нужно.
func assetVersion() (string, error) {
	h := sha256.New()
	for _, p := range []string{"static/css/jellybit.css", "static/js/app.js"} {
		b, err := web.FS.ReadFile(p)
		if err != nil {
			return "", err
		}
		_, _ = h.Write(b)
	}
	return hex.EncodeToString(h.Sum(nil))[:12], nil
}

// staticHandler отдаёт встроенную статику с длинным иммутабельным кэшем —
// URL версионируются через ?v=<assetVersion> в шаблонах, поэтому свежий
// деплой не отдаёт устаревший файл.
func staticHandler(fsys fs.FS) http.Handler {
	fileServer := http.FileServer(http.FS(fsys))
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Cache-Control", "public, max-age=31536000, immutable")
		fileServer.ServeHTTP(w, r)
	})
}

// badgeLabel — человекочитаемая подпись состояния для бейджа (см. handoff п.4).
// CSS-класс берётся отдельно как st-<state>; неизвестное состояние показываем
// как есть, чтобы не терять его в UI.
func badgeLabel(state string) string {
	switch state {
	case "catched":
		return "🎣 принято, добавляется"
	case "downloading":
		return "⬇ качается"
	case "completed":
		return "⬇ скачано"
	case "recognizing":
		return "🧠 распознаётся"
	case "linking":
		return "🔗 раскладка"
	case "review":
		return "🟡 на ревью"
	case "deferred":
		return "🕗 отложено"
	case "done":
		return "✅ готово"
	case "stuck":
		return "⏳ застряло"
	case "target_missing":
		return "⚠ нет цели"
	case "failed":
		return "⛔ ошибка"
	case "orphaned":
		return "⚠ потеряно"
	case "cancelled":
		return "✖ отменено"
	case "reverted":
		return "↩ откат"
	case "deleted":
		return "🗑 удалено"
	default:
		return state
	}
}

// render отрисовывает именованный шаблон в буфер и только затем пишет ответ —
// при ошибке шаблона клиент не получит «полустраницу».
func (s *server) render(w http.ResponseWriter, name string, data any) {
	var buf bytes.Buffer
	if err := s.tmpl.ExecuteTemplate(&buf, name, data); err != nil {
		s.deps.Logger.Error("render", "template", name, "error", err)
		http.Error(w, "внутренняя ошибка", http.StatusInternalServerError)
		return
	}
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	_, _ = buf.WriteTo(w)
}
