package handlers

import (
	"errors"
	"github.com/Pena-Co-Ltd/amocrm_templategen_back/dal/model"
	"github.com/Pena-Co-Ltd/amocrm_templategen_back/middleware"
	"github.com/dgrijalva/jwt-go"
	"go.uber.org/zap"
	"golang.org/x/crypto/bcrypt"
	"net/http"
	"time"
)

type RespRegistration struct {
	FullName string `json:"full-name" schema:"full-name,required"`
	Email    string `json:"email" schema:"email,required"`
	Password string `json:"password" schema:"password,required"`
}

func (h *Handlers) UserRegistration(w http.ResponseWriter, r *http.Request) {
	var resp RespRegistration

	err := decodePost(&resp, r)

	if err != nil {
		h.reportError(w, err, 500)
		return
	}

	id, err := h.dal.User.Insert(r.Context(), &model.User{
		FullName: resp.FullName,
		Email:    resp.Email,
		Password: resp.Password,
	})

	if err != nil {
		h.reportError(w, err, 500)
		return
	}

	// Set jwt token
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, &middleware.UserClaims{UserID: id, FullName: resp.FullName,
		Email: resp.Email})

	ss, err := token.SignedString(middleware.JwtSecret)

	if err != nil {
		h.reportError(w, err, 500)
		return
	}

	http.SetCookie(w, &http.Cookie{
		Name:   "Authorization",
		Value:  ss,
		MaxAge: 3600 * 24 * 30,
		Path:   "/",
	})

	sendResponse(w, 200, nil)
}

type RespLogin struct {
	Email    string `json:"email" schema:"email,required"`
	Password string `json:"password" schema:"password,required"`
}

func (h *Handlers) UserLogin(w http.ResponseWriter, r *http.Request) {
	var resp RespLogin

	err := decodePost(&resp, r)

	if err != nil {
		h.reportError(w, err, 500)
		return
	}

	user, err := h.dal.User.GetByEmail(r.Context(), resp.Email)

	if err != nil {
		h.reportError(w, err, 500)
		return
	}

	// Check password

	err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(resp.Password))

	if err != nil {
		h.reportError(w, errors.New("incorrect password"), http.StatusForbidden)
		return
	}

	// Set jwt token
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, &middleware.UserClaims{
		UserID:      user.ID,
		FullName:    user.FullName,
		Email:       user.Email,
		IsActivated: user.IsActivated,
	})

	ss, err := token.SignedString(middleware.JwtSecret)

	if err != nil {
		h.reportError(w, err, 500)
		return
	}

	http.SetCookie(w, &http.Cookie{
		Name:   "Authorization",
		Value:  ss,
		MaxAge: 3600 * 24 * 30,
		Path:   "/",
	})

	sendResponse(w, 200, nil)
}

func (h *Handlers) UserLogout(w http.ResponseWriter, r *http.Request) {
	http.SetCookie(w, &http.Cookie{
		Name:    "Authorization",
		Value:   "",
		MaxAge:  -1,
		Path:    "/",
		Expires: time.Unix(0, 0),
	})

	sendResponse(w, 200, nil)
}

func (h *Handlers) UserDelete(w http.ResponseWriter, r *http.Request) {
	user := getJwtUser(r)

	if user == nil {
		h.reportError(w, ErrorUnauthorized, http.StatusUnauthorized)
		return
	}

	err := h.dal.User.Delete(r.Context(), user.UserID)
	if err != nil {
		h.reportError(w, err, http.StatusInternalServerError)
		return
	}

	err = h.dal.YaDisk.DeleteByUserID(r.Context(), user.UserID)
	if err != nil {
		h.logger.Error("ErrorHandler", zap.Error(err))
	}

	http.SetCookie(w, &http.Cookie{
		Name:    "Authorization",
		Value:   "",
		MaxAge:  -1,
		Path:    "/",
		Expires: time.Unix(0, 0),
	})

	sendResponse(w, 200, nil)
}
