package repositories

import(
	"strconv"
	"gorm.io/gorm"

	"git.dynamicdiscord.de/kalipso/zineshop/models"
)	

type CartItemRepository interface {
	Create(models.CartItem) (models.CartItem, error)	
	GetAll() ([]models.CartItem, error)
	GetById(string) (models.CartItem, error)
	GetAllBySession(string) ([]models.CartItem, error)
	Update(models.CartItem) (models.CartItem, error)
	DeleteById(string) (error)
}

type GORMCartItemRepository struct {
	DB *gorm.DB
}

func NewGORMCartItemRepository(db *gorm.DB) CartItemRepository {
	return &GORMCartItemRepository{
		DB: db,
	}
}

func (r *GORMCartItemRepository) Create(cartItem models.CartItem) (models.CartItem, error) {
	//Omit the shopitem so it is not created again in db leading to unique constain fails
	result := r.DB.Omit("ShopItem").Create(&cartItem)
	if result.Error != nil {
		return models.CartItem{}, result.Error	
	}

	return cartItem, nil
}

func (r *GORMCartItemRepository) GetAll() ([]models.CartItem, error) {
	var cartItems []models.CartItem
	result := r.DB.Preload("ShopItem").Preload("ItemVariant").Find(&cartItems)

	return cartItems, result.Error
}

func (t *GORMCartItemRepository) GetById(id string) (models.CartItem, error) {
	cartItemId, err := strconv.Atoi(id)

	if err != nil {
		return models.CartItem{}, err
	}

	var cartItem models.CartItem
	result := t.DB.Preload("ShopItem").Preload("ItemVariant").First(&cartItem, uint(cartItemId))

	if result.Error != nil {
		return models.CartItem{}, result.Error
	}

	return cartItem, nil
}


func (r *GORMCartItemRepository) GetAllBySession(sessionId string) ([]models.CartItem, error) {
	var cartItems []models.CartItem
	result := r.DB.Preload("ShopItem").Preload("ItemVariant").Where("session_id = ?", sessionId).Find(&cartItems)

	return cartItems, result.Error

}

func (r *GORMCartItemRepository) Update(cartItem models.CartItem) (models.CartItem, error) {
	result := r.DB.Save(&cartItem)
	if result.Error != nil {
		return models.CartItem{}, result.Error
	}

	return cartItem, nil
}

func (r *GORMCartItemRepository) DeleteById(id string) error {
	cartItemId, err := strconv.Atoi(id)

	if err != nil {
		return err
	}

	result := r.DB.Omit("ShopItem").Omit("ItemVariant").Delete(&models.CartItem{}, cartItemId)
	return result.Error
}
