package handler

import (
	"apskel-pos-be/internal/contract"
	"apskel-pos-be/internal/models"
	"apskel-pos-be/internal/service"
	"net/http"

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

type OutletSettingHandlerImpl struct {
	outletSettingService service.OutletSettingService
}

func NewOutletSettingHandlerImpl(outletSettingService service.OutletSettingService) *OutletSettingHandlerImpl {
	return &OutletSettingHandlerImpl{
		outletSettingService: outletSettingService,
	}
}

func (h *OutletSettingHandlerImpl) CreateSetting(c *gin.Context) {
	var req models.CreateOutletSettingRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, contract.ErrorResponse{
			Error:   "Invalid request body",
			Message: err.Error(),
		})
		return
	}

	outletID, err := uuid.Parse(c.Param("outlet_id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, contract.ErrorResponse{
			Error:   "Invalid outlet ID",
			Message: "Outlet ID must be a valid UUID",
		})
		return
	}
	req.OutletID = outletID

	setting, err := h.outletSettingService.CreateSetting(c.Request.Context(), &req)
	if err != nil {
		c.JSON(http.StatusInternalServerError, contract.ErrorResponse{
			Error:   "Failed to create setting",
			Message: err.Error(),
		})
		return
	}

	c.JSON(http.StatusCreated, contract.SuccessResponse{
		Data: setting,
	})
}

func (h *OutletSettingHandlerImpl) UpdateSetting(c *gin.Context) {
	var req models.UpdateOutletSettingRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, contract.ErrorResponse{
			Error:   "Invalid request body",
			Message: err.Error(),
		})
		return
	}

	// Validate outlet ID from URL
	outletID, err := uuid.Parse(c.Param("outlet_id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, contract.ErrorResponse{
			Error:   "Invalid outlet ID",
			Message: "Outlet ID must be a valid UUID",
		})
		return
	}

	// Get key from URL
	key := c.Param("key")
	if key == "" {
		c.JSON(http.StatusBadRequest, contract.ErrorResponse{
			Error:   "Missing setting key",
			Message: "Setting key is required",
		})
		return
	}

	setting, err := h.outletSettingService.UpdateSetting(c.Request.Context(), outletID, key, &req)
	if err != nil {
		c.JSON(http.StatusInternalServerError, contract.ErrorResponse{
			Error:   "Failed to update setting",
			Message: err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, contract.SuccessResponse{
		Data: setting,
	})
}

func (h *OutletSettingHandlerImpl) GetSetting(c *gin.Context) {
	outletID, err := uuid.Parse(c.Param("outlet_id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, contract.ErrorResponse{
			Error:   "Invalid outlet ID",
			Message: "Outlet ID must be a valid UUID",
		})
		return
	}

	// Get key from URL
	key := c.Param("key")
	if key == "" {
		c.JSON(http.StatusBadRequest, contract.ErrorResponse{
			Error:   "Missing setting key",
			Message: "Setting key is required",
		})
		return
	}

	setting, err := h.outletSettingService.GetSetting(c.Request.Context(), outletID, key)
	if err != nil {
		c.JSON(http.StatusNotFound, contract.ErrorResponse{
			Error:   "Setting not found",
			Message: err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, contract.SuccessResponse{
		Data: setting,
	})
}

func (h *OutletSettingHandlerImpl) GetPrinterSettings(c *gin.Context) {
	outletID, err := uuid.Parse(c.Param("outlet_id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, contract.ErrorResponse{
			Error:   "Invalid outlet ID",
			Message: "Outlet ID must be a valid UUID",
		})
		return
	}

	settings, err := h.outletSettingService.GetPrinterSettings(c.Request.Context(), outletID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, contract.ErrorResponse{
			Error:   "Failed to get printer settings",
			Message: err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, contract.SuccessResponse{
		Data: settings,
	})
}

func (h *OutletSettingHandlerImpl) UpdatePrinterSettings(c *gin.Context) {
	var req models.UpdateOutletPrinterSettingsRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, contract.ErrorResponse{
			Error:   "Invalid request body",
			Message: err.Error(),
		})
		return
	}

	outletID, err := uuid.Parse(c.Param("outlet_id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, contract.ErrorResponse{
			Error:   "Invalid outlet ID",
			Message: "Outlet ID must be a valid UUID",
		})
		return
	}

	settings, err := h.outletSettingService.UpdatePrinterSettings(c.Request.Context(), outletID, &req)
	if err != nil {
		c.JSON(http.StatusInternalServerError, contract.ErrorResponse{
			Error:   "Failed to update printer settings",
			Message: err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, contract.SuccessResponse{
		Data: settings,
	})
}

// DeleteSetting deletes a specific outlet setting
func (h *OutletSettingHandlerImpl) DeleteSetting(c *gin.Context) {
	// Validate outlet ID from URL
	outletID, err := uuid.Parse(c.Param("outlet_id"))
	if err != nil {
		c.JSON(http.StatusBadRequest, contract.ErrorResponse{
			Error:   "Invalid outlet ID",
			Message: "Outlet ID must be a valid UUID",
		})
		return
	}

	// Get key from URL
	key := c.Param("key")
	if key == "" {
		c.JSON(http.StatusBadRequest, contract.ErrorResponse{
			Error:   "Missing setting key",
			Message: "Setting key is required",
		})
		return
	}

	err = h.outletSettingService.DeleteSetting(c.Request.Context(), outletID, key)
	if err != nil {
		c.JSON(http.StatusInternalServerError, contract.ErrorResponse{
			Error:   "Failed to delete setting",
			Message: err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, contract.SuccessResponse{
		Message: "Setting deleted successfully",
	})
}
