package main

import (
	"fmt"
	"html/template"
	"log"
	"os"
	"path/filepath"
	"time"

	"github.com/gin-gonic/gin"
)

var tm *TemplateManager

func init() {
	tm = NewTemplateManager("templates", "base", "html")
}

type TemplateManager struct {
	templates map[string]*template.Template
	funcs     template.FuncMap
	base      string
	ext       string
	dir       string
}

// NewTemplateManager initializes the manager and loads templates
func NewTemplateManager(dir string, base string, ext string) *TemplateManager {
	tm := &TemplateManager{
		templates: make(map[string]*template.Template),
		funcs: template.FuncMap{
			"fmtTime": func(t time.Time) string {
				return t.Local().Format("2006-01-02 15:04") // Go’s reference time
			},
		},
		base: base,
		dir:  dir,
		ext:  ext,
	}
	tm.LoadTemplates()

	return tm
}

// LoadTemplates parses the base template with each view template in the directory
func (tm *TemplateManager) LoadTemplates() {
	pattern := filepath.Join(tm.dir, "*."+tm.ext)
	files, err := filepath.Glob(pattern)
	if err != nil {
		panic(err)
	}
	base := filepath.Join(tm.dir, tm.base+"."+tm.ext)

	for _, file := range files {
		if filepath.Base(file) == tm.base {
			continue
		}

		name := stripAfterDot(filepath.Base(file))
		logger.Println(name)

		// Parse base + view template together
		tpl, err := template.New(name).
			Funcs(tm.funcs).
			ParseFiles(base, file)
		if err != nil {
			panic(err)
		}

		tm.templates[name] = tpl
	}
}

// Render executes a template by name into the given context
func (tm *TemplateManager) Render(c *gin.Context, name string, data gin.H) error {
	print("\nRendering template:", name, "\n")
	u := getSessionUser(c)
	data["CurrentUser"] = u

	tpl, ok := tm.templates[name]
	if !ok {
		return os.ErrNotExist
	}
	fmt.Print(tm.templates[name])

	if err := tpl.ExecuteTemplate(c.Writer, tm.base, data); err != nil {
		log.Println("tpl error:", err)
		c.Status(500)
		return err
	}

	return nil
}
