package controllers

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

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

type ShockStockController struct {
	queries *catalogue.Queries
}

func NewShockStockController(queries *catalogue.Queries) *ShockStockController {
	return &ShockStockController{queries: queries}
}

func (ctrl *ShockStockController) GetShockStocksByShockSpec(c *gin.Context) {
	shockSpecIDStr := c.Param("shock_spec_id")
	shockSpecID, err := strconv.Atoi(shockSpecIDStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid shock spec id"})
		return
	}

	stocks, err := ctrl.queries.GetShockStocksByShockSpec(c.Request.Context(), pgtype.Int4{Int32: int32(shockSpecID), Valid: true})
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, stocks)
}

func (ctrl *ShockStockController) GetShockStocks(c *gin.Context) {
	limit, offset := parsePagination(c)
	search := parseSearch(c)
	stocks, err := ctrl.queries.GetShockStocks(c.Request.Context(), catalogue.GetShockStocksParams{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 CreateShockStockRequest struct {
	Quantity  int32 `json:"quantity" binding:"required"`
	FkIdShock int32 `json:"fk_id_shock" binding:"required"`
}

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

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

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

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

type UpdateShockStockRequest struct {
	Quantity  int32 `json:"quantity" binding:"required"`
	FkIdShock int32 `json:"fk_id_shock"`
}

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

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

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

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

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