package web

import (
	"html/template"
	"net/http"
	"path/filepath"
	"time"
)

// RobotsNone is used for private, protected, expired, or temporary pages.
const RobotsNone = "noindex,nofollow,noarchive"

type Renderer struct {
	templates  map[string]*template.Template
	appName    string
	appVersion string
	baseURL    string
}

type PageData struct {
	AppName      string
	AppVersion   string
	BaseURL      string
	CanonicalURL string
	Robots       string
	OGType       string
	Title        string
	Description  string
	ImageURL     string
	ImageAlt     string
	ImageType    string
	MediaURL     string
	MediaType    string
	CurrentYear  int
	CurrentUser  any
	CSRFToken    string
	Data         any
}

func NewRenderer(templateDir, appName, appVersion, baseURL string) (*Renderer, error) {
	layouts, err := filepath.Glob(filepath.Join(templateDir, "layouts", "*.html"))
	if err != nil {
		return nil, err
	}

	partials, err := filepath.Glob(filepath.Join(templateDir, "partials", "*.html"))
	if err != nil {
		return nil, err
	}

	pages, err := filepath.Glob(filepath.Join(templateDir, "pages", "*.html"))
	if err != nil {
		return nil, err
	}

	templates := make(map[string]*template.Template, len(pages))
	for _, page := range pages {
		files := append([]string{}, layouts...)
		files = append(files, partials...)
		files = append(files, page)

		parsed, err := template.ParseFiles(files...)
		if err != nil {
			return nil, err
		}

		templates[filepath.Base(page)] = parsed
	}

	return &Renderer{
		templates:  templates,
		appName:    appName,
		appVersion: appVersion,
		baseURL:    baseURL,
	}, nil
}

func (r *Renderer) Render(w http.ResponseWriter, status int, page string, data PageData) {
	data.AppName = r.appName
	data.AppVersion = r.appVersion
	data.BaseURL = r.baseURL
	data.CurrentYear = time.Now().Year()

	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	w.WriteHeader(status)

	tmpl, ok := r.templates[page]
	if !ok {
		http.Error(w, "template not found", http.StatusInternalServerError)
		return
	}

	if err := tmpl.ExecuteTemplate(w, page, data); err != nil {
		http.Error(w, "template render error", http.StatusInternalServerError)
	}
}
