package repository

import (
	"api_yal/internal/models"
	"gorm.io/gorm"
)

// accountRepositoryImpl реализация интерфейса AccountRepository
type accountRepositoryImpl struct {
	db *gorm.DB
}

// NewAccountRepository создает новый экземпляр репозитория аккаунтов
func NewAccountRepository(db *gorm.DB) AccountRepository {
	return &accountRepositoryImpl{db: db}
}

// Create создает новый аккаунт
func (r *accountRepositoryImpl) Create(account *models.Account) error {
	return r.db.Create(account).Error
}

// GetByID возвращает аккаунт по ID
func (r *accountRepositoryImpl) GetByID(id uint) (*models.Account, error) {
	var account models.Account
	err := r.db.Preload("Objects").First(&account, id).Error
	if err != nil {
		return nil, err
	}
	return &account, nil
}

// GetByEmail возвращает аккаунт по email
func (r *accountRepositoryImpl) GetByEmail(email string) (*models.Account, error) {
	var account models.Account
	err := r.db.Preload("Objects").Where("email = ?", email).First(&account).Error
	if err != nil {
		return nil, err
	}
	return &account, nil
}

// Update обновляет существующий аккаунт
func (r *accountRepositoryImpl) Update(account *models.Account) error {
	return r.db.Save(account).Error
}

// Delete помечает аккаунт как удаленный
func (r *accountRepositoryImpl) Delete(id uint) error {
	return r.db.Delete(&models.Account{}, id).Error
}

// List возвращает список аккаунтов с пагинацией
func (r *accountRepositoryImpl) List(offset, limit int) ([]models.Account, error) {
	var accounts []models.Account
	err := r.db.Preload("Objects").Offset(offset).Limit(limit).Find(&accounts).Error
	if err != nil {
		return nil, err
	}
	return accounts, nil
}

// Count возвращает общее количество аккаунтов
func (r *accountRepositoryImpl) Count() (int64, error) {
	var count int64
	err := r.db.Model(&models.Account{}).Count(&count).Error
	return count, err
}

// Search находит аккаунты по email или полному имени
func (r *accountRepositoryImpl) Search(query string, offset, limit int) ([]models.Account, error) {
	var accounts []models.Account
	err := r.db.Preload("Objects").Where("email LIKE ? OR full_name LIKE ?", "%"+query+"%", "%"+query+"%").Offset(offset).Limit(limit).Find(&accounts).Error
	if err != nil {
		return nil, err
	}
	return accounts, nil
}

// GetObjects возвращает все объекты, принадлежащие аккаунту
func (r *accountRepositoryImpl) GetObjects(accountID uint) ([]models.Object, error) {
	var objects []models.Object
	err := r.db.Where("owner_id = ?", accountID).Find(&objects).Error
	if err != nil {
		return nil, err
	}
	return objects, nil
}

// CreatePasswordReset создаёт новую запись о сбросе пароля
func (r *accountRepositoryImpl) CreatePasswordReset(reset *models.PasswordReset) error {
	return r.db.Create(reset).Error
}

// GetPasswordResetByToken находит запись о сбросе пароля по токену
func (r *accountRepositoryImpl) GetPasswordResetByToken(token string) (*models.PasswordReset, error) {
	var reset models.PasswordReset
	err := r.db.Where("token = ?", token).First(&reset).Error
	if err != nil {
		return nil, err
	}
	return &reset, nil
}

// UpdatePasswordReset обновляет запись о сбросе пароля
func (r *accountRepositoryImpl) UpdatePasswordReset(reset *models.PasswordReset) error {
	return r.db.Save(reset).Error
}