import type { IStorage } from './storage.js';
import { EmailNotificationService, type EmailDigestData } from './email-service.js';

export class EmailScheduler {
  private storage: IStorage;
  private emailService: EmailNotificationService;
  private schedulerInterval: NodeJS.Timeout | null = null;
  private isRunning = false;

  constructor(storage: IStorage) {
    this.storage = storage;
    this.emailService = new EmailNotificationService(storage);
  }

  /**
   * Start the email scheduler
   */
  async start(): Promise<void> {
    if (this.schedulerInterval) {
      console.log('Email scheduler already running');
      return;
    }

    console.log('Starting LocalLendables email notification scheduler...');

    // Check every 30 minutes for scheduled runs
    this.schedulerInterval = setInterval(async () => {
      await this.checkAndRunDailyDigest();
    }, 30 * 60 * 1000); // 30 minutes

    // Run initial check
    await this.checkAndRunDailyDigest();
    
    console.log('Email scheduler started - checking every 30 minutes');
  }

  /**
   * Stop the email scheduler
   */
  stop(): void {
    if (this.schedulerInterval) {
      clearInterval(this.schedulerInterval);
      this.schedulerInterval = null;
      console.log('Email scheduler stopped');
    }
  }

  /**
   * Check if it's time to run daily digest and execute if needed
   */
  async checkAndRunDailyDigest(): Promise<void> {
    try {
      const settings = await this.storage.getEmailNotificationSettings();
      
      if (!settings || !settings.isEnabled) {
        console.log('Email notifications disabled, skipping digest check');
        return;
      }

      if (settings.isRunning) {
        console.log('Email digest already running, skipping this check');
        return;
      }

      const now = new Date();
      const currentDate = now.toLocaleDateString('en-CA'); // YYYY-MM-DD format
      const currentTime = now.toLocaleTimeString('en-CA', { 
        timeZone: settings.timezone,
        hour12: false,
        hour: '2-digit',
        minute: '2-digit'
      });

      // Check if we should run today
      const shouldRun = (
        settings.lastRunDate !== currentDate && // Haven't run today
        currentTime >= settings.dailyScheduleTime // Past scheduled time
      );

      if (shouldRun) {
        console.log(`Starting daily email digest at ${currentTime} (scheduled: ${settings.dailyScheduleTime})`);
        await this.runDailyDigest();
      }

    } catch (error) {
      console.error('Error in email scheduler check:', error);
    }
  }

  /**
   * Execute the daily digest process
   */
  async runDailyDigest(): Promise<void> {
    if (this.isRunning) {
      console.log('Daily digest already running, skipping');
      return;
    }

    this.isRunning = true;
    
    try {
      // Mark as running in database
      await this.storage.updateEmailNotificationSettings({
        isRunning: true,
        lastRunDate: new Date().toLocaleDateString('en-CA')
      });

      console.log('Starting daily email digest generation...');

      // Get all active users
      const users = await this.storage.getAllUsers();
      const activeUsers = users.filter(user => user.active && user.email);

      console.log(`Processing daily digest for ${activeUsers.length} active users`);

      let sentCount = 0;
      let skippedCount = 0;
      let failedCount = 0;

      // Get email settings
      const settings = await this.storage.getEmailNotificationSettings();
      const temporaryMode = settings?.temporaryMode ?? true;
      const temporaryEmail = settings?.temporaryEmail ?? "manager@tatacommons.com";

      // Process each user
      for (const user of activeUsers) {
        try {
          const digestData = await this.generateUserDigestData(user.id);
          
          // Only send if user has new messages or notifications
          if (digestData.hasNewMessages || digestData.hasNewNotifications) {
            const success = await this.emailService.sendDailyDigest(digestData, temporaryMode, temporaryEmail);
            
            if (success) {
              sentCount++;
              // Mark digest as sent in queue
              await this.storage.createEmailDigestQueue({
                userId: user.id,
                userName: digestData.userName,
                userEmail: user.email,
                hasNewMessages: digestData.hasNewMessages,
                hasNewNotifications: digestData.hasNewNotifications,
                messageCount: digestData.messageCount,
                notificationCount: digestData.notificationCount,
                status: 'sent',
                processedAt: new Date()
              });
            } else {
              failedCount++;
              await this.storage.createEmailDigestQueue({
                userId: user.id,
                userName: digestData.userName,
                userEmail: user.email,
                hasNewMessages: digestData.hasNewMessages,
                hasNewNotifications: digestData.hasNewNotifications,
                messageCount: digestData.messageCount,
                notificationCount: digestData.notificationCount,
                status: 'failed',
                processedAt: new Date()
              });
            }
          } else {
            skippedCount++;
            // Log skipped users for tracking
            await this.storage.createEmailDigestQueue({
              userId: user.id,
              userName: digestData.userName,
              userEmail: user.email,
              hasNewMessages: false,
              hasNewNotifications: false,
              messageCount: 0,
              notificationCount: 0,
              status: 'skipped',
              processedAt: new Date()
            });
          }

          // Small delay between emails to avoid rate limiting
          await new Promise(resolve => setTimeout(resolve, 1000));

        } catch (userError) {
          console.error(`Error processing digest for user ${user.id}:`, userError);
          failedCount++;
        }
      }

      console.log(`Daily digest completed: ${sentCount} sent, ${skippedCount} skipped, ${failedCount} failed`);

    } catch (error) {
      console.error('Error running daily digest:', error);
    } finally {
      // Mark as not running
      await this.storage.updateEmailNotificationSettings({
        isRunning: false
      });
      this.isRunning = false;
    }
  }

