package repositories

import (
	"errors"
	"time"

	"gorm.io/gorm"

	"github.com/treytartt/honeydue-api/internal/models"
)

var (
	ErrAdminNotFound = errors.New("admin user not found")
	ErrAdminExists   = errors.New("admin user already exists")
)

// AdminRepository handles admin user database operations
type AdminRepository struct {
	db *gorm.DB
}

// NewAdminRepository creates a new admin repository
func NewAdminRepository(db *gorm.DB) *AdminRepository {
	return &AdminRepository{db: db}
}

// FindByID finds an admin user by ID
func (r *AdminRepository) FindByID(id uint) (*models.AdminUser, error) {
	var admin models.AdminUser
	if err := r.db.First(&admin, id).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, ErrAdminNotFound
		}
		return nil, err
	}
	return &admin, nil
}

// FindByEmail finds an admin user by email (case-insensitive)
func (r *AdminRepository) FindByEmail(email string) (*models.AdminUser, error) {
	var admin models.AdminUser
	if err := r.db.Where("LOWER(email) = LOWER(?)", email).First(&admin).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, ErrAdminNotFound
		}
		return nil, err
	}
	return &admin, nil
}

// Create creates a new admin user
func (r *AdminRepository) Create(admin *models.AdminUser) error {
	// Check if email already exists
	var count int64
	if err := r.db.Model(&models.AdminUser{}).Where("LOWER(email) = LOWER(?)", admin.Email).Count(&count).Error; err != nil {
		return err
	}
	if count > 0 {
		return ErrAdminExists
	}

	return r.db.Create(admin).Error
}

// Update updates an admin user
func (r *AdminRepository) Update(admin *models.AdminUser) error {
	return r.db.Save(admin).Error
}

// Delete deletes an admin user
func (r *AdminRepository) Delete(id uint) error {
	return r.db.Delete(&models.AdminUser{}, id).Error
}

// UpdateLastLogin updates the last login timestamp
func (r *AdminRepository) UpdateLastLogin(id uint) error {
	now := time.Now()
	return r.db.Model(&models.AdminUser{}).Where("id = ?", id).Update("last_login", now).Error
}

// List returns all admin users with pagination
func (r *AdminRepository) List(page, pageSize int) ([]models.AdminUser, int64, error) {
	var admins []models.AdminUser
	var total int64

	// Get total count
	if err := r.db.Model(&models.AdminUser{}).Count(&total).Error; err != nil {
		return nil, 0, err
	}

	// Get paginated results
	offset := (page - 1) * pageSize
	if err := r.db.Order("created_at DESC").Offset(offset).Limit(pageSize).Find(&admins).Error; err != nil {
		return nil, 0, err
	}

	return admins, total, nil
}

// ExistsByEmail checks if an admin user with the given email exists
func (r *AdminRepository) ExistsByEmail(email string) (bool, error) {
	var count int64
	if err := r.db.Model(&models.AdminUser{}).Where("LOWER(email) = LOWER(?)", email).Count(&count).Error; err != nil {
		return false, err
	}
	return count > 0, nil
}
