package api

import (
	"errors"
	"log"
	"net/http"
	"time"

	jwt "github.com/dgrijalva/jwt-go"
	"gogs.carducci-dante.gov.it/karmen/config"
	"gogs.carducci-dante.gov.it/karmen/core/renderer"
)

func logoutHandler() http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		session, err := store.Get(r, "login-session")
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		session.Values["token"] = []uint8{}
		session.Save(r, w)

		http.Redirect(w, r, "/", http.StatusSeeOther)

	}
	return http.HandlerFunc(fn)
}

func loginHandler() http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		if r.Method == "GET" {
			if err := renderer.Render(w, "login", "login", nil); err != nil {
				panic(err)
			}
		}
		if r.Method == "POST" {
			r.ParseForm()
			token, err := getToken(r.FormValue("username"), r.FormValue("password"))
			if err != nil {
				panic(err)
			} else {
				session, err := store.Get(r, "login-session")
				if err != nil {
					panic(err)
				}

				session.Values["token"] = token
				session.Save(r, w)
				r.Method = "GET"
				http.Redirect(w, r, "/teachers", http.StatusSeeOther)
			}
		}
	}
	return http.HandlerFunc(fn)
}

func queryDB(username string, password string) (*User, error) {
	log.Println(username, config.Config.Admin.Username, password, config.Config.Admin.Password)
	if username == config.Config.Admin.Username && password == config.Config.Admin.Password {
		return &User{username, true}, nil
	}
	return nil, errors.New("Authentication failed!")
}

func getToken(username string, password string) ([]byte, error) {
	user, err := queryDB(username, password)
	if err != nil {
		return nil, err
	}

	/* Set token claims */
	claims := make(map[string]interface{})
	claims["admin"] = user.Admin
	claims["name"] = user.Name
	claims["exp"] = time.Now().Add(time.Hour * 24).Unix()

	/* Create the token */
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims(claims))

	/* Sign the token with our secret */
	tokenString, err := token.SignedString(signingKey)
	if err != nil {
		return nil, err
	}

	return []byte(tokenString), nil
}