  /**
   * Generate digest data for a specific user
   */
  private async generateUserDigestData(userId: number): Promise<EmailDigestData> {
    const user = await this.storage.getUser(userId);
    if (!user) {
      throw new Error(`User ${userId} not found`);
    }

    const userName = user.showName || `${user.firstName} ${user.lastName}`.trim() || user.email;
    
    // Get messages from last 24 hours
    const yesterday = new Date();
    yesterday.setDate(yesterday.getDate() - 1);
    
    const recentMessages = await this.storage.getRecentMessagesForUser(userId, yesterday);
    const recentNotifications = await this.storage.getRecentNotificationsForUser(userId, yesterday);

    // Process messages for digest
    const messages = recentMessages.map(msg => ({
      id: msg.id,
      sender: msg.senderName || 'Unknown',
      itemName: msg.itemName || 'Unknown Item',
      excerpt: this.truncateText(msg.textContent || 'Voice message', 80),
      createdAt: msg.createdAt
    }));

    // Process notifications for digest
    const notifications = recentNotifications.map(notif => ({
      id: notif.id,
      type: notif.type,
      title: notif.title,
      message: this.truncateText(notif.message, 120),
      createdAt: notif.createdAt
    }));

    return {
      userId,
      userName,
      userEmail: user.email,
      hasNewMessages: messages.length > 0,
      hasNewNotifications: notifications.length > 0,
      messageCount: messages.length,
      notificationCount: notifications.length,
      messages,
      notifications
    };
  }

  /**
   * Truncate text to specified length with ellipsis
   */
  private truncateText(text: string, maxLength: number): string {
    if (text.length <= maxLength) return text;
    return text.substring(0, maxLength - 3) + '...';
  }

  /**
   * Manual trigger for testing (admin only)
   */
  async triggerManualDigest(userId?: number): Promise<{ sent: number; failed: number; skipped: number }> {
    console.log('Manual digest trigger initiated');
    
    if (userId) {
      // Single user digest
      try {
        const digestData = await this.generateUserDigestData(userId);
        const settings = await this.storage.getEmailNotificationSettings();
        const success = await this.emailService.sendDailyDigest(
          digestData, 
          settings?.temporaryMode ?? true, 
          settings?.temporaryEmail ?? "manager@tatacommons.com"
        );
        
        return success ? { sent: 1, failed: 0, skipped: 0 } : { sent: 0, failed: 1, skipped: 0 };
      } catch (error) {
        console.error('Manual digest failed for user:', userId, error);
        return { sent: 0, failed: 1, skipped: 0 };
      }
    } else {
      // All users digest
      await this.runDailyDigest();
      
      // Get today's stats from queue
      const today = new Date().toLocaleDateString('en-CA');
      const todayStats = await this.storage.getEmailDigestStats(today);
      
      return {
        sent: todayStats.sent || 0,
        failed: todayStats.failed || 0,
        skipped: todayStats.skipped || 0
      };
    }
  }
}