package main

import (
	"context"
	"encoding/json"
	"fmt"
	"html/template"
	"io"
	"log"
	"net/http"
	"strings"

	"github.com/labstack/echo/v4"
	"github.com/labstack/echo/v4/middleware"
	uuid "github.com/satori/go.uuid"
)

type Template struct {
	templates *template.Template
}

func (t *Template) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
	return t.templates.ExecuteTemplate(w, name, data)
}

func main() {
	e := echo.New()
	e.Use(middleware.Logger())

	t := &Template{
		templates: template.Must(template.ParseGlob("src/templates/*.html")),
	}
	e.Renderer = t

	e.Static("/static", "src/static")
	e.Static("/dist", "dist/")
	e.GET("/", HomeHandler)
	e.POST("/", HomeHandler)

	e.Logger.Fatal(e.Start(":1323"))
}

func HomeHandler(c echo.Context) error {
	config := getConfig()

	if c.Request().Method == "POST" {
		message := Message{
			Name:    c.FormValue("name"),
			Phone:   c.FormValue("phone"),
			Email:   c.FormValue("email"),
			Service: c.FormValue("service"),
			Note:    c.FormValue("note"),
			VIN:     c.FormValue("vin"),
		}
		// Validate
		message.Validate()
		if message.Errors > 0 {
			return c.Render(http.StatusOK, "index.html", Response{Error: "Opravte prosím chyby ve formuláři", Message: message})
		}

		// Store
		client, err := getDBClient()
		if err != nil {
			return c.Render(http.StatusOK, "index.html", Response{Error: err.Error(), Message: message})
		}

		db := client.DB(context.TODO(), config.CouchDBName)
		if err != nil {
			return c.Render(http.StatusOK, "index.html", Response{Error: err.Error(), Message: message})
		}

		body, err := json.Marshal(message)
		if err != nil {
			return c.Render(http.StatusOK, "index.html", Response{Error: err.Error(), Message: message})
		}

		messageUUID := uuid.NewV4()

		_, err = db.Put(context.TODO(), strings.Replace(messageUUID.String(), "-", "", -1), body)
		if err != nil {
			return c.Render(http.StatusOK, "index.html", Response{Error: err.Error(), Message: message})
		}

		go func() {
			msg := "Zpráva z rezervačního formuláře\n\n"
			msg += fmt.Sprintf("  Jméno: %s\n", message.Name)
			msg += fmt.Sprintf("  Telefon: %s\n", message.Phone)
			if message.Email != "" {
				msg += fmt.Sprintf("  Email: %s\n", message.Email)
			}
			if message.Email != "" {
				msg += fmt.Sprintf("  Služba: %s\n", message.Service)
			}
			if message.Email != "" {
				msg += fmt.Sprintf("  VIN: %s\n", message.VIN)
			}
			if message.Email != "" {
				msg += fmt.Sprintf("\nPoznámka:\n\n%s\n", message.Note)
			}

			err := sendEmail(config.SMTPHostname, config.SMTPUsername, config.SMTPPassword, config.EmailTo, config.EmailFrom, config.EmailSubject, msg, config.SMTPPort)
			if err != nil {
				log.Println("SMTP ERROR:", err)
			}
		}()

		return c.Redirect(http.StatusFound, "/?message=Zpráva odeslána")

	}
	return c.Render(http.StatusOK, "index.html", Response{StatusMessage: c.QueryParam("message")})
}
