package render

import (
	"bytes"
	"os"
	"regexp"
	"strings"
	"text/template"

	"github.com/spf13/viper"
)

type Render struct {
	tmpl *template.Template
}

const timeOutputLayout = "2006-01-02 15:04:05 MST"

var tmplFuncs = template.FuncMap{
	"toUpper": strings.ToUpper,
	"toLower": strings.ToLower,
	"join": func(sep string, s []string) string {
		return strings.Join(s, sep)
	},
	"reMatch": func(pattern, text string) bool {
		re := regexp.MustCompile(pattern)
		return re.MatchString(text)
	},
	"reReplaceAll": func(pattern, repl, text string) string {
		re := regexp.MustCompile(pattern)
		return re.ReplaceAllString(text, repl)
	},
	"reSubmatch": func(pattern, text string) []string {
		re := regexp.MustCompile(pattern)
		return re.FindStringSubmatch(text)
	},
	"reAllSubmatch": func(pattern, text string) [][]string {
		re := regexp.MustCompile(pattern)
		return re.FindAllStringSubmatch(text, -1)
	},
	"unique": func(s []string) []string {
		set := make(map[string]struct{})
		for _, v := range s {
			set[v] = struct{}{}
		}
		us := make([]string, 0, len(set))
		for v := range set {
			us = append(us, v)
		}
		return us
	},
	"stringSlice": func(s ...string) []string {
		return s
	},
	"appendString": func(s []string, es ...string) []string {
		return append(s, es...)
	},
}

func New() (*Render, error) {
	tmplPath := viper.GetString("template-file")

	b, err := os.ReadFile(tmplPath)
	if err != nil {
		return nil, err
	}
	tmplStr := string(b)

	tmpl, err := template.New("").Funcs(tmplFuncs).Parse(tmplStr)
	if err != nil {
		return nil, err
	}
	return &Render{tmpl: tmpl}, nil
}

func (r *Render) Render(tmplName string, data map[string]interface{}) (title string, text string, color string, err error) {
	data["DefaultTimeFormat"] = timeOutputLayout

	textTmplName := tmplName + ".text"
	titleTmplName := tmplName + ".title"
	colorTmplName := tmplName + ".color"

	var buf bytes.Buffer
	err = r.tmpl.ExecuteTemplate(&buf, textTmplName, data)
	if err != nil {
		return "", "", "", err
	}
	// text = strings.ReplaceAll(buf.String(), "\n", "\\n")
	text = buf.String()

	buf.Reset()
	err = r.tmpl.ExecuteTemplate(&buf, titleTmplName, data)
	if err != nil {
		return "", "", "", err
	}
	// title := strings.ReplaceAll(buf.String(), "\n", "\\n")
	title = buf.String()

	buf.Reset()
	err = r.tmpl.ExecuteTemplate(&buf, colorTmplName, data)
	if err != nil {
		return "", "", "", err
	}
	color = buf.String()

	return title, text, color, nil
}
