package user

import (
	"embed"
	"errors"
	"fmt"
	"github.com/go-chi/chi/v5"
	"github.com/go-chi/jwtauth/v5"
	"github.com/unrolled/render"
	"net/http"
	"time"
)

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

var ren *render.Render


var tokenAuth *jwtauth.JWTAuth

func Register(router chi.Router) {
	ren = render.New(render.Options{
		//Layout: "layout",
		FileSystem: &render.EmbedFileSystem{
			FS: webserver,
		},
	})

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

	tokenAuth = jwtauth.New("HS256", []byte("secret"), nil)

	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 login(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()


	uc := GetUserClient()
	res, _ := uc.login(r.FormValue("username"), r.FormValue("password"))
	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 register(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()


	uc := GetUserClient()
	res, _ := uc.register(r.FormValue("username"), r.FormValue("password"))
	if res {
		w.Write([]byte("Register ok"))
	} else {
		w.Write([]byte("Register failed"))
	}
}

type UserClient struct {
	users map[string]string
}

var u *UserClient

func GetUserClient() *UserClient {
	if u == nil {
		uc := UserClient{}
		uc.users = make(map[string]string)
		uc.users["admin"]="password"
		u = &uc
	}

	return u
}

func (uc *UserClient) register(username, password string) (bool, error) {
	if _, ok := uc.users[username]; ok {
		return false, errors.New("Username already used")
	}

	uc.users[username] = password
	return true, nil
}

func (uc UserClient) login(username, password string) (bool, error) {
	if val, ok := uc.users[username]; ok {
		fmt.Println("Login for valide user")
		if val == password {
			return true, nil
		}
	} else {
		fmt.Printf("User %v not found", username)
	}

	return false, nil
}