package http

import (
	_const "chonho/const"
	"chonho/internal/api-v1/delivery/http-handler/controller"
	"chonho/internal/api-v1/usecase/authentication_usecase"
	"fmt"
	"net/http"
	"strings"

	"github.com/gin-gonic/gin"
)

type Handler struct {
	ginApp *gin.Engine

	// useCase
	authUseCase authentication_usecase.UseCase

	// Controller
	ApartmentController *controller.ApartmentController
	CategoryController  *controller.CategoryController
	StoreController     *controller.StoreController
	ProductController   *controller.ProductController
	UploadController    *controller.UploadController

	AuthController          *controller.AuthenticationController
	SellerProductController *controller.SellerProductController
	SellerStoreController   *controller.SellerStoreController
	SellerOrderController   *controller.SellerOrderController
	UserController          *controller.UserController
	OrderController         *controller.OrderController
}

type HandlerOption func(*Handler)

func NewHandler(options ...HandlerOption) *Handler {
	handler := &Handler{}
	for _, option := range options {
		option(handler)
	}
	return handler
}

func WithGinEngine(r *gin.Engine) HandlerOption {
	return func(handler *Handler) {
		handler.ginApp = r
	}
}

func WithAuthUseCase(uc authentication_usecase.UseCase) HandlerOption {
	return func(handler *Handler) {
		handler.authUseCase = uc
	}
}

func (h *Handler) Authorise(ctx *gin.Context) {
	// auth first
	h.Authentication(ctx)

	// validate user_repository
	_, exist := ctx.Get("user")
	if !exist {
		ctx.JSON(http.StatusUnauthorized, gin.H{
			"code":    _const.Unauthorized,
			"message": _const.ClientMessage[_const.Unauthorized],
			"title":   _const.ErrorTitle,
		})
		ctx.Abort()
		return
	}

	// TODO get user_repository role and resource

}

// Authentication check and pair user_repository if exist
func (h *Handler) Authentication(ctx *gin.Context) {
	token := ctx.GetHeader("Authorization")

	// get only token , remove Bearer
	token = strings.Replace(token, "Bearer ", "", 1)

	// validate token
	user, err := h.authUseCase.ParseJWTToken(token, ctx)
	if err != nil {
		fmt.Println(err)
		return
	}

	ctx.Set("user_id", user.Id)
	ctx.Set("user", user)
}
