package services

import (
	"fmt"
	"time"

	"github.com/Nanqipro/YunQue-Tech-Projects/ai_english_learning/serve/internal/models"
	"gorm.io/gorm"
)

// NotificationService 通知服务
type NotificationService struct {
	db *gorm.DB
}

// NewNotificationService 创建通知服务实例
func NewNotificationService(db *gorm.DB) *NotificationService {
	return &NotificationService{db: db}
}

// GetUserNotifications 获取用户通知列表
func (s *NotificationService) GetUserNotifications(userID int64, page, limit int, onlyUnread bool) ([]models.Notification, int64, error) {
	var notifications []models.Notification
	var total int64

	query := s.db.Model(&models.Notification{}).Where("user_id = ?", userID)

	// 只查询未读通知
	if onlyUnread {
		query = query.Where("is_read = ?", false)
	}

	// 获取总数
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, fmt.Errorf("统计通知数量失败: %w", err)
	}

	// 分页查询
	offset := (page - 1) * limit
	if err := query.Order("priority DESC, created_at DESC").
		Offset(offset).
		Limit(limit).
		Find(&notifications).Error; err != nil {
		return nil, 0, fmt.Errorf("查询通知列表失败: %w", err)
	}

	return notifications, total, nil
}

// GetUnreadCount 获取未读通知数量
func (s *NotificationService) GetUnreadCount(userID int64) (int64, error) {
	var count int64
	if err := s.db.Model(&models.Notification{}).
		Where("user_id = ? AND is_read = ?", userID, false).
		Count(&count).Error; err != nil {
		return 0, fmt.Errorf("统计未读通知失败: %w", err)
	}
	return count, nil
}

// MarkAsRead 标记通知为已读
func (s *NotificationService) MarkAsRead(userID, notificationID int64) error {
	now := time.Now()
	result := s.db.Model(&models.Notification{}).
		Where("id = ? AND user_id = ?", notificationID, userID).
		Updates(map[string]interface{}{
			"is_read": true,
			"read_at": now,
		})

	if result.Error != nil {
		return fmt.Errorf("标记通知已读失败: %w", result.Error)
	}

	if result.RowsAffected == 0 {
		return fmt.Errorf("通知不存在或无权限")
	}

	return nil
}

// MarkAllAsRead 标记所有通知为已读
func (s *NotificationService) MarkAllAsRead(userID int64) error {
	now := time.Now()
	result := s.db.Model(&models.Notification{}).
		Where("user_id = ? AND is_read = ?", userID, false).
		Updates(map[string]interface{}{
			"is_read": true,
			"read_at": now,
		})

	if result.Error != nil {
		return fmt.Errorf("标记所有通知已读失败: %w", result.Error)
	}

	return nil
}

// DeleteNotification 删除通知
func (s *NotificationService) DeleteNotification(userID, notificationID int64) error {
	result := s.db.Where("id = ? AND user_id = ?", notificationID, userID).
		Delete(&models.Notification{})

	if result.Error != nil {
		return fmt.Errorf("删除通知失败: %w", result.Error)
	}

	if result.RowsAffected == 0 {
		return fmt.Errorf("通知不存在或无权限")
	}

	return nil
}

// CreateNotification 创建通知（内部使用）
func (s *NotificationService) CreateNotification(notification *models.Notification) error {
	if err := s.db.Create(notification).Error; err != nil {
		return fmt.Errorf("创建通知失败: %w", err)
	}
	return nil
}

// SendSystemNotification 发送系统通知
func (s *NotificationService) SendSystemNotification(userID int64, title, content string, link *string, priority int) error {
	notification := &models.Notification{
		UserID:   userID,
		Type:     models.NotificationTypeSystem,
		Title:    title,
		Content:  content,
		Link:     link,
		Priority: priority,
		IsRead:   false,
	}
	return s.CreateNotification(notification)
}

// SendLearningReminder 发送学习提醒
func (s *NotificationService) SendLearningReminder(userID int64, title, content string, link *string) error {
	notification := &models.Notification{
		UserID:   userID,
		Type:     models.NotificationTypeLearning,
		Title:    title,
		Content:  content,
		Link:     link,
		Priority: models.NotificationPriorityNormal,
		IsRead:   false,
	}
	return s.CreateNotification(notification)
}

// SendAchievementNotification 发送成就通知
func (s *NotificationService) SendAchievementNotification(userID int64, title, content string, link *string) error {
	notification := &models.Notification{
		UserID:   userID,
		Type:     models.NotificationTypeAchievement,
		Title:    title,
		Content:  content,
		Link:     link,
		Priority: models.NotificationPriorityImportant,
		IsRead:   false,
	}
	return s.CreateNotification(notification)
}
