package controllers

import (
	"catalogue.midpdsa.com/src/db/catalogue"
	"github.com/gin-gonic/gin"
	"net/http"
	"strconv"

	"github.com/jackc/pgx/v5/pgtype"
)

type ExtraProductStockController struct {
	queries *catalogue.Queries
}

func NewExtraProductStockController(queries *catalogue.Queries) *ExtraProductStockController {
	return &ExtraProductStockController{queries: queries}
}

func (ctrl *ExtraProductStockController) GetExtraProductStocks(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.Atoi(idStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"})
		return
	}

	stock, err := ctrl.queries.GetExtraProductStocks(c.Request.Context(), int32(id))
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "not found"})
		return
	}
	c.JSON(http.StatusOK, stock)
}

type CreateExtraProductStockRequest struct {
	Quantity         int32 `json:"quantity" binding:"required"`
	FkIdExtraProduct int32 `json:"fk_id_extra_product" binding:"required"`
}

func (ctrl *ExtraProductStockController) CreateExtraProductStock(c *gin.Context) {
	var req CreateExtraProductStockRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	stock, err := ctrl.queries.CreateExtraProductStock(c.Request.Context(), catalogue.CreateExtraProductStockParams{
		Quantity: pgtype.Int4{Int32: req.Quantity, Valid: true},
		FkIdExtraProduct: pgtype.Int4{Int32: req.FkIdExtraProduct, Valid: true},
	})
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusCreated, stock)
}

func (ctrl *ExtraProductStockController) ListExtraProductStocks(c *gin.Context) {
	limit, offset := parsePagination(c)
	search := parseSearch(c)
	stocks, err := ctrl.queries.ListExtraProductStocks(c.Request.Context(), catalogue.ListExtraProductStocksParams{Limit: limit, Offset: offset, Search: search})
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, stocks)
}

type UpdateExtraProductStockRequest struct {
	Quantity         int32 `json:"quantity" binding:"required"`
	FkIdExtraProduct int32 `json:"fk_id_extra_product"`
}

func (ctrl *ExtraProductStockController) UpdateExtraProductStock(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.Atoi(idStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"})
		return
	}

	var req UpdateExtraProductStockRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	stock, err := ctrl.queries.UpdateExtraProductStock(c.Request.Context(), catalogue.UpdateExtraProductStockParams{
		ID:              int32(id),
		Quantity:        pgtype.Int4{Int32: req.Quantity, Valid: true},
		FkIdExtraProduct: pgtype.Int4{Int32: req.FkIdExtraProduct, Valid: req.FkIdExtraProduct != 0},
	})
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, stock)
}

func (ctrl *ExtraProductStockController) DeleteExtraProductStock(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.Atoi(idStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"})
		return
	}

	if _, err := ctrl.queries.DeleteExtraProductStock(c.Request.Context(), int32(id)); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"message": "deleted"})
}