package cartsRepo

import (
	"git.ma-al.com/goc_daniel/b2b/app/db"
	"git.ma-al.com/goc_daniel/b2b/app/model"
	constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data"
)

type UICartsRepo interface {
	CartsAmount(user_id uint) (uint, error)
	CreateNewCart(user_id uint) (model.CustomerCart, error)
	UserHasCart(user_id uint, cart_id uint) (uint, error)
	UpdateCartName(user_id uint, cart_id uint, new_name string) error
	RetrieveCartsInfo(user_id uint) ([]model.CustomerCart, error)
	RetrieveCart(user_id uint, cart_id uint) (*model.CustomerCart, error)
	CheckProductExists(product_id uint, product_attribute_id *uint) (uint, error)
	AddProduct(user_id uint, cart_id uint, product_id uint, product_attribute_id *uint, amount uint) error
}

type CartsRepo struct{}

func New() UICartsRepo {
	return &CartsRepo{}
}

func (repo *CartsRepo) CartsAmount(user_id uint) (uint, error) {
	var amt uint

	err := db.DB.
		Table("b2b_customer_carts").
		Select("COUNT(*) AS amt").
		Where("user_id = ?", user_id).
		Scan(&amt).
		Error

	return amt, err
}

func (repo *CartsRepo) CreateNewCart(user_id uint) (model.CustomerCart, error) {
	var name string
	name = constdata.DEFAULT_NEW_CART_NAME

	cart := model.CustomerCart{
		UserID: user_id,
		Name:   &name,
	}
	err := db.DB.Create(&cart).Error

	return cart, err
}

func (repo *CartsRepo) UserHasCart(user_id uint, cart_id uint) (uint, error) {
	var amt uint

	err := db.DB.
		Table("b2b_customer_carts").
		Select("COUNT(*) AS amt").
		Where("user_id = ? AND cart_id = ?", user_id, cart_id).
		Scan(&amt).
		Error

	return amt, err
}

func (repo *CartsRepo) UpdateCartName(user_id uint, cart_id uint, new_name string) error {
	err := db.DB.
		Table("b2b_customer_carts").
		Where("user_id = ? AND cart_id = ?", user_id, cart_id).
		Update("name", new_name).
		Error

	return err
}

func (repo *CartsRepo) RetrieveCartsInfo(user_id uint) ([]model.CustomerCart, error) {
	var carts []model.CustomerCart

	err := db.DB.
		Table("b2b_customer_carts").
		Where("user_id = ?", user_id).
		Scan(&carts).
		Error

	return carts, err
}

func (repo *CartsRepo) RetrieveCart(user_id uint, cart_id uint) (*model.CustomerCart, error) {
	var cart model.CustomerCart

	err := db.DB.
		Preload("Products").
		Where("user_id = ? AND cart_id = ?", user_id, cart_id).
		First(&cart).
		Error

	return &cart, err
}

func (repo *CartsRepo) CheckProductExists(product_id uint, product_attribute_id *uint) (uint, error) {
	var amt uint

	if product_attribute_id == nil {
		err := db.DB.
			Table("ps_product_shop").
			Select("COUNT(*) AS amt").
			Where("id_product = ?", product_id).
			Scan(&amt).
			Error
		return amt, err

	} else {
		err := db.DB.
			Table("ps_product_shop AS ps").
			Joins("INNER JOIN ps_product_attribute_shop AS pas ON pas.id_product = ps.id_product").
			Select("COUNT(*) AS amt").
			Where("ps.id_product = ? AND pas.id_product_attribute = ?", product_id, *product_attribute_id).
			Scan(&amt).
			Error
		return amt, err
	}
}

func (repo *CartsRepo) AddProduct(user_id uint, cart_id uint, product_id uint, product_attribute_id *uint, amount uint) error {
	product := model.CartProduct{
		CartID:             cart_id,
		ProductID:          product_id,
		ProductAttributeID: product_attribute_id,
		Amount:             amount,
	}
	err := db.DB.Create(&product).Error

	return err
}
