/**
 * Notification Permission Manager
 * 
 * Handles Android 13+ notification permissions with graceful fallbacks
 * Provides user-friendly permission request flows and education
 * 
 * @author Matthew Raymer
 * @version 1.0.0
 */

import { Capacitor } from '@capacitor/core';

/**
 * Permission status interface
 */
export interface PermissionStatus {
  notifications: 'granted' | 'denied' | 'prompt' | 'not_supported';
  exactAlarms: 'granted' | 'denied' | 'not_supported';
  batteryOptimization: 'granted' | 'denied' | 'not_supported';
  overall: 'ready' | 'partial' | 'blocked';
}

/**
 * Permission request result
 */
export interface PermissionRequestResult {
  success: boolean;
  permissions: PermissionStatus;
  message: string;
  nextSteps?: string[];
}

/**
 * Permission education content
 */
export interface PermissionEducation {
  title: string;
  message: string;
  benefits: string[];
  steps: string[];
  fallbackOptions: string[];
}

/**
 * Notification Permission Manager
 */
export class NotificationPermissionManager {
  private static instance: NotificationPermissionManager;
  
  private constructor() {
    // Singleton constructor - no initialization needed
  }
  
  public static getInstance(): NotificationPermissionManager {
    if (!NotificationPermissionManager.instance) {
      NotificationPermissionManager.instance = new NotificationPermissionManager();
    }
    return NotificationPermissionManager.instance;
  }
  
  /**
   * Check current permission status
   */
  async checkPermissions(): Promise<PermissionStatus> {
    try {
      const platform = Capacitor.getPlatform();
      
      if (platform === 'web') {
        return {
          notifications: 'not_supported',
          exactAlarms: 'not_supported',
          batteryOptimization: 'not_supported',
          overall: 'blocked'
        };
      }
      
      // Check notification permissions
      const notificationStatus = await this.checkNotificationPermissions();
      
      // Check exact alarm permissions
      const exactAlarmStatus = await this.checkExactAlarmPermissions();
      
      // Check battery optimization status
      const batteryStatus = await this.checkBatteryOptimizationStatus();
      
      // Determine overall status
      const overall = this.determineOverallStatus(notificationStatus, exactAlarmStatus, batteryStatus);
      
      return {
        notifications: notificationStatus,
        exactAlarms: exactAlarmStatus,
        batteryOptimization: batteryStatus,
        overall
      };
      
    } catch (error) {
      console.error('Error checking permissions:', error);
      return {
        notifications: 'denied',
        exactAlarms: 'denied',
        batteryOptimization: 'denied',
        overall: 'blocked'
      };
    }
  }
  
  /**
   * Request all required permissions with education
   */
  async requestPermissionsWithEducation(): Promise<PermissionRequestResult> {
    try {
      const currentStatus = await this.checkPermissions();
      
      if (currentStatus.overall === 'ready') {
        return {
          success: true,
          permissions: currentStatus,
          message: 'All permissions already granted'
        };
      }
      
      const results: string[] = [];
      const nextSteps: string[] = [];
      
      // Request notification permissions
      if (currentStatus.notifications === 'prompt') {
        const notificationResult = await this.requestNotificationPermissions();
        results.push(notificationResult.message);
        if (!notificationResult.success) {
          nextSteps.push('Enable notifications in device settings');
        }
      }
      
      // Request exact alarm permissions
      if (currentStatus.exactAlarms === 'denied') {
        const exactAlarmResult = await this.requestExactAlarmPermissions();
        results.push(exactAlarmResult.message);
        if (!exactAlarmResult.success) {
          nextSteps.push('Enable exact alarms in device settings');
        }
      }
      
      // Request battery optimization exemption
      if (currentStatus.batteryOptimization === 'denied') {
        const batteryResult = await this.requestBatteryOptimizationExemption();
        results.push(batteryResult.message);
        if (!batteryResult.success) {
          nextSteps.push('Disable battery optimization for this app');
        }
      }
      
      const finalStatus = await this.checkPermissions();
      const success = finalStatus.overall === 'ready' || finalStatus.overall === 'partial';
      
      return {
        success,
        permissions: finalStatus,
        message: results.join('; '),
        nextSteps: nextSteps.length > 0 ? nextSteps : undefined
      };
      
    } catch (error) {
      console.error('Error requesting permissions:', error);
      return {
        success: false,
        permissions: await this.checkPermissions(),
        message: 'Failed to request permissions: ' + (error instanceof Error ? error.message : String(error))
      };
    }
  }
  
  /**
   * Get permission education content
   */
  getPermissionEducation(): PermissionEducation {
    return {
      title: 'Enable Notifications for Better Experience',
      message: 'To receive timely updates and reminders, please enable notifications and related permissions.',
      benefits: [
        'Receive daily updates at your preferred time',
        'Get notified about important changes',
        'Never miss important reminders',
        'Enjoy reliable notification delivery'
      ],
      steps: [
        'Tap "Allow" when prompted for notification permissions',
        'Enable exact alarms for precise timing',
        'Disable battery optimization for this app',
        'Test notifications to ensure everything works'
      ],
      fallbackOptions: [
        'Use in-app reminders as backup',
        'Check the app regularly for updates',
        'Enable email notifications if available'
      ]
    };
  }
  
