package controller

import (
	"math"
	"strconv"
	"strings"

	"gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/dto"
	service "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/services"
	validation "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/validations"
	"gitlab.com/mbugroup/lti-api.git/internal/response"
	"gitlab.com/mbugroup/lti-api.git/internal/utils"

	"github.com/gofiber/fiber/v2"
)

type ProductWarehouseController struct {
	ProductWarehouseService service.ProductWarehouseService
}

func NewProductWarehouseController(productWarehouseService service.ProductWarehouseService) *ProductWarehouseController {
	return &ProductWarehouseController{
		ProductWarehouseService: productWarehouseService,
	}
}

func (u *ProductWarehouseController) GetAll(c *fiber.Ctx) error {
	query := &validation.Query{
		Page:            c.QueryInt("page", 1),
		Limit:           c.QueryInt("limit", 10),
		Search:          c.Query("search", ""),
		ProductId:       uint(c.QueryInt("product_id", 0)),
		WarehouseId:     uint(c.QueryInt("warehouse_id", 0)),
		LocationId:      uint(c.QueryInt("location_id", 0)),
		Flags:           c.Query("flags", ""),
		KandangId:       uint(c.QueryInt("kandang_id", 0)),
		AvailableOnly:   parseBoolQuery(c.Query("available_only", "")),
		TransferContext: c.Query(utils.TransferContextKey, ""),
		StockMode:       c.Query("stock_mode", ""),
		Type:            c.Query("type", ""),
	}

	if query.Page < 1 || query.Limit < 1 {
		return fiber.NewError(fiber.StatusBadRequest, "page and limit must be greater than 0")
	}

	result, totalResults, err := u.ProductWarehouseService.GetAll(c, query)
	if err != nil {
		return err
	}

	return c.Status(fiber.StatusOK).
		JSON(response.SuccessWithPaginate[dto.ProductWarehouseListDTO]{
			Code:    fiber.StatusOK,
			Status:  "success",
			Message: "Get all productWarehouses successfully",
			Meta: response.Meta{
				Page:         query.Page,
				Limit:        query.Limit,
				TotalPages:   int64(math.Ceil(float64(totalResults) / float64(query.Limit))),
				TotalResults: totalResults,
			},
			Data: dto.ToProductWarehouseListDTOs(result),
		})
}

func parseBoolQuery(raw string) bool {
	switch strings.TrimSpace(strings.ToLower(raw)) {
	case "1", "true", "yes", "y":
		return true
	default:
		return false
	}
}

func (u *ProductWarehouseController) GetOne(c *fiber.Ctx) error {
	param := c.Params("id")

	id, err := strconv.Atoi(param)
	if err != nil {
		return fiber.NewError(fiber.StatusBadRequest, "Invalid Id")
	}

	result, err := u.ProductWarehouseService.GetOne(c, uint(id))
	if err != nil {
		return err
	}

	return c.Status(fiber.StatusOK).
		JSON(response.Success{
			Code:    fiber.StatusOK,
			Status:  "success",
			Message: "Get productWarehouse successfully",
			Data:    dto.ToProductWarehouseListDTO(*result),
		})
}
