package restricted

import (
	"git.ma-al.com/goc_daniel/b2b/app/config"
	"git.ma-al.com/goc_daniel/b2b/app/model"
	"git.ma-al.com/goc_daniel/b2b/app/service/listService"
	"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
	"git.ma-al.com/goc_daniel/b2b/app/utils/nullable"
	"git.ma-al.com/goc_daniel/b2b/app/utils/query/query_params"
	"git.ma-al.com/goc_daniel/b2b/app/utils/response"
	"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
	"github.com/gofiber/fiber/v3"
)

// ListHandler handles endpoints that list various things (e.g. products or users)
type ListHandler struct {
	listService *listService.ListService
	config      *config.Config
}

// NewListHandler creates a new ListHandler instance
func NewListHandler() *ListHandler {
	listService := listService.New()
	return &ListHandler{
		listService: listService,
		config:      config.Get(),
	}
}

func ListHandlerRoutes(r fiber.Router) fiber.Router {
	handler := NewListHandler()

	r.Get("/list-products", handler.ListProducts)
	r.Get("/list-users", handler.ListUsers)

	return r
}

func (h *ListHandler) ListProducts(c fiber.Ctx) error {
	paging, filters, err := query_params.ParseFilters[model.Product](c, columnMappingListProducts)
	if err != nil {
		return c.Status(responseErrors.GetErrorStatus(err)).
			JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
	}

	id_lang, ok := c.Locals("langID").(uint)
	if !ok {
		return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
			JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
	}

	listing, err := h.listService.ListProducts(id_lang, paging, filters)
	if err != nil {
		return c.Status(responseErrors.GetErrorStatus(err)).
			JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
	}

	return c.JSON(response.Make(&listing.Items, int(listing.Count), i18n.T_(c, response.Message_OK)))
}

var columnMappingListProducts map[string]string = map[string]string{
	"product_id":    "ps.id_product",
	"name":          "pl.name",
	"reference":     "p.reference",
	"category_name": "cl.name",
	"category_id":   "cp.id_category",
	"quantity":      "sa.quantity",
}

func (h *ListHandler) ListUsers(c fiber.Ctx) error {
	paging, filters, err := query_params.ParseFilters[model.Customer](c, columnMappingListUsers)
	if err != nil {
		return c.Status(responseErrors.GetErrorStatus(err)).
			JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
	}

	id_lang, ok := c.Locals("langID").(uint)
	if !ok {
		return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
			JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
	}

	listing, err := h.listService.ListUsers(id_lang, paging, filters)
	if err != nil {
		return c.Status(responseErrors.GetErrorStatus(err)).
			JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
	}

	return c.JSON(response.Make(&listing.Items, int(listing.Count), i18n.T_(c, response.Message_OK)))
}

var columnMappingListUsers map[string]string = map[string]string{
	"user_id":     "users.id",
	"email":       "users.email",
	"first_name":  "users.first_name",
	"second_name": "users.second_name",
	"role":        "users.role",
}
