package handlers

import (
	"net/http"
	"strconv"

	"sale/internal/models"
	"sale/internal/schemas"
	"sale/internal/utils"

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

type AddressHandler struct{}

func NewAddressHandler() *AddressHandler {
	return &AddressHandler{}
}

func (h *AddressHandler) List(c *gin.Context) {
	userID := c.GetUint("user_id")
	var addresses []models.Address
	utils.DB.Where("user_id = ?", userID).Order("is_default DESC, created_at DESC").Find(&addresses)
	c.JSON(http.StatusOK, gin.H{"data": addresses})
}

func (h *AddressHandler) Create(c *gin.Context) {
	userID := c.GetUint("user_id")
	var req schemas.CreateAddressRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	if req.IsDefault {
		utils.DB.Model(&models.Address{}).Where("user_id = ?", userID).Update("is_default", false)
	}

	address := models.Address{
		UserID:    userID,
		Name:      req.Name,
		Phone:     req.Phone,
		Province:  req.Province,
		City:      req.City,
		District:  req.District,
		Address:   req.Address,
		IsDefault: req.IsDefault,
	}

	utils.DB.Create(&address)
	c.JSON(http.StatusCreated, gin.H{"data": address})
}

func (h *AddressHandler) Update(c *gin.Context) {
	userID := c.GetUint("user_id")
	id, _ := strconv.Atoi(c.Param("id"))

	var address models.Address
	if err := utils.DB.Where("id = ? AND user_id = ?", id, userID).First(&address).Error; err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "Address not found"})
		return
	}

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

	updates := make(map[string]interface{})
	if req.Name != nil {
		updates["name"] = *req.Name
	}
	if req.Phone != nil {
		updates["phone"] = *req.Phone
	}
	if req.Province != nil {
		updates["province"] = *req.Province
	}
	if req.City != nil {
		updates["city"] = *req.City
	}
	if req.District != nil {
		updates["district"] = *req.District
	}
	if req.Address != nil {
		updates["address"] = *req.Address
	}
	if req.IsDefault != nil && *req.IsDefault {
		utils.DB.Model(&models.Address{}).Where("user_id = ?", userID).Update("is_default", false)
		updates["is_default"] = true
	}

	utils.DB.Model(&address).Updates(updates)
	c.JSON(http.StatusOK, gin.H{"data": address})
}

func (h *AddressHandler) Delete(c *gin.Context) {
	userID := c.GetUint("user_id")
	id, _ := strconv.Atoi(c.Param("id"))

	if err := utils.DB.Where("id = ? AND user_id = ?", id, userID).Delete(&models.Address{}).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to delete address"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "Address deleted successfully"})
}

func (h *AddressHandler) SetDefault(c *gin.Context) {
	userID := c.GetUint("user_id")
	id, _ := strconv.Atoi(c.Param("id"))

	var address models.Address
	if err := utils.DB.Where("id = ? AND user_id = ?", id, userID).First(&address).Error; err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "Address not found"})
		return
	}

	utils.DB.Model(&models.Address{}).Where("user_id = ?", userID).Update("is_default", false)
	utils.DB.Model(&address).Update("is_default", true)

	c.JSON(http.StatusOK, gin.H{"message": "Default address set successfully"})
}
