package User

import (
	config "astrology-api/configs"
	dto "astrology-api/dto"
	repositories "astrology-api/repositories"
	services "astrology-api/services"
	"net/http"
	"strconv"

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

type OrderAddressController struct {
	service services.OrderAddressService
}

func NewOrderAddressController() *OrderAddressController {

	db := config.DB

	repository := repositories.NewOrderAddressRepository(db)

	service := services.NewOrderAddressService(
		db,
		repository,
	)

	return &OrderAddressController{
		service: service,
	}
}

//
// Add Order Address
//
func (oc *OrderAddressController) AddOrderAddress(c *gin.Context) {

	var req dto.AddOrderAddressRequest

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

	userID := c.MustGet("user_id").(uint)

	address, err := oc.service.AddOrderAddress(userID, &req)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"message": err.Error(),
			"status":  500,
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message":    "Order address add successfully",
		"recordList": address,
		"status":     200,
	})
}

//
// Update Order Address
//
func (oc *OrderAddressController) UpdateOrderAddress(c *gin.Context) {

	id, err := strconv.ParseUint(c.Param("id"), 10, 64)
	if err != nil {

		c.JSON(http.StatusBadRequest, gin.H{
			"message": "Invalid Address ID",
			"status":  400,
		})
		return
	}

	var req dto.UpdateOrderAddressRequest

	if err := c.ShouldBindJSON(&req); err != nil {

		c.JSON(http.StatusBadRequest, gin.H{
			"error":  err.Error(),
			"status": 400,
		})
		return
	}

	userID := c.MustGet("user_id").(uint)

	address, err := oc.service.UpdateOrderAddress(
		uint(id),
		userID,
		&req,
	)

	if err != nil {

		if err == gorm.ErrRecordNotFound {

			c.JSON(http.StatusNotFound, gin.H{
				"message": "Order address not found",
				"status":  404,
			})
			return
		}

		c.JSON(http.StatusInternalServerError, gin.H{
			"message": err.Error(),
			"status":  500,
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message":    "Order address update successfully",
		"recordList": address,
		"status":     200,
	})
}

//
// Get Order Address List
//
func (oc *OrderAddressController) GetOrderAddresses(c *gin.Context) {

	var req dto.GetOrderAddressRequest

	if err := c.ShouldBindJSON(&req); err != nil {

		req.Search = ""
	}

	userID := c.MustGet("user_id").(uint)

	addresses, err := oc.service.GetOrderAddresses(
		userID,
		req.Search,
	)

	if err != nil {

		c.JSON(http.StatusInternalServerError, gin.H{
			"message": err.Error(),
			"status":  500,
		})
		return
	}

	if addresses == nil {
		addresses = []dto.OrderAddressResponse{}
	}

	c.JSON(http.StatusOK, gin.H{
		"recordList": addresses,
		"status":     200,
	})
}