  /**
   * Show permission education dialog
   */
  async showPermissionEducation(): Promise<boolean> {
    try {
      const education = this.getPermissionEducation();
      
      // Create and show education dialog
      const userChoice = await this.showEducationDialog(education);
      
      if (userChoice === 'continue') {
        return await this.requestPermissionsWithEducation().then(result => result.success);
      }
      
      return false;
      
    } catch (error) {
      console.error('Error showing permission education:', error);
      return false;
    }
  }
  
  /**
   * Handle permission denied gracefully
   */
  async handlePermissionDenied(permissionType: 'notifications' | 'exactAlarms' | 'batteryOptimization'): Promise<void> {
    try {
      const education = this.getPermissionEducation();
      
      switch (permissionType) {
        case 'notifications':
          await this.showNotificationDeniedDialog(education);
          break;
        case 'exactAlarms':
          await this.showExactAlarmDeniedDialog(education);
          break;
        case 'batteryOptimization':
          await this.showBatteryOptimizationDeniedDialog(education);
          break;
      }
      
    } catch (error) {
      console.error('Error handling permission denied:', error);
    }
  }
  
  /**
   * Check if app can function with current permissions
   */
  async canFunctionWithCurrentPermissions(): Promise<boolean> {
    try {
      const status = await this.checkPermissions();
      
      // App can function if notifications are granted, even without exact alarms
      return status.notifications === 'granted';
      
    } catch (error) {
      console.error('Error checking if app can function:', error);
      return false;
    }
  }
  
  /**
   * Get fallback notification strategy
   */
  getFallbackStrategy(): string[] {
    return [
      'Use in-app notifications instead of system notifications',
      'Implement periodic background checks',
      'Show notification badges in the app',
      'Use email notifications as backup',
      'Implement push notifications through a service'
    ];
  }
  
  // Private helper methods
  
  private async checkNotificationPermissions(): Promise<'granted' | 'denied' | 'prompt' | 'not_supported'> {
    try {
      if (Capacitor.getPlatform() === 'web') {
        return 'not_supported';
      }
      
      // Check if we can access the plugin
      if (typeof (window as unknown as { Capacitor?: { Plugins?: { DailyNotification?: unknown } } }).Capacitor?.Plugins?.DailyNotification === 'undefined') {
        return 'not_supported';
      }
      
      const status = await (window as unknown as { Capacitor?: { Plugins?: { DailyNotification?: { checkPermissions: () => Promise<{ notifications?: 'granted' | 'denied' | 'prompt' | 'not_supported' }> } } } }).Capacitor?.Plugins?.DailyNotification?.checkPermissions();
      return (status?.notifications || 'denied') as 'granted' | 'denied' | 'prompt' | 'not_supported';
      
    } catch (error) {
      console.error('Error checking notification permissions:', error);
      return 'denied';
    }
  }
  
  private async checkExactAlarmPermissions(): Promise<'granted' | 'denied' | 'not_supported'> {
    try {
      if (Capacitor.getPlatform() === 'web') {
        return 'not_supported';
      }
      
      if (typeof (window as unknown as { Capacitor?: { Plugins?: { DailyNotification?: unknown } } }).Capacitor?.Plugins?.DailyNotification === 'undefined') {
        return 'denied';
      }
      
      const status = await (window as unknown as { Capacitor?: { Plugins?: { DailyNotification?: { getExactAlarmStatus: () => Promise<{ canSchedule?: boolean }> } } } }).Capacitor?.Plugins?.DailyNotification?.getExactAlarmStatus();
      return status?.canSchedule ? 'granted' : 'denied';
      
    } catch (error) {
      console.error('Error checking exact alarm permissions:', error);
      return 'denied';
    }
  }
  
  private async checkBatteryOptimizationStatus(): Promise<'granted' | 'denied' | 'not_supported'> {
    try {
      if (Capacitor.getPlatform() === 'web') {
        return 'not_supported';
      }
      
      if (typeof (window as unknown as { Capacitor?: { Plugins?: { DailyNotification?: unknown } } }).Capacitor?.Plugins?.DailyNotification === 'undefined') {
        return 'denied';
      }
      
      const status = await (window as unknown as { Capacitor?: { Plugins?: { DailyNotification?: { getBatteryStatus: () => Promise<{ isOptimized?: boolean }> } } } }).Capacitor?.Plugins?.DailyNotification?.getBatteryStatus();
      return status?.isOptimized ? 'denied' : 'granted';
      
    } catch (error) {
      console.error('Error checking battery optimization status:', error);
      return 'denied';
    }
  }
  
