package pdfhelper

import (
	"bytes"
	"html/template"
	"log"
	"os"
	"os/exec"
	"strconv"
	"strings"
	"time"

	"github.com/SebastiaanKlippert/go-wkhtmltopdf"
)

// pdf requestpdf struct
type RequestPdf struct {
	body string
}

// new request to pdf function
func NewRequestPdf(body string) *RequestPdf {
	return &RequestPdf{
		body: body,
	}
}

// parsing template function
func (r *RequestPdf) ParseTemplate(templatePath string, data interface{}) error {
	f := strings.Split(templatePath, "/")
	fileName := f[len(f)-1]
	funcs := template.FuncMap{
		"nl2br": func(text string) template.HTML {
			return template.HTML(strings.Replace(template.HTMLEscapeString(text), "\n", "<br>", -1))
		},
		"safeHTML": func(text string) template.HTML {
			return template.HTML(text)
		},
	}
	t, err := template.New(fileName).Funcs(funcs).ParseFiles(templatePath)
	if err != nil {
		return err
	}
	buf := new(bytes.Buffer)
	if err = t.Execute(buf, data); err != nil {
		return err
	}
	r.body = buf.String()

	return nil
}

func (r *RequestPdf) GenerateByCommand(pdfPath string, templatePath string, useA5Lanscape bool) (bool, error) {
	t := time.Now().Unix()
	var cmd *exec.Cmd

	if _, err := os.Stat("cloneTemplate/"); os.IsNotExist(err) {
		errDir := os.Mkdir("cloneTemplate/", 0777)
		if errDir != nil {
			log.Fatal(errDir)
		}
	}
	htmlName := strconv.FormatInt(int64(t), 10) + ".html"
	err := os.WriteFile("cloneTemplate/"+htmlName, []byte(r.body), 0644)
	if err != nil {
		panic(err)
	}

	if !useA5Lanscape {
		cmd = exec.Command("wkhtmltopdf", "--enable-local-file-access", "-L", "0", "-R", "0", "-B", "0", "-s", "A4", "cloneTemplate/"+htmlName, pdfPath)
	} else {
		cmd = exec.Command("wkhtmltopdf",
			"--enable-local-file-access",
			"-L", "0", // left margin
			"-R", "0", // right margin
			"-B", "0", // bottom margin
			"-T", "0", // top margin
			"-s", "A5", // page size A5
			"-O", "Landscape", // landscape mode
			"cloneTemplate/"+htmlName,
			pdfPath)
	}

	if err := cmd.Run(); err != nil {
		return false, err
	}
	dir, err := os.Getwd()
	if err != nil {
		panic(err)
	}
	defer os.RemoveAll(dir + "/cloneTemplate")
	return true, nil
}

// generate pdf function
func (r *RequestPdf) GeneratePDF(pdfPath string) (bool, error) {
	t := time.Now().Unix()

	if _, err := os.Stat("cloneTemplate/"); os.IsNotExist(err) {
		errDir := os.Mkdir("cloneTemplate/", 0777)
		if errDir != nil {
			log.Fatal(errDir)
		}
	}
	err1 := os.WriteFile("cloneTemplate/"+strconv.FormatInt(int64(t), 10)+".html", []byte(r.body), 0644)
	if err1 != nil {
		panic(err1)
	}

	f, err := os.Open("cloneTemplate/" + strconv.FormatInt(int64(t), 10) + ".html")
	if f != nil {
		defer f.Close()
	}
	if err != nil {
		log.Fatal(err)
	}

	pdfg, err := wkhtmltopdf.NewPDFGenerator()
	if err != nil {
		log.Fatal(err)
	}

	pdfg.AddPage(wkhtmltopdf.NewPageReader(f))

	pdfg.PageSize.Set(wkhtmltopdf.PageSizeA4)

	pdfg.Dpi.Set(300)

	err = pdfg.Create()
	if err != nil {
		log.Fatal(err)
	}

	err = pdfg.WriteFile(pdfPath)
	if err != nil {
		log.Fatal(err)
	}

	dir, err := os.Getwd()
	if err != nil {
		panic(err)
	}

	defer os.RemoveAll(dir + "/cloneTemplate")

	return true, nil
}
