package service

import (
	"api_bb/internal/models"
	"api_bb/internal/repository"
	"api_bb/pkg/logger"
	"fmt"
	"time"

	"go.uber.org/zap"
)

type UserService interface {
	GetUserProfile(userID uint) (*models.User, error)
	UpdateProfile(user *models.User) error
	GetAllUsers() ([]models.User, error)
}

type userService struct {
	userRepo   repository.UserRepository
	jwtService JWTService
	logger     logger.LoggerInterface
}

// Обновление профиля
func (s *userService) UpdateProfile(user *models.User) error {
	s.logger.Info("Updating user profile",
		zap.Uint("user_id", user.ID),
	)

	// Проверяем, что пользователь существует
	existingUser, err := s.userRepo.FindByID(user.ID)
	if err != nil {
		s.logger.Error("User not found for profile update",
			zap.Uint("user_id", user.ID),
			zap.Error(err),
		)
		return fmt.Errorf("user not found")
	}

	// Убеждаемся, что email не меняется
	user.Email = existingUser.Email
	user.Avatar = existingUser.Avatar

	updateData := &models.User{
		ID:         user.ID,
		FirstName:  user.FirstName,
		LastName:   user.LastName,
		Avatar:     user.Avatar,
		Phone:      user.Phone,
		Experience: user.Experience,
		Goals:      user.Goals,
		Newsletter: user.Newsletter,
		UpdatedAt:  time.Now(),
	}

	return s.userRepo.UpdateExcludeEmail(updateData)
}

func NewUserService(userRepo repository.UserRepository, jwtService JWTService, log logger.LoggerInterface) userService {
	// Создаем логгер с контекстом для сервиса
	serviceLogger := log.With(zap.String("service", "user"))

	return userService{
		userRepo:   userRepo,
		jwtService: jwtService,
		logger:     serviceLogger,
	}
}

func (s *userService) GetAllUsers() ([]models.User, error) {
	s.logger.Info("Fetching all users")

	users, err := s.userRepo.FindAll()
	if err != nil {
		s.logger.Error("Failed to fetch users",
			zap.Error(err),
		)
		return nil, fmt.Errorf("failed to get users: %w", err)
	}

	s.logger.Debug("Successfully fetched users",
		zap.Int("count", len(users)),
	)
	return users, nil
}

func (s *authService) UpdateProfile(user *models.User) error {
	s.logger.Info("Updating user profile",
		zap.Uint("user_id", user.ID),
	)

	// Проверяем, что пользователь существует
	existingUser, err := s.userRepo.FindByID(user.ID)
	if err != nil {
		s.logger.Error("User not found for profile update",
			zap.Uint("user_id", user.ID),
			zap.Error(err),
		)
		return fmt.Errorf("user not found")
	}

	// Убеждаемся, что email не меняется
	user.Email = existingUser.Email
	user.Avatar = existingUser.Avatar

	updateData := &models.User{
		ID:         user.ID,
		FirstName:  user.FirstName,
		LastName:   user.LastName,
		Avatar:     user.Avatar,
		Phone:      user.Phone,
		Experience: user.Experience,
		Goals:      user.Goals,
		Newsletter: user.Newsletter,
		UpdatedAt:  time.Now(),
	}

	return s.userRepo.UpdateExcludeEmail(updateData)
}

func (s *userService) GetUserProfile(userID uint) (*models.User, error) {
	s.logger.Debug("Getting user profile",
		zap.Uint("user_id", userID),
	)

	user, err := s.userRepo.FindByID(userID)
	if err != nil {
		s.logger.Warn("Failed to get user profile",
			zap.Uint("user_id", userID),
			zap.Error(err),
		)
		return nil, err
	}

	return user, nil
}


