/**
 * Event Notifications Service
 * Manages notifications and reminders for seasonal events
 */

import { getDb } from "../db.ts";

export interface EventNotification {
  id: string;
  userId: number;
  eventId: string;
  type: 'event_start' | 'event_ending' | 'reward_available' | 'milestone_reached' | 'reminder';
  title: string;
  message: string;
  icon: string;
  read: boolean;
  createdAt: Date;
  expiresAt?: Date;
}

export interface NotificationPreferences {
  userId: number;
  eventStartNotifications: boolean;
  eventEndingNotifications: boolean;
  rewardNotifications: boolean;
  milestoneNotifications: boolean;
  reminderNotifications: boolean;
}

// Predefined notification templates
const NOTIFICATION_TEMPLATES = {
  event_start: {
    halloween: {
      title: '🎃 Spooky Spin Spectacular Started!',
      message: 'The Halloween event is now live! Enjoy 2x bonus multipliers on all spins.',
      icon: '🎃',
    },
    christmas: {
      title: '🎄 Festive Fortune is Here!',
      message: 'Christmas event is live! Get 3x bonus multipliers and special holiday games.',
      icon: '🎄',
    },
    new_year: {
      title: '🎆 New Year New Luck!',
      message: 'Welcome to 2027! Enjoy 2.5x bonus multipliers throughout January.',
      icon: '🎆',
    },
    summer: {
      title: '☀️ Summer Sizzle Begins!',
      message: 'Summer event is here! Play beach-themed games with 1.5x multipliers.',
      icon: '☀️',
    },
  },
  event_ending: {
    halloween: {
      title: '⏰ Spooky Spin Spectacular Ending Soon!',
      message: 'The Halloween event ends in 24 hours. Claim your rewards before time runs out!',
      icon: '⏰',
    },
    christmas: {
      title: '⏰ Festive Fortune Ending Soon!',
      message: 'The Christmas event ends in 24 hours. Grab your last bonus multipliers!',
      icon: '⏰',
    },
    new_year: {
      title: '⏰ New Year New Luck Ending Soon!',
      message: 'The New Year event ends in 24 hours. Make your final spins count!',
      icon: '⏰',
    },
    summer: {
      title: '⏰ Summer Sizzle Ending Soon!',
      message: 'The Summer event ends in 24 hours. Enjoy the last of the beach games!',
      icon: '⏰',
    },
  },
  reward_available: {
    title: '🎁 New Reward Available!',
    message: 'You\'ve earned a new reward in the seasonal event. Claim it now!',
    icon: '🎁',
  },
  milestone_reached: {
    title: '🏆 Milestone Reached!',
    message: 'Congratulations! You\'ve reached a new milestone in the seasonal event.',
    icon: '🏆',
  },
  reminder: {
    title: '⏰ Don\'t Miss Out!',
    message: 'The seasonal event is still active. Come back and play to earn more rewards!',
    icon: '⏰',
  },
};

/**
 * Create and send event start notification
 */
export async function sendEventStartNotification(
  userId: number,
  eventId: string,
  theme: string
): Promise<boolean> {
  try {
    const template = NOTIFICATION_TEMPLATES.event_start[theme as keyof typeof NOTIFICATION_TEMPLATES.event_start];
    if (!template) return false;

    const db = await getDb();
    if (!db) return false;

    await db.raw(
      `INSERT INTO notifications (userId, eventId, type, title, message, icon, read, createdAt)
       VALUES (?, ?, ?, ?, ?, ?, ?, NOW())`,
      [userId, eventId, 'event_start', template.title, template.message, template.icon, 0]
    );

    return true;
  } catch (error) {
    console.error('Error sending event start notification:', error);
    return false;
  }
}

/**
 * Create and send event ending notification
 */
export async function sendEventEndingNotification(
  userId: number,
  eventId: string,
  theme: string
): Promise<boolean> {
  try {
    const template = NOTIFICATION_TEMPLATES.event_ending[theme as keyof typeof NOTIFICATION_TEMPLATES.event_ending];
    if (!template) return false;

    const db = await getDb();
    if (!db) return false;

    await db.raw(
      `INSERT INTO notifications (userId, eventId, type, title, message, icon, read, createdAt)
       VALUES (?, ?, ?, ?, ?, ?, ?, NOW())`,
      [userId, eventId, 'event_ending', template.title, template.message, template.icon, 0]
    );

    return true;
  } catch (error) {
    console.error('Error sending event ending notification:', error);
    return false;
  }
}

/**
 * Create and send reward available notification
 */
export async function sendRewardNotification(
  userId: number,
  eventId: string,
  rewardName: string
): Promise<boolean> {
  try {
    const template = NOTIFICATION_TEMPLATES.reward_available;
    const message = `You've earned "${rewardName}" in the seasonal event. Claim it now!`;

    const db = await getDb();
    if (!db) return false;

    await db.raw(
      `INSERT INTO notifications (userId, eventId, type, title, message, icon, read, createdAt)
       VALUES (?, ?, ?, ?, ?, ?, ?, NOW())`,
      [userId, eventId, 'reward_available', template.title, message, template.icon, 0]
    );

    return true;
  } catch (error) {
    console.error('Error sending reward notification:', error);
    return false;
  }
}

