package repository

import (
	"api_bb/internal/models"
	"fmt"

	"gorm.io/gorm"
)

type UserRepository interface {
	Create(user *models.User) error
	FindByID(id uint) (*models.User, error)
	FindByEmail(email string) (*models.User, error)
	Update(user *models.User) error
	Delete(id uint) error
	UpdateExcludeEmail(userUpdate *models.User) error
	UpdateAvatar(userID uint, avatarPath string) error
	FindAll() ([]models.User, error)
	MarkEmailAsVerified(userID uint) error
	UpdatePassword(userID uint, newPassword string) error
	GetUserByID(id uint) (*models.User, error)
}

func (r *userRepository) UpdateAvatar(userID uint, avatarPath string) error {
	result := r.db.Model(&models.User{}).Where("id = ?", userID).Update("avatar", avatarPath)
	if result.Error != nil {
		return result.Error
	}
	if result.RowsAffected == 0 {
		return fmt.Errorf("user not found")
	}
	return nil
}

type userRepository struct {
	db *gorm.DB
}

func NewUserRepository(db *gorm.DB) UserRepository {
	return &userRepository{db: db}
}

// Add to userRepository implementation
func (r *userRepository) FindAll() ([]models.User, error) {
	var users []models.User
	err := r.db.Find(&users).Error
	return users, err
}

func (r *userRepository) Create(user *models.User) error {
	return r.db.Create(user).Error
}

func (r *userRepository) FindByID(id uint) (*models.User, error) {
	var user models.User
	err := r.db.First(&user, id).Error
	return &user, err
}

func (r *userRepository) FindByEmail(email string) (*models.User, error) {
	var user models.User
	err := r.db.Where("email = ?", email).First(&user).Error
	return &user, err
}

func (r *userRepository) Update(user *models.User) error {
	return r.db.Save(user).Error
}

func (r *userRepository) Delete(id uint) error {
	return r.db.Delete(&models.User{}, id).Error
}

// repository/user_repository.go
func (r *userRepository) UpdateExcludeEmail(userUpdate *models.User) error {
	result := r.db.Model(userUpdate).Where("id = ?", userUpdate.ID).Updates(map[string]interface{}{
		"first_name": userUpdate.FirstName,
		"last_name":  userUpdate.LastName,
		"avatar":     userUpdate.Avatar, // Добавить обновление аватара
		"phone":      userUpdate.Phone,
		"experience": userUpdate.Experience,
		"goals":      userUpdate.Goals,
		"newsletter": userUpdate.Newsletter,
		"updated_at": userUpdate.UpdatedAt,
	})

	if result.Error != nil {
		return result.Error
	}

	if result.RowsAffected == 0 {
		return fmt.Errorf("user not found")
	}

	return nil
}

// MarkEmailAsVerified помечает email пользователя как верифицированный
func (r userRepository) MarkEmailAsVerified(userID uint) error {
	result := r.db.Model(&models.User{}).Where("id = ?", userID).Update("email_verified", true)
	if result.Error != nil {
		return result.Error
	}
	if result.RowsAffected == 0 {
		return fmt.Errorf("user not found")
	}
	return nil
}

// UpdatePassword обновляет пароль пользователя
func (r userRepository) UpdatePassword(userID uint, newPassword string) error {
	result := r.db.Model(&models.User{}).Where("id = ?", userID).Update("password", newPassword)
	if result.Error != nil {
		return result.Error
	}
	if result.RowsAffected == 0 {
		return fmt.Errorf("user not found")
	}
	return nil
}

func (r userRepository) GetUserByID(id uint) (*models.User, error) {
	var user models.User
	err := r.db.First(&user, id).Error
	return &user, err
}
