// service/achievement_service.go (дополнение)
package service

import (
	"api_bb/internal/models"
	"api_bb/internal/repository"
	"errors"
)

type AchievementService struct {
	achievementRepo repository.AchievementRepository
}

func NewAchievementService(achievementRepo repository.AchievementRepository) *AchievementService {
	return &AchievementService{
		achievementRepo: achievementRepo,
	}
}

// CreateAchievement создает новое достижение
func (s *AchievementService) CreateAchievement(userID uint, req models.AchievementCreateRequest) (*models.Achievement, error) {
	// Проверяем, нет ли уже достижения с таким названием у пользователя
	exists, err := s.achievementRepo.ExistsByTitleAndUser(userID, req.Title)
	if err != nil {
		return nil, err
	}
	if exists {
		return nil, ErrAchievementAlreadyExists
	}

	achievement := &models.Achievement{
		UserID:      userID,
		Type:        req.Type,
		Title:       req.Title,
		Description: req.Description,
		Result:      req.Result,
		Distance:    req.Distance,
		Date:        req.Date,
		BadgeImage:  req.BadgeImage,
		Verified:    false, // По умолчанию не подтверждено
	}

	if err := s.achievementRepo.Create(achievement); err != nil {
		return nil, err
	}

	return achievement, nil
}

// GetVerifiedAchievements возвращает только подтвержденные достижения пользователя
func (s *AchievementService) GetVerifiedAchievements(userID uint) ([]models.Achievement, error) {
	return s.achievementRepo.GetVerifiedByUserID(userID)
}

// GetVerifiedRecentAchievements возвращает последние подтвержденные достижения
func (s *AchievementService) GetVerifiedRecentAchievements(userID uint, limit int) ([]models.Achievement, error) {
	achievements, err := s.achievementRepo.GetRecentAchievements(userID, limit)
	if err != nil {
		return nil, err
	}

	// Фильтруем только подтвержденные
	var verified []models.Achievement
	for _, achievement := range achievements {
		if achievement.Verified {
			verified = append(verified, achievement)
		}
	}

	return verified, nil
}

// GetUserAchievements возвращает все достижения пользователя
func (s *AchievementService) GetUserAchievements(userID uint) ([]models.Achievement, error) {
	return s.achievementRepo.GetByUserID(userID)
}

// GetUserAchievementsSummary возвращает сводку по достижениям пользователя
func (s *AchievementService) GetUserAchievementsSummary(userID uint) (*models.UserAchievementsResponse, error) {
	return s.achievementRepo.GetUserAchievementsSummary(userID)
}

// VerifyAchievement подтверждает достижение
func (s *AchievementService) VerifyAchievement(achievementID uint, userID uint) error {
	// Проверяем, что достижение принадлежит пользователю
	achievement, err := s.achievementRepo.GetByID(achievementID)
	if err != nil {
		return err
	}

	if achievement.UserID != userID {
		return ErrAchievementNotFound
	}

	return s.achievementRepo.VerifyAchievement(achievementID)
}

// GetRecentAchievements возвращает последние достижения
func (s *AchievementService) GetRecentAchievements(userID uint, limit int) ([]models.Achievement, error) {
	return s.achievementRepo.GetRecentAchievements(userID, limit)
}

// GetAchievementsByType возвращает достижения по типу
func (s *AchievementService) GetAchievementsByType(userID uint, achievementType models.AchievementType) ([]models.Achievement, error) {
	return s.achievementRepo.GetByUserAndType(userID, achievementType)
}

// DeleteAchievement удаляет достижение
func (s *AchievementService) DeleteAchievement(achievementID uint, userID uint) error {
	// Проверяем, что достижение принадлежит пользователю
	achievement, err := s.achievementRepo.GetByID(achievementID)
	if err != nil {
		return err
	}

	if achievement.UserID != userID {
		return ErrAchievementNotFound
	}

	return s.achievementRepo.Delete(achievementID)
}

// GetAchievementByID возвращает достижение по ID
func (s *AchievementService) GetAchievementByID(achievementID uint, userID uint) (*models.Achievement, error) {
	achievement, err := s.achievementRepo.GetByID(achievementID)
	if err != nil {
		return nil, err
	}

	// Проверяем, что достижение принадлежит пользователю
	if achievement.UserID != userID {
		return nil, ErrAchievementNotFound
	}

	return achievement, nil
}

// UpdateAchievement обновляет достижение
func (s *AchievementService) UpdateAchievement(achievementID uint, userID uint, req models.AchievementCreateRequest) (*models.Achievement, error) {
	// Проверяем, что достижение принадлежит пользователю
	existingAchievement, err := s.achievementRepo.GetByID(achievementID)
	if err != nil {
		return nil, err
	}

	if existingAchievement.UserID != userID {
		return nil, ErrAchievementNotFound
	}

	// Проверяем, нет ли другого достижения с таким названием
	if existingAchievement.Title != req.Title {
		exists, err := s.achievementRepo.ExistsByTitleAndUser(userID, req.Title)
		if err != nil {
			return nil, err
		}
		if exists {
			return nil, ErrAchievementAlreadyExists
		}
	}

	// Обновляем данные
	existingAchievement.Type = req.Type
	existingAchievement.Title = req.Title
	existingAchievement.Description = req.Description
	existingAchievement.Result = req.Result
	existingAchievement.Distance = req.Distance
	existingAchievement.Date = req.Date
	existingAchievement.BadgeImage = req.BadgeImage

	if err := s.achievementRepo.Update(existingAchievement); err != nil {
		return nil, err
	}

	return existingAchievement, nil
}

// Ошибки
var (
	ErrAchievementAlreadyExists = errors.New("achievement with this title already exists")
	ErrAchievementNotFound      = errors.New("achievement not found")
)