/**
 * Create and send milestone notification
 */
export async function sendMilestoneNotification(
  userId: number,
  eventId: string,
  milestone: number
): Promise<boolean> {
  try {
    const template = NOTIFICATION_TEMPLATES.milestone_reached;
    const message = `Congratulations! You've reached ${milestone} wins in the seasonal event!`;

    const db = await getDb();
    if (!db) return false;

    await db.raw(
      `INSERT INTO notifications (userId, eventId, type, title, message, icon, read, createdAt)
       VALUES (?, ?, ?, ?, ?, ?, ?, NOW())`,
      [userId, eventId, 'milestone_reached', template.title, message, template.icon, 0]
    );

    return true;
  } catch (error) {
    console.error('Error sending milestone notification:', error);
    return false;
  }
}

/**
 * Create and send reminder notification
 */
export async function sendReminderNotification(userId: number, eventId: string): Promise<boolean> {
  try {
    const template = NOTIFICATION_TEMPLATES.reminder;

    const db = await getDb();
    if (!db) return false;

    await db.raw(
      `INSERT INTO notifications (userId, eventId, type, title, message, icon, read, createdAt)
       VALUES (?, ?, ?, ?, ?, ?, ?, NOW())`,
      [userId, eventId, 'reminder', template.title, template.message, template.icon, 0]
    );

    return true;
  } catch (error) {
    console.error('Error sending reminder notification:', error);
    return false;
  }
}

/**
 * Get user notification preferences
 */
export async function getUserNotificationPreferences(userId: number): Promise<NotificationPreferences> {
  try {
    const db = await getDb();
    if (!db) {
      return {
        userId,
        eventStartNotifications: true,
        eventEndingNotifications: true,
        rewardNotifications: true,
        milestoneNotifications: true,
        reminderNotifications: true,
      };
    }

    const result = await db.raw(
      `SELECT * FROM notification_preferences WHERE userId = ?`,
      [userId]
    );

    if (result && result.length > 0) {
      return result[0];
    }

    return {
      userId,
      eventStartNotifications: true,
      eventEndingNotifications: true,
      rewardNotifications: true,
      milestoneNotifications: true,
      reminderNotifications: true,
    };
  } catch (error) {
    console.error('Error getting notification preferences:', error);
    return {
      userId,
      eventStartNotifications: true,
      eventEndingNotifications: true,
      rewardNotifications: true,
      milestoneNotifications: true,
      reminderNotifications: true,
    };
  }
}

/**
 * Update user notification preferences
 */
export async function updateNotificationPreferences(
  userId: number,
  preferences: Partial<NotificationPreferences>
): Promise<boolean> {
  try {
    const db = await getDb();
    if (!db) return false;

    await db.raw(
      `INSERT INTO notification_preferences (userId, eventStartNotifications, eventEndingNotifications, rewardNotifications, milestoneNotifications, reminderNotifications)
       VALUES (?, ?, ?, ?, ?, ?)
       ON DUPLICATE KEY UPDATE
       eventStartNotifications = VALUES(eventStartNotifications),
       eventEndingNotifications = VALUES(eventEndingNotifications),
       rewardNotifications = VALUES(rewardNotifications),
       milestoneNotifications = VALUES(milestoneNotifications),
       reminderNotifications = VALUES(reminderNotifications)`,
      [
        userId,
        preferences.eventStartNotifications ?? true,
        preferences.eventEndingNotifications ?? true,
        preferences.rewardNotifications ?? true,
        preferences.milestoneNotifications ?? true,
        preferences.reminderNotifications ?? true,
      ]
    );

    return true;
  } catch (error) {
    console.error('Error updating notification preferences:', error);
    return false;
  }
}

/**
 * Get unread notifications for user
 */
export async function getUnreadNotifications(userId: number): Promise<EventNotification[]> {
  try {
    const db = await getDb();
    if (!db) return [];

    const result = await db.raw(
      `SELECT * FROM notifications WHERE userId = ? AND read = 0 ORDER BY createdAt DESC LIMIT 20`,
      [userId]
    );

    return result || [];
  } catch (error) {
    console.error('Error getting unread notifications:', error);
    return [];
  }
}

/**
 * Mark notification as read
 */
export async function markNotificationAsRead(notificationId: string): Promise<boolean> {
  try {
    const db = await getDb();
    if (!db) return false;

    await db.raw(`UPDATE notifications SET read = 1 WHERE id = ?`, [notificationId]);

    return true;
  } catch (error) {
    console.error('Error marking notification as read:', error);
    return false;
  }
}

/**
 * Schedule event reminders for all active players
 */
export async function scheduleEventReminders(eventId: string, hoursBeforeEnd: number = 24): Promise<number> {
  try {
    const db = await getDb();
    if (!db) return 0;

    // Get all users who participated in the event
    const users = await db.raw(
      `SELECT DISTINCT userId FROM transactions 
       WHERE referenceType = 'seasonal_event' AND referenceId = ?`,
      [eventId]
    );

    let count = 0;
    for (const user of users || []) {
      const sent = await sendReminderNotification(user.userId, eventId);
      if (sent) count++;
    }

    return count;
  } catch (error) {
    console.error('Error scheduling event reminders:', error);
    return 0;
  }
}
