package repositories

import (
	models "astrology-api/models/usermodel"

	"gorm.io/gorm"
)

type KundaliRepository interface {

	// Generate Kundali from Vedic Api :  Methods
	GetKundaliCount(userID uint) (int64, error)
	FindKundaliByID(id uint) (*models.Kundali, error)
	FindUserKundali(userID uint, kundaliID uint) (*models.Kundali, error)
	FindKundaliByUser(userID uint, kundaliID uint) (*models.Kundali, error)
	CreateKundali(tx *gorm.DB, kundali *models.Kundali) error
	UpdateKundali(tx *gorm.DB, kundali *models.Kundali) error
	GetUserWallet(userID uint) (*models.UserWallet, error)
	UpdateWallet(tx *gorm.DB, wallet *models.UserWallet) error
	CreateWalletTransaction(tx *gorm.DB, transaction *models.WalletTransaction) error
	GetVedicAPIKey() (string, error)

	// Users Generated Kundali Operation :  Methods
	GetUserKundalis(userID uint, search string) ([]models.Kundali, error)
	CountUserKundalis(userID uint) (int64, error)
	GetUserKundaliByID(userID uint, kundaliID uint) (*models.Kundali, error)
	UpdateKundaliDetails(tx *gorm.DB, kundali *models.Kundali) error
	DeleteKundali(tx *gorm.DB, kundali *models.Kundali) error
}

type kundaliRepository struct {
	db *gorm.DB
}

func NewKundaliRepository(db *gorm.DB) KundaliRepository {
	return &kundaliRepository{
		db: db,
	}
}

func (r *kundaliRepository) GetKundaliCount(userID uint) (int64, error) {
	var count int64

	err := r.db.
		Model(&models.Kundali{}).
		Where("createdBy = ?", userID).
		Count(&count).Error

	return count, err
}

func (r *kundaliRepository) FindKundaliByID(id uint) (*models.Kundali, error) {

	var kundali models.Kundali

	err := r.db.
		Where("id = ?", id).
		First(&kundali).Error

	if err != nil {
		return nil, err
	}

	return &kundali, nil
}

func (r *kundaliRepository) CreateKundali(tx *gorm.DB, kundali *models.Kundali) error {

	return tx.Create(kundali).Error

}

func (r *kundaliRepository) UpdateKundali(tx *gorm.DB, kundali *models.Kundali) error {

	return tx.Save(kundali).Error

}

func (r *kundaliRepository) GetUserWallet(userID uint) (*models.UserWallet, error) {

	var wallet models.UserWallet

	err := r.db.
		Where("userId = ?", userID).
		First(&wallet).Error

	if err != nil {
		return nil, err
	}

	return &wallet, nil
}

func (r *kundaliRepository) UpdateWallet(tx *gorm.DB, wallet *models.UserWallet) error {

	return tx.Save(wallet).Error

}

func (r *kundaliRepository) CreateWalletTransaction(
	tx *gorm.DB,
	transaction *models.WalletTransaction,
) error {

	return tx.Create(transaction).Error

}

func (r *kundaliRepository) GetVedicAPIKey() (string, error) {

	var flag models.SystemFlag

	err := r.db.
		Where("name = ?", "vedicAstroAPI").
		First(&flag).Error

	if err != nil {
		return "", err
	}

	return flag.Value, nil
}

func (r *kundaliRepository) FindUserKundali(
	userID uint,
	kundaliID uint,
) (*models.Kundali, error) {

	var kundali models.Kundali

	err := r.db.
		Where("id = ?", kundaliID).
		Where("createdBy = ?", int(userID)).
		First(&kundali).Error

	if err != nil {
		return nil, err
	}

	return &kundali, nil
}

func (r *kundaliRepository) FindKundaliByUser(
	userID uint,
	kundaliID uint,
) (*models.Kundali, error) {

	var kundali models.Kundali

	err := r.db.
		Where("id=? AND createdBy=?", kundaliID, userID).
		First(&kundali).Error

	if err != nil {
		return nil, err
	}

	return &kundali, nil
}

func (r *kundaliRepository) GetUserKundalis(
	userID uint,
	search string,
) ([]models.Kundali, error) {

	var kundalis []models.Kundali

	query := r.db.
		Model(&models.Kundali{}).
		Where("createdBy = ?", int(userID)).
		Where("forMatch = ?", "0").
		Order("created_at DESC")

	if search != "" {
		query = query.Where("name LIKE ?", "%"+search+"%")
	}

	err := query.Find(&kundalis).Error

	if err != nil {
		return nil, err
	}

	return kundalis, nil
}

func (r *kundaliRepository) CountUserKundalis(
	userID uint,
) (int64, error) {

	var count int64

	err := r.db.
		Model(&models.Kundali{}).
		Where("createdBy = ?", int(userID)).
		Where("forMatch = ?", "0").
		Count(&count).Error

	if err != nil {
		return 0, err
	}

	return count, nil
}

func (r *kundaliRepository) GetUserKundaliByID(
	userID uint,
	kundaliID uint,
) (*models.Kundali, error) {

	var kundali models.Kundali

	err := r.db.
		Where("id = ?", kundaliID).
		Where("createdBy = ?", int(userID)).
		First(&kundali).Error

	if err != nil {
		return nil, err
	}

	return &kundali, nil
}

func (r *kundaliRepository) UpdateKundaliDetails(
	tx *gorm.DB,
	kundali *models.Kundali,
) error {

	return tx.Save(kundali).Error
}

func (r *kundaliRepository) DeleteKundali(
	tx *gorm.DB,
	kundali *models.Kundali,
) error {

	return tx.Delete(kundali).Error
}
