package handlers

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

	"github.com/gorilla/sessions"
)

type Handler struct {
	DB    *sql.DB
	Store *sessions.CookieStore
}

// Template helper functions
var funcMap = template.FuncMap{
	"formatMoney": func(amount float64) string {
		return fmt.Sprintf("$%.2f", amount)
	},
	"formatDate": func(date string) string {
		t, err := time.Parse("2006-01-02", date)
		if err != nil {
			return date
		}
		return t.Format("Jan 02, 2006")
	},
	"statusBadge": func(status string) template.HTML {
		colors := map[string]string{
			"draft":     "bg-gray-100 text-gray-800",
			"confirmed": "bg-blue-100 text-blue-800",
			"fulfilled": "bg-green-100 text-green-800",
			"cancelled": "bg-red-100 text-red-800",
			"pending":   "bg-yellow-100 text-yellow-800",
			"paid":      "bg-green-100 text-green-800",
			"overdue":   "bg-red-100 text-red-800",
		}
		color, ok := colors[status]
		if !ok {
			color = "bg-gray-100 text-gray-800"
		}
		return template.HTML(fmt.Sprintf(`<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium %s">%s</span>`, color, status))
	},
	"capitalize": func(s string) string {
		if len(s) == 0 {
			return s
		}
		return string(s[0]-32) + s[1:]
	},
	"accountTypeBadge": func(t string) template.HTML {
		colors := map[string]string{
			"asset":     "bg-blue-100 text-blue-800",
			"liability": "bg-red-100 text-red-800",
			"equity":    "bg-purple-100 text-purple-800",
			"revenue":   "bg-green-100 text-green-800",
			"expense":   "bg-orange-100 text-orange-800",
		}
		color, ok := colors[t]
		if !ok {
			color = "bg-gray-100 text-gray-800"
		}
		return template.HTML(fmt.Sprintf(`<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium %s">%s</span>`, color, t))
	},
	"sub": func(a, b float64) float64 {
		return a - b
	},
}

func (h *Handler) render(w http.ResponseWriter, templates []string, data interface{}) {
	paths := make([]string, len(templates))
	for i, t := range templates {
		paths[i] = filepath.Join("templates", t)
	}

	tmpl, err := template.New("").Funcs(funcMap).ParseFiles(paths...)
	if err != nil {
		http.Error(w, fmt.Sprintf("Template error: %v", err), http.StatusInternalServerError)
		return
	}

	if err := tmpl.ExecuteTemplate(w, "layout", data); err != nil {
		http.Error(w, fmt.Sprintf("Render error: %v", err), http.StatusInternalServerError)
	}
}

func (h *Handler) renderPartial(w http.ResponseWriter, templateFile string, templateName string, data interface{}) {
	path := filepath.Join("templates", templateFile)
	tmpl, err := template.New("").Funcs(funcMap).ParseFiles(path)
	if err != nil {
		http.Error(w, fmt.Sprintf("Template error: %v", err), http.StatusInternalServerError)
		return
	}

	if err := tmpl.ExecuteTemplate(w, templateName, data); err != nil {
		http.Error(w, fmt.Sprintf("Render error: %v", err), http.StatusInternalServerError)
	}
}

func (h *Handler) getUsername(r *http.Request) string {
	session, _ := h.Store.Get(r, "erp-session")
	if username, ok := session.Values["username"].(string); ok {
		return username
	}
	return ""
}
