package api

import (
	"errors"
	"net/http"
	"strings"

	"party.at/party/internal/data"
	"party.at/party/internal/validator"
	"party.at/party/cmd/party/common"
)

func (api *Api) CreateAuthenticationToken(w http.ResponseWriter, r *http.Request) {
	var input struct {
		Email    string `json:"email"`
		Password string `json:"password"`
	}

	if err := common.ReadJSON(w, r, &input); err != nil {
		api.errorResponse(w, r, data.ErrBadRequest)
		return
	}

	v := validator.New()
	v.Check(input.Email != "", "email", "must be provided")
	v.Check(input.Password != "", "password", "must be provided")
	if !v.Valid() {
		api.errorResponse(w, r, data.ErrValidationFailed.(*data.Error).WithDetails(v.Errors))
		return
	}

	token, err := api.App.LoginUser(input.Email, input.Password)
	if err != nil {
		switch {
		case errors.Is(err, data.ErrInvalidCredentials):
			api.errorResponse(w, r, data.ErrInvalidCredentials)
		default:
			api.ServerErrorResponse(w, r, err)
		}
		return
	}

	if err = common.WriteJSON(w, http.StatusCreated, common.Envelope{"authentication_token": token}, nil); err != nil {
		api.ServerErrorResponse(w, r, err)
	}
}

func (api *Api) DeleteAuthenticationToken(w http.ResponseWriter, r *http.Request) {
	authHeader := r.Header.Get("Authorization")
	parts := strings.Split(authHeader, " ")
	if len(parts) != 2 || parts[0] != "Bearer" {
		api.errorResponse(w, r, data.ErrInvalidAuthToken)
		return
	}

	token := parts[1]
	v := validator.New()
	if data.ValidateTokenPlaintext(v, token); !v.Valid() {
		api.errorResponse(w, r, data.ErrInvalidAuthToken)
		return
	}

	if err := api.App.DeleteToken(token); err != nil {
		api.ServerErrorResponse(w, r, err)
		return
	}

	if err := common.WriteJSON(w, http.StatusOK, common.Envelope{"message": "authentication token successfully deleted"}, nil); err != nil {
		api.ServerErrorResponse(w, r, err)
	}
}
