package repository

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

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

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

// Create создает новый отзыв
func (r *feedbackRepositoryImpl) Create(feedback *models.Feedback) error {
	return r.db.Create(feedback).Error
}

// GetByID возвращает отзыв по ID
func (r *feedbackRepositoryImpl) GetByID(id uint) (*models.Feedback, error) {
	var feedback models.Feedback
	err := r.db.Preload("Owner").Preload("Object").Preload("Comments").First(&feedback, id).Error
	if err != nil {
		return nil, err
	}
	return &feedback, nil
}

// Update обновляет существующий отзыв
func (r *feedbackRepositoryImpl) Update(feedback *models.Feedback) error {
	return r.db.Save(feedback).Error
}

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

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

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

// ListByOwner возвращает отзывы по владельцу
func (r *feedbackRepositoryImpl) ListByOwner(ownerID uint, offset, limit int) ([]models.Feedback, error) {
	var feedbacks []models.Feedback
	err := r.db.Preload("Object").Where("owner_id = ?", ownerID).Offset(offset).Limit(limit).Find(&feedbacks).Error
	if err != nil {
		return nil, err
	}
	return feedbacks, nil
}

// ListByObject возвращает отзывы по объекту
func (r *feedbackRepositoryImpl) ListByObject(objectID uint, offset, limit int) ([]models.Feedback, error) {
	var feedbacks []models.Feedback
	err := r.db.Preload("Owner").Where("object_id = ?", objectID).Offset(offset).Limit(limit).Find(&feedbacks).Error
	if err != nil {
		return nil, err
	}
	return feedbacks, nil
}

// ListByPlatform возвращает отзывы по платформе
func (r *feedbackRepositoryImpl) ListByPlatform(platform models.PlatformType, offset, limit int) ([]models.Feedback, error) {
	var feedbacks []models.Feedback
	err := r.db.Preload("Owner").Preload("Object").Where("platform = ?", platform).Offset(offset).Limit(limit).Find(&feedbacks).Error
	if err != nil {
		return nil, err
	}
	return feedbacks, nil
}

// GetOwner возвращает владельца отзыва
func (r *feedbackRepositoryImpl) GetOwner(feedbackID uint) (*models.Account, error) {
	var feedback models.Feedback
	err := r.db.Select("owner_id").First(&feedback, feedbackID).Error
	if err != nil {
		return nil, err
	}
	return r.getAccountByID(feedback.OwnerID)
}

// GetObject возвращает объект, к которому относится отзыв
func (r *feedbackRepositoryImpl) GetObject(feedbackID uint) (*models.Object, error) {
	var feedback models.Feedback
	err := r.db.Select("object_id").First(&feedback, feedbackID).Error
	if err != nil {
		return nil, err
	}
	return r.getObjectByID(feedback.ObjectID)
}

// GetComments возвращает комментарии к отзыву
func (r *feedbackRepositoryImpl) GetComments(feedbackID uint, offset, limit int) ([]models.Comment, error) {
	var comments []models.Comment
	err := r.db.Where("feedback_id = ?", feedbackID).Order("created_at asc").Offset(offset).Limit(limit).Find(&comments).Error
	if err != nil {
		return nil, err
	}
	return comments, nil
}

// GetCommentCount возвращает количество комментариев к отзыву
func (r *feedbackRepositoryImpl) GetCommentCount(feedbackID uint) (int, error) {
	var count int64
	err := r.db.Model(&models.Comment{}).Where("feedback_id = ?", feedbackID).Count(&count).Error
	return int(count), err
}

// UpdateCommentCount обновляет количество комментариев у отзыва
func (r *feedbackRepositoryImpl) UpdateCommentCount(feedbackID uint, count int) error {
	return r.db.Model(&models.Feedback{}).Where("id = ?", feedbackID).Update("comment_count", count).Error
}

// Search находит отзывы по тексту
func (r *feedbackRepositoryImpl) Search(query string, offset, limit int) ([]models.Feedback, error) {
	var feedbacks []models.Feedback
	err := r.db.Preload("Owner").Preload("Object").Where("text LIKE ?", "%"+query+"%").Offset(offset).Limit(limit).Find(&feedbacks).Error
	if err != nil {
		return nil, err
	}
	return feedbacks, nil
}

// Вспомогательные методы для получения связанных сущностей
func (r *feedbackRepositoryImpl) getAccountByID(id uint) (*models.Account, error) {
	var account models.Account
	err := r.db.First(&account, id).Error
	if err != nil {
		return nil, err
	}
	return &account, nil
}

func (r *feedbackRepositoryImpl) getObjectByID(id uint) (*models.Object, error) {
	var object models.Object
	err := r.db.First(&object, id).Error
	if err != nil {
		return nil, err
	}
	return &object, nil
}

