// internal/services/notification_service.go
package services

import (
	"errors"
	"lost-and-found/internal/models"
	"lost-and-found/internal/repositories"

	"gorm.io/gorm"
)

type NotificationService struct {
	db               *gorm.DB // Tambahkan ini
	notificationRepo *repositories.NotificationRepository
}

func NewNotificationService(db *gorm.DB) *NotificationService {
	return &NotificationService{
		db:               db, // Tambahkan ini
		notificationRepo: repositories.NewNotificationRepository(db),
	}
}
// GetUserNotifications gets notifications for a user
func (s *NotificationService) GetUserNotifications(userID uint, page, limit int, onlyUnread bool) ([]models.NotificationResponse, int64, error) {
	notifications, total, err := s.notificationRepo.FindByUser(userID, page, limit, onlyUnread)
	if err != nil {
		return nil, 0, err
	}

	var responses []models.NotificationResponse
	for _, notification := range notifications {
		responses = append(responses, notification.ToResponse())
	}

	return responses, total, nil
}

// GetNotificationByID gets notification by ID
func (s *NotificationService) GetNotificationByID(userID, notificationID uint) (*models.Notification, error) {
	notification, err := s.notificationRepo.FindByID(notificationID)
	if err != nil {
		return nil, err
	}

	// Check ownership
	if notification.UserID != userID {
		return nil, errors.New("unauthorized")
	}

	return notification, nil
}

// MarkAsRead marks a notification as read
func (s *NotificationService) MarkAsRead(userID, notificationID uint) error {
	notification, err := s.notificationRepo.FindByID(notificationID)
	if err != nil {
		return err
	}

	// Check ownership
	if notification.UserID != userID {
		return errors.New("unauthorized")
	}

	return s.notificationRepo.MarkAsRead(notificationID)
}

// MarkAllAsRead marks all notifications as read for a user
func (s *NotificationService) MarkAllAsRead(userID uint) error {
	return s.notificationRepo.MarkAllAsRead(userID)
}

// DeleteNotification deletes a notification
func (s *NotificationService) DeleteNotification(userID, notificationID uint) error {
	notification, err := s.notificationRepo.FindByID(notificationID)
	if err != nil {
		return err
	}

	// Check ownership
	if notification.UserID != userID {
		return errors.New("unauthorized")
	}

	return s.notificationRepo.Delete(notificationID)
}

// DeleteAllNotifications deletes all notifications for a user
func (s *NotificationService) DeleteAllNotifications(userID uint) error {
	return s.notificationRepo.DeleteAllForUser(userID)
}

// CountUnread counts unread notifications for a user
func (s *NotificationService) CountUnread(userID uint) (int64, error) {
	return s.notificationRepo.CountUnread(userID)
}

// CreateNotification creates a new notification
func (s *NotificationService) CreateNotification(userID uint, notifType, title, message, entityType string, entityID *uint) error {
	return s.notificationRepo.Notify(userID, notifType, title, message, entityType, entityID)
}

// SendMatchNotification sends notification when a match is found
func (s *NotificationService) SendMatchNotification(userID uint, itemName string, matchID uint) error {
	return models.CreateMatchNotification(s.db, userID, itemName, matchID)
}

// SendClaimApprovedNotification sends notification when claim is approved
func (s *NotificationService) SendClaimApprovedNotification(userID uint, itemName string, claimID uint) error {
	return models.CreateClaimApprovedNotification(s.db, userID, itemName, claimID)
}

// SendClaimRejectedNotification sends notification when claim is rejected
func (s *NotificationService) SendClaimRejectedNotification(userID uint, itemName, reason string, claimID uint) error {
	return models.CreateClaimRejectedNotification(s.db, userID, itemName, reason, claimID)
}