/**
 * Report Scheduler Runner
 * Daemon script to execute due report schedules and subscription deliveries
 */

import { 
  getDueSchedules, 
  executeScheduledReport,
  getDueSubscriptions,
  executeSubscriptionDelivery 
} from '../../lib/reports/report-scheduler';
import { BRAND } from '@/lib/white-label/constants';

interface ExecutionResult {
  id: string;
  name?: string;
  success: boolean;
  generatedReportId?: string;
  error?: string;
}

interface RunSummary {
  runAt: Date;
  schedulesProcessed: number;
  schedulesSucceeded: number;
  schedulesFailed: number;
  subscriptionsProcessed: number;
  subscriptionsSucceeded: number;
  subscriptionsFailed: number;
  scheduleResults: ExecutionResult[];
  subscriptionResults: ExecutionResult[];
  totalDuration: number;
}

async function sendSummaryEmail(summary: RunSummary, adminEmail: string): Promise<void> {
  const apiKey = process.env.ABACUSAI_API_KEY;
  const webAppId = process.env.WEB_APP_ID;
  
  if (!apiKey || !webAppId) {
    console.log('Missing ABACUSAI_API_KEY or WEB_APP_ID, skipping email notification');
    return;
  }

  const subject = `Report Scheduler Run Summary - ${summary.runAt.toISOString().split('T')[0]}`;
  
  const failedSchedules = summary.scheduleResults.filter(r => !r.success);
  const failedSubscriptions = summary.subscriptionResults.filter(r => !r.success);
  
  let body = `
<html>
<body style="font-family: Arial, sans-serif; padding: 20px;">
<h2>${BRAND.companyName} - Report Scheduler Summary</h2>
<p><strong>Run Time:</strong> ${summary.runAt.toISOString()}</p>
<p><strong>Duration:</strong> ${summary.totalDuration}ms</p>

<h3>Scheduled Reports</h3>
<ul>
  <li>Processed: ${summary.schedulesProcessed}</li>
  <li>Succeeded: ${summary.schedulesSucceeded}</li>
  <li>Failed: ${summary.schedulesFailed}</li>
</ul>

<h3>Subscription Deliveries</h3>
<ul>
  <li>Processed: ${summary.subscriptionsProcessed}</li>
  <li>Succeeded: ${summary.subscriptionsSucceeded}</li>
  <li>Failed: ${summary.subscriptionsFailed}</li>
</ul>
`;

  if (failedSchedules.length > 0) {
    body += `
<h3 style="color: #dc3545;">Failed Schedules</h3>
<ul>
${failedSchedules.map(f => `<li><strong>${f.name || f.id}</strong>: ${f.error}</li>`).join('\n')}
</ul>
`;
  }

  if (failedSubscriptions.length > 0) {
    body += `
<h3 style="color: #dc3545;">Failed Subscriptions</h3>
<ul>
${failedSubscriptions.map(f => `<li><strong>${f.id}</strong>: ${f.error}</li>`).join('\n')}
</ul>
`;
  }

  if (summary.schedulesProcessed === 0 && summary.subscriptionsProcessed === 0) {
    body += `<p style="color: #6c757d;"><em>No due schedules or subscriptions found during this run.</em></p>`;
  }

  body += `
<hr>
<p style="color: #6c757d; font-size: 12px;">
This is an automated message from $${BRAND.companyName} Report Scheduler.
</p>
</body>
</html>
`;

  try {
    const response = await fetch('https://apps.abacus.ai/api/sendAppNotification', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${apiKey}`,
      },
      body: JSON.stringify({
        webAppId,
        notificationType: 'email',
        recipient: adminEmail,
        subject,
        body,
        isHtml: true,
      }),
    });

    const responseData = await response.json();
    
    if (!response.ok || !responseData.success) {
      console.log('Failed to send summary email:', JSON.stringify(responseData));
    } else {
      console.log('Summary email sent to', adminEmail);
    }
  } catch (error) {
    console.log('Error sending summary email:', error instanceof Error ? error.message : String(error));
  }
}

async function run(): Promise<void> {
  const startTime = Date.now();
  const adminEmail = process.env.ADMIN_EMAIL || 'ghostfoundrysyndicate@outlook.com';
  
  console.log('='.repeat(60));
  console.log('Report Scheduler Runner - Starting');
  console.log('Run Time:', new Date().toISOString());
  console.log('='.repeat(60));

  const summary: RunSummary = {
    runAt: new Date(),
    schedulesProcessed: 0,
    schedulesSucceeded: 0,
    schedulesFailed: 0,
    subscriptionsProcessed: 0,
    subscriptionsSucceeded: 0,
    subscriptionsFailed: 0,
    scheduleResults: [],
    subscriptionResults: [],
    totalDuration: 0,
  };

  // Process due schedules
  console.log('\n--- Processing Due Schedules ---');
  try {
    const dueSchedules = await getDueSchedules();
    console.log(`Found ${dueSchedules.length} due schedule(s)`);
    summary.schedulesProcessed = dueSchedules.length;

    for (const schedule of dueSchedules) {
      console.log(`\nExecuting schedule: ${schedule.name} (${schedule.id})`);
      try {
        const result = await executeScheduledReport(schedule.id);
        console.log(`  ✓ Success - Generated report: ${result.generatedReportId}`);
        summary.schedulesSucceeded++;
        summary.scheduleResults.push({
          id: schedule.id,
          name: schedule.name,
          success: true,
          generatedReportId: result.generatedReportId,
        });
      } catch (error) {
        const errorMsg = error instanceof Error ? error.message : String(error);
        console.error(`  ✗ Failed: ${errorMsg}`);
        summary.schedulesFailed++;
        summary.scheduleResults.push({
          id: schedule.id,
          name: schedule.name,
          success: false,
          error: errorMsg,
        });
      }
    }
  } catch (error) {
    console.error('Error fetching due schedules:', error);
  }

  // Process due subscriptions
  console.log('\n--- Processing Due Subscriptions ---');
  try {
    const dueSubscriptions = await getDueSubscriptions();
    console.log(`Found ${dueSubscriptions.length} due subscription(s)`);
    summary.subscriptionsProcessed = dueSubscriptions.length;

    for (const subscription of dueSubscriptions) {
      console.log(`\nExecuting subscription: ${subscription.id} (User: ${subscription.userId})`);
      try {
        const result = await executeSubscriptionDelivery(subscription.id);
        console.log(`  ✓ Success - Generated report: ${result.generatedReportId}`);
        summary.subscriptionsSucceeded++;
        summary.subscriptionResults.push({
          id: subscription.id,
          success: true,
          generatedReportId: result.generatedReportId,
        });
      } catch (error) {
        const errorMsg = error instanceof Error ? error.message : String(error);
        console.error(`  ✗ Failed: ${errorMsg}`);
        summary.subscriptionsFailed++;
        summary.subscriptionResults.push({
          id: subscription.id,
          success: false,
          error: errorMsg,
        });
      }
    }
  } catch (error) {
    console.error('Error fetching due subscriptions:', error);
  }

  // Calculate total duration
  summary.totalDuration = Date.now() - startTime;

  // Print summary
  console.log('\n' + '='.repeat(60));
  console.log('RUN SUMMARY');
  console.log('='.repeat(60));
  console.log(`Schedules: ${summary.schedulesSucceeded}/${summary.schedulesProcessed} succeeded`);
  console.log(`Subscriptions: ${summary.subscriptionsSucceeded}/${summary.subscriptionsProcessed} succeeded`);
  console.log(`Duration: ${summary.totalDuration}ms`);
  console.log('='.repeat(60));

  // Send summary email
  await sendSummaryEmail(summary, adminEmail);

  console.log('\nReport Scheduler Runner - Complete');
}

// Execute
run()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error('Fatal error:', error);
    process.exit(1);
  });