  private determineOverallStatus(
    notifications: string,
    exactAlarms: string,
    batteryOptimization: string
  ): 'ready' | 'partial' | 'blocked' {
    if (notifications === 'granted' && exactAlarms === 'granted' && batteryOptimization === 'granted') {
      return 'ready';
    } else if (notifications === 'granted') {
      return 'partial';
    } else {
      return 'blocked';
    }
  }
  
  private async requestNotificationPermissions(): Promise<{ success: boolean; message: string }> {
    try {
      if (typeof (window as unknown as { Capacitor?: { Plugins?: { DailyNotification?: unknown } } }).Capacitor?.Plugins?.DailyNotification === 'undefined') {
        return { success: false, message: 'Plugin not available' };
      }
      
      const result = await (window as unknown as { Capacitor?: { Plugins?: { DailyNotification?: { requestPermissions: () => Promise<{ notifications?: string }> } } } }).Capacitor?.Plugins?.DailyNotification?.requestPermissions();
      return {
        success: result?.notifications === 'granted',
        message: result?.notifications === 'granted' ? 'Notification permissions granted' : 'Notification permissions denied'
      };
      
    } catch (error) {
      return { success: false, message: 'Failed to request notification permissions' };
    }
  }
  
  private async requestExactAlarmPermissions(): Promise<{ success: boolean; message: string }> {
    try {
      if (typeof (window as unknown as { Capacitor?: { Plugins?: { DailyNotification?: unknown } } }).Capacitor?.Plugins?.DailyNotification === 'undefined') {
        return { success: false, message: 'Plugin not available' };
      }
      
      await (window as unknown as { Capacitor?: { Plugins?: { DailyNotification?: { requestExactAlarmPermission: () => Promise<void> } } } }).Capacitor?.Plugins?.DailyNotification?.requestExactAlarmPermission();
      
      // Check if permission was granted
      const status = await (window as unknown as { Capacitor?: { Plugins?: { DailyNotification?: { getExactAlarmStatus: () => Promise<{ canSchedule?: boolean }> } } } }).Capacitor?.Plugins?.DailyNotification?.getExactAlarmStatus();
      return {
        success: !!status?.canSchedule,
        message: status?.canSchedule ? 'Exact alarm permissions granted' : 'Exact alarm permissions denied'
      };
      
    } catch (error) {
      return { success: false, message: 'Failed to request exact alarm permissions' };
    }
  }
  
  private async requestBatteryOptimizationExemption(): Promise<{ success: boolean; message: string }> {
    try {
      if (typeof (window as unknown as { Capacitor?: { Plugins?: { DailyNotification?: unknown } } }).Capacitor?.Plugins?.DailyNotification === 'undefined') {
        return { success: false, message: 'Plugin not available' };
      }
      
      await (window as unknown as { Capacitor?: { Plugins?: { DailyNotification?: { requestBatteryOptimizationExemption: () => Promise<void> } } } }).Capacitor?.Plugins?.DailyNotification?.requestBatteryOptimizationExemption();
      
      // Check if exemption was granted
      const status = await (window as unknown as { Capacitor?: { Plugins?: { DailyNotification?: { getBatteryStatus: () => Promise<{ isOptimized?: boolean }> } } } }).Capacitor?.Plugins?.DailyNotification?.getBatteryStatus();
      return {
        success: !status?.isOptimized,
        message: !status?.isOptimized ? 'Battery optimization exemption granted' : 'Battery optimization exemption denied'
      };
      
    } catch (error) {
      return { success: false, message: 'Failed to request battery optimization exemption' };
    }
  }
  
  private async showEducationDialog(education: PermissionEducation): Promise<'continue' | 'cancel'> {
    // This would show a custom dialog with the education content
    // For now, we'll use a simple confirm dialog
    const message = `${education.title}\n\n${education.message}\n\nBenefits:\n${education.benefits.map(b => `• ${b}`).join('\n')}`;
    
    return new Promise((resolve) => {
      if (confirm(message)) {
        resolve('continue');
      } else {
        resolve('cancel');
      }
    });
  }
  
  private async showNotificationDeniedDialog(education: PermissionEducation): Promise<void> {
    const message = `Notifications are disabled. You can still use the app, but you won't receive timely updates.\n\nTo enable notifications:\n${education.steps.slice(0, 2).map(s => `• ${s}`).join('\n')}`;
    alert(message);
  }
  
  private async showExactAlarmDeniedDialog(_education: PermissionEducation): Promise<void> {
    const message = `Exact alarms are disabled. Notifications may not arrive at the exact time you specified.\n\nTo enable exact alarms:\n• Go to device settings\n• Find this app\n• Enable "Alarms & reminders"`;
    alert(message);
  }
  
  private async showBatteryOptimizationDeniedDialog(_education: PermissionEducation): Promise<void> {
    const message = `Battery optimization is enabled. This may prevent notifications from arriving on time.\n\nTo disable battery optimization:\n• Go to device settings\n• Find "Battery optimization"\n• Select this app\n• Choose "Don't optimize"`;
    alert(message);
  }
}

export default NotificationPermissionManager;
