package httpapp

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

type Config struct {
	Addr         string
	TemplatesDir string
	StaticDir    string
}

type App struct {
	cfg  Config
	tmpl *template.Template
	mux  *http.ServeMux
}

func New(cfg Config) (*App, error) {
	if cfg.TemplatesDir == "" {
		cfg.TemplatesDir = "web/templates"
	}
	if cfg.StaticDir == "" {
		cfg.StaticDir = "web/static"
	}

	tmpl, err := parseTemplates(cfg.TemplatesDir)
	if err != nil {
		return nil, err
	}

	a := &App{
		cfg:  cfg,
		tmpl: tmpl,
		mux:  http.NewServeMux(),
	}

	a.routes()
	return a, nil
}

func (a *App) Router() http.Handler {
	// Wrap the mux with basic middleware chain
	return requestID(logging(a.mux))
}

func (a *App) routes() {
	// Static
	fs := http.FileServer(http.Dir(a.cfg.StaticDir))
	a.mux.Handle("/static/", http.StripPrefix("/static/", fs))

	// Core pages
	a.mux.HandleFunc("/", a.handleDashboard)

	// Health & metrics
	a.mux.HandleFunc("/healthz", a.handleHealthz)
	a.mux.HandleFunc("/metrics", a.handleMetrics)
}

func parseTemplates(dir string) (*template.Template, error) {
	pattern := filepath.Join(dir, "*.html")
	files, err := filepath.Glob(pattern)
	if err != nil {
		return nil, err
	}
	if len(files) == 0 {
		return nil, fmt.Errorf("no templates found at %s", pattern)
	}

	funcs := template.FuncMap{
		"nowRFC3339": func() string { return time.Now().Format(time.RFC3339) },
	}

	t := template.New("root").Funcs(funcs)
	return t.ParseFiles(files...)
}
