const { Notification, User } = require('../models');
const logger = require('../config/logger');
const { Op } = require('sequelize');

/**
 * Admin Notification Management Service
 */
class AdminNotificationService {
  /**
   * Get all notifications with pagination and filtering (admin view)
   */
  static async getNotifications({ page = 1, limit = 20, type, userId, isRead, search }) {
    try {
      const offset = (page - 1) * limit;
      const where = {};

      if (type) where.type = type;
      if (userId) where.userId = userId;
      if (isRead !== undefined && isRead !== '') {
        where.isRead = isRead === 'true' || isRead === true;
      }
      if (search) {
        where[Op.or] = [
          { titleZh: { [Op.like]: `%${search}%` } },
          { titleEn: { [Op.like]: `%${search}%` } },
          { contentZh: { [Op.like]: `%${search}%` } },
        ];
      }

      const { count, rows } = await Notification.findAndCountAll({
        where,
        include: [{ model: User, as: 'user', attributes: ['id', 'nickname', 'phone'] }],
        order: [['createdAt', 'DESC']],
        limit: parseInt(limit),
        offset: parseInt(offset),
      });

      return {
        data: rows.map(n => n.toJSON()),
        pagination: { page: parseInt(page), limit: parseInt(limit), total: count, totalPages: Math.ceil(count / limit) },
      };
    } catch (error) {
      logger.error('Error fetching notifications (admin):', error);
      throw error;
    }
  }

  /**
   * Send notification to specific user (supports both userId and uid)
   */
  static async sendToUser(userId, notificationData) {
    try {
      let user;
      // Support both UUID and UID (6-digit number)
      if (/^\d{6}$/.test(userId)) {
        user = await User.findOne({ where: { uid: userId } });
      } else {
        user = await User.findByPk(userId);
      }
      
      if (!user) {
        const error = new Error('User not found');
        error.statusCode = 404;
        throw error;
      }

      const notification = await Notification.create({
        userId: user.id,
        type: notificationData.type || 'system',
        titleZh: notificationData.titleZh,
        titleEn: notificationData.titleEn || notificationData.titleZh,
        titleEs: notificationData.titleEs || notificationData.titleZh,
        contentZh: notificationData.contentZh,
        contentEn: notificationData.contentEn || notificationData.contentZh,
        contentEs: notificationData.contentEs || notificationData.contentZh,
        isRead: false,
      });

      logger.info(`Admin sent notification to user ${user.id} (uid: ${user.uid})`);
      return notification.toJSON();
    } catch (error) {
      logger.error('Error sending notification:', error);
      throw error;
    }
  }

  /**
   * Send notification to all users (broadcast)
   */
  static async broadcast(notificationData) {
    try {
      const users = await User.findAll({ attributes: ['id'] });
      const notifications = users.map(user => ({
        userId: user.id,
        type: notificationData.type || 'system',
        titleZh: notificationData.titleZh,
        titleEn: notificationData.titleEn || notificationData.titleZh,
        titleEs: notificationData.titleEs || notificationData.titleZh,
        contentZh: notificationData.contentZh,
        contentEn: notificationData.contentEn || notificationData.contentZh,
        contentEs: notificationData.contentEs || notificationData.contentZh,
        isRead: false,
      }));

      await Notification.bulkCreate(notifications);
      logger.info(`Admin broadcast notification to ${users.length} users`);
      return { count: users.length };
    } catch (error) {
      logger.error('Error broadcasting notification:', error);
      throw error;
    }
  }

  /**
   * Delete notification by admin
   */
  static async deleteNotification(notificationId) {
    try {
      const notification = await Notification.findByPk(notificationId);
      if (!notification) {
        const error = new Error('Notification not found');
        error.statusCode = 404;
        throw error;
      }
      await notification.destroy();
      logger.info(`Admin deleted notification ${notificationId}`);
      return true;
    } catch (error) {
      logger.error(`Error deleting notification ${notificationId}:`, error);
      throw error;
    }
  }

  /**
   * Get notification statistics
   */
  static async getStatistics() {
    try {
      const [total, unread, byType] = await Promise.all([
        Notification.count(),
        Notification.count({ where: { isRead: false } }),
        Notification.findAll({
          attributes: ['type', [require('sequelize').fn('COUNT', '*'), 'count']],
          group: ['type'],
          raw: true,
        }),
      ]);
      return { total, unread, read: total - unread, byType };
    } catch (error) {
      logger.error('Error getting notification statistics:', error);
      throw error;
    }
  }
}

module.exports = AdminNotificationService;
