package pkg

import (
	"fmt"
	"golang.org/x/text/message"
	"golang.org/x/text/number"
	"html/template"
	"io"
	"math"
	"net/http"
	"strconv"
	"time"
)

const overrideMethodName = "_method"

func templateFile(name string) string {
	return "web/template/" + name
}

func mustRenderTemplate(wr io.Writer, r *http.Request, layout string, filename string, data interface{}) {
	locale := getLocale(r)
	company := getCompany(r)
	user := getUser(r)
	t := template.New(filename)
	t.Funcs(template.FuncMap{
		"gettext":  locale.Get,
		"pgettext": locale.GetC,
		"currentLocale": func() string {
			return locale.Language.String()
		},
		"companyURI": func(uri string) string {
			return companyURI(company, uri)
		},
		"formatPrice": func(price string) string {
			p := message.NewPrinter(locale.Language)
			f, err := strconv.ParseFloat(price, 64)
			if err != nil {
				f = math.NaN()
			}
			return p.Sprintf(locale.CurrencyPattern, company.DecimalDigits, number.Decimal(f), company.CurrencySymbol)
		},
		"formatDate": func(time time.Time) string {
			return time.Format("02/01/2006")
		},
		"csrfToken": func() template.HTML {
			return template.HTML(fmt.Sprintf(`<input type="hidden" name="%s" value="%s">`, csrfTokenField, user.CsrfToken))
		},
		"addInputAttr": func(attr string, field *InputField) *InputField {
			field.Attributes = append(field.Attributes, template.HTMLAttr(attr))
			return field
		},
		"addSelectAttr": func(attr string, field *SelectField) *SelectField {
			field.Attributes = append(field.Attributes, template.HTMLAttr(attr))
			return field
		},
		"deleteMethod": func() template.HTML {
			return overrideMethodField(http.MethodDelete)
		},
		"putMethod": func() template.HTML {
			return overrideMethodField(http.MethodPut)
		},
	})
	if _, err := t.ParseFiles(templateFile(filename), templateFile(layout), templateFile("form.gohtml")); err != nil {
		panic(err)
	}
	if err := t.ExecuteTemplate(wr, layout, data); err != nil {
		panic(err)
	}
}

func companyURI(company *Company, uri string) string {
	if company == nil {
		return uri
	}
	return "/company/" + company.Slug + uri
}

func overrideMethodField(method string) template.HTML {
	return template.HTML(fmt.Sprintf(`<input type="hidden" name="%s" value="%s">`, overrideMethodName, method))
}
func mustRenderAppTemplate(w io.Writer, r *http.Request, filename string, data interface{}) {
	mustRenderTemplate(w, r, "app.gohtml", filename, data)
}

func mustRenderWebTemplate(w io.Writer, r *http.Request, filename string, data interface{}) {
	mustRenderTemplate(w, r, "web.gohtml", filename, data)
}
