package user

import (
	"bytes"
	"embed"
	"fmt"
	"github.com/go-chi/chi/v5"
	"github.com/go-chi/jwtauth/v5"
	"github.com/unrolled/render"
	gomail "gopkg.in/mail.v2"
	"io"
	"net/http"
	"time"
)

// content holds our static web server content.
//go:embed templates/*
var webserver embed.FS

var ren *render.Render

var uc UserClient

var tokenAuth *jwtauth.JWTAuth

var d *gomail.Dialer

func Register(router chi.Router, token *jwtauth.JWTAuth, userClient UserClient, dialer *gomail.Dialer) {
	uc = userClient
	ren = render.New(render.Options{
		//Layout: "layout",
		FileSystem: &render.EmbedFileSystem{
			FS: webserver,
		},
	})

	router.Get("/login", loginForm)
	router.Post("/login", login)
	router.Get("/register", registerForm)
	router.Post("/register", register)
	router.Get("/logout", logout)

	tokenAuth = token

	d = dialer

	router.Group(func(r chi.Router) {
		r.Use(jwtauth.Verifier(tokenAuth))
		r.Get("/me", func(w http.ResponseWriter, r *http.Request) {
			_, claims, _ := jwtauth.FromContext(r.Context())
			if val, ok := claims["username"]; ok {
				w.Write([]byte(fmt.Sprintf("hi %v", val)))
			} else {
				w.Write([]byte("Du bist nicht eingeloggt"))
			}

		})
	})


}

func loginForm(w http.ResponseWriter, r *http.Request) {
	ren.HTML(w, http.StatusOK, "login", nil)
}

func registerForm(w http.ResponseWriter, r *http.Request) {
	ren.HTML(w, http.StatusOK, "register", nil)
}

func login(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()


	res, _ := uc.login(r.FormValue("username"), r.FormValue("password"), false)
	if res {

		_, tokenstring, err := tokenAuth.Encode(map[string]interface{}{"username": r.FormValue("username")})
		if err != nil {
			panic(err)
		}
		expiration := time.Now().Add(365 * 24 * time.Hour)
		cookie    :=    http.Cookie{Name: "jwt",Value:tokenstring,Expires:expiration}
		http.SetCookie(w, &cookie)
		w.Write([]byte("Login ok"))
	} else {
		w.Write([]byte("Login failed"))
	}
}

func logout(w http.ResponseWriter, r *http.Request)  {
	cookie := http.Cookie{
		Name:       "jwt",
		Value:      "",
	}
	http.SetCookie(w, &cookie)
	w.Write([]byte("Du wurdest ausgeloggt"))
}

func register(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()

	res, err := uc.register(r.FormValue("username"), r.FormValue("password"), r.FormValue("email"))
	if err != nil || res == false {
		w.Write([]byte("Registration Failed"))
		return
	}

	rw := &LayoutMiddlewareResponseWriter{
		ResponseWriter: w,
		buf:            &bytes.Buffer{},
	}

	ren.HTML(rw, http.StatusOK, "token", map[string]string{"username": r.FormValue("username"), "url": "http://www.google.de"})

	content, err := io.ReadAll(rw.buf)
	if err != nil {
		panic(err)
	}

	m := gomail.NewMessage()
	m.SetHeader("From", "test@keks.cloud")
	m.SetHeader("To", "to@example.com")
	m.SetHeader("Subject", "Gomail test subject")
	m.SetBody("text/plain", "This is Gomail test body")
	m.SetBody("text/html", string(content))



	if err := d.DialAndSend(m); err != nil {
		fmt.Println(err)
		panic(err)
	}

}

type LayoutMiddlewareResponseWriter struct {
	http.ResponseWriter
	buf *bytes.Buffer
}

func (myrw *LayoutMiddlewareResponseWriter) Write(p []byte) (int, error) {
	return myrw.buf.Write(p)
}

