// Notification Service for Push Notifications

import { Platform } from 'react-native';
import * as Notifications from 'expo-notifications';
import { useSettingsStore } from '@/stores/settings-store';
import { NotificationType } from '@/types/global';

// Define local types compatible with expo-notifications
interface NotificationConfig {
  id: string;
  type: NotificationType;
  title: string;
  body: string;
  data?: Record<string, unknown>;
  urgency?: 'normal' | 'high';
  sound?: string;
  badge?: number;
}

// Configure notification behavior
Notifications.setNotificationHandler({
  handleNotification: async () => {
    const settings = useSettingsStore.getState();
    
    // Check if notifications are enabled
    if (!settings.accountSettings.notificationsEnabled) {
      return {
        shouldShowBanner: false,
        shouldShowList: false,
        shouldPlaySound: false,
        shouldSetBadge: false,
      };
    }

    return {
      shouldShowBanner: true,
      shouldShowList: true,
      shouldPlaySound: settings.notificationPreferences.sound,
      shouldVibrate: settings.notificationPreferences.vibration,
      shouldSetBadge: settings.notificationPreferences.badgeCount,
    };
  },
});

// Notification channel configuration (Android)
export async function registerNotificationChannels(): Promise<void> {
  if (Platform.OS === 'android') {
    await Notifications.setNotificationChannelAsync('default', {
      name: 'default',
      importance: Notifications.AndroidImportance.MAX,
      vibrationPattern: [0, 250, 250, 250],
      lightColor: '#FF231F7C',
    });

    await Notifications.setNotificationChannelAsync('new-articles', {
      name: 'new-articles',
      importance: Notifications.AndroidImportance.DEFAULT,
      vibrationPattern: [0, 100],
    });

    await Notifications.setNotificationChannelAsync('episode-releases', {
      name: 'episode-releases',
      importance: Notifications.AndroidImportance.DEFAULT,
      vibrationPattern: [0, 100],
    });

    await Notifications.setNotificationChannelAsync('custom-alerts', {
      name: 'custom-alerts',
      importance: Notifications.AndroidImportance.MAX,
      vibrationPattern: [0, 250, 250, 250],
    });
  }
}

// Request notification permissions
export async function requestNotificationPermissions(): Promise<boolean> {
  const { status } = await Notifications.requestPermissionsAsync();
  return status === 'granted';
}

// Get current permission status
export async function getNotificationPermissionStatus(): Promise<'denied' | 'granted' | 'undetermined'> {
  const { status } = await Notifications.getPermissionsAsync();
  return status;
}

// Schedule a local notification
export async function scheduleNotification(
  notification: NotificationConfig
): Promise<string | null> {
  const settings = useSettingsStore.getState();
  
  // Check if notification type is enabled
  const isEnabled = getNotificationTypeEnabled(notification.type, settings);
  if (!isEnabled) {
    return null;
  }

  const trigger: Notifications.SchedulableNotificationTriggerInput = {
    type: Notifications.SchedulableTriggerInputTypes.TIME_INTERVAL,
    seconds: 1,
  };

  const content: Notifications.NotificationContentInput = {
    title: notification.title,
    body: notification.body,
    data: notification.data,
    sound: notification.sound,
    badge: notification.badge,
    priority: notification.urgency === 'high' 
      ? Notifications.AndroidNotificationPriority.HIGH 
      : Notifications.AndroidNotificationPriority.DEFAULT,
  };

  // Add channel ID for Android
  if (Platform.OS === 'android') {
    const channelId = getChannelIdForType(notification.type);
    if (channelId) {
      (trigger as Notifications.TimeIntervalTriggerInput).channelId = channelId;
    }
  }

  const scheduled = await Notifications.scheduleNotificationAsync({
    content,
    trigger,
  });

  return scheduled;
}

// Schedule notification at a specific time
export async function scheduleNotificationAtTime(
  notification: NotificationConfig,
  date: Date
): Promise<string | null> {
  const settings = useSettingsStore.getState();
  
  const isEnabled = getNotificationTypeEnabled(notification.type, settings);
  if (!isEnabled) {
    return null;
  }

  const trigger: Notifications.DateTriggerInput = {
    type: Notifications.SchedulableTriggerInputTypes.DATE,
    date,
  };

  const content: Notifications.NotificationContentInput = {
    title: notification.title,
    body: notification.body,
    data: notification.data,
    sound: notification.sound,
    badge: notification.badge,
  };

  // Add channel ID for Android
  if (Platform.OS === 'android') {
    const channelId = getChannelIdForType(notification.type);
    if (channelId) {
      trigger.channelId = channelId;
    }
  }

  const scheduled = await Notifications.scheduleNotificationAsync({
    content,
    trigger,
  });

  return scheduled;
}

// Cancel a scheduled notification
export async function cancelNotification(
  identifier: string
): Promise<void> {
  await Notifications.cancelScheduledNotificationAsync(identifier);
}

// Cancel all scheduled notifications
export async function cancelAllNotifications(): Promise<void> {
  await Notifications.cancelAllScheduledNotificationsAsync();
}

// Get all scheduled notifications
export async function getScheduledNotifications(): Promise<
  Notifications.NotificationRequest[]
> {
  return await Notifications.getAllScheduledNotificationsAsync();
}

// Show an immediate notification
export async function showNotification(
  notification: NotificationConfig
): Promise<void> {
  const settings = useSettingsStore.getState();
  
  const isEnabled = getNotificationTypeEnabled(notification.type, settings);
  if (!isEnabled) {
    return;
  }

  const content: Notifications.NotificationContentInput = {
    title: notification.title,
    body: notification.body,
    data: notification.data,
    sound: notification.sound,
    badge: notification.badge,
  };

  // For immediate notification, use null trigger
  await Notifications.scheduleNotificationAsync({
    content,
    trigger: null,
  });
}

// Set badge count
export async function setBadgeCount(count: number): Promise<void> {
  await Notifications.setBadgeCountAsync(count);
}

// Get badge count
export async function getBadgeCount(): Promise<number> {
  return await Notifications.getBadgeCountAsync();
}

// Add notification listener
export function addNotificationListener(
  callback: (notification: Notifications.Notification) => void
): () => void {
  const subscription = Notifications.addNotificationReceivedListener(callback);
  return () => subscription.remove();
}

// Add response listener
export function addNotificationResponseListener(
  callback: (response: Notifications.NotificationResponse) => void
): () => void {
  const subscription = Notifications.addNotificationResponseReceivedListener(callback);
  return () => subscription.remove();
}

// Check if notification type is enabled based on settings
function getNotificationTypeEnabled(
  type: NotificationType,
  settings: any
): boolean {
  switch (type) {
    case NotificationType.NEW_ARTICLE:
      return settings.notificationPreferences.newArticles;
    case NotificationType.EPISODE_RELEASE:
      return settings.notificationPreferences.episodeReleases;
    case NotificationType.CUSTOM_ALERT:
      return settings.notificationPreferences.customAlerts;
    default:
      return true;
  }
}

// Get channel ID for notification type (Android)
function getChannelIdForType(type: NotificationType): string | undefined {
  switch (type) {
    case NotificationType.NEW_ARTICLE:
      return 'new-articles';
    case NotificationType.EPISODE_RELEASE:
      return 'episode-releases';
    case NotificationType.CUSTOM_ALERT:
      return 'custom-alerts';
    default:
      return 'default';
  }
}

// Export notification types for use in other modules
export type { NotificationConfig };
export { NotificationType };
