import messaging from '@react-native-firebase/messaging';
import notifee, { AndroidImportance, EventType } from '@notifee/react-native';
import { Platform } from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
import APIClient from '@aethex/core';

interface NotificationData {
  type: 'message' | 'call' | 'friend_request' | 'voice_channel';
  conversationId?: string;
  callId?: string;
  userId?: string;
  title: string;
  body: string;
  imageUrl?: string;
  actions?: Array<{ action: string; title: string }>;
}

class PushNotificationService {
  private apiClient: APIClient | null = null;

  async initialize(apiClient: APIClient) {
    this.apiClient = apiClient;

    // Request permissions
    const authStatus = await messaging().requestPermission();
    const enabled =
      authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
      authStatus === messaging.AuthorizationStatus.PROVISIONAL;

    if (enabled) {
      console.log('Push notification permission granted');
      await this.getFCMToken();
    }

    // Create notification channels (Android)
    if (Platform.OS === 'android') {
      await this.createChannels();
    }

    // Handle foreground messages
    messaging().onMessage(async (remoteMessage) => {
      await this.displayNotification(remoteMessage);
    });

    // Handle background messages
    messaging().setBackgroundMessageHandler(async (remoteMessage) => {
      console.log('Background message:', remoteMessage);
      await this.displayNotification(remoteMessage);
    });

    // Handle notification actions
    notifee.onBackgroundEvent(async ({ type, detail }) => {
      await this.handleNotificationEvent(type, detail);
    });

    notifee.onForegroundEvent(async ({ type, detail }) => {
      await this.handleNotificationEvent(type, detail);
    });

    // Handle token refresh
    messaging().onTokenRefresh(async (token) => {
      await this.updateFCMToken(token);
    });
  }

  async getFCMToken(): Promise<string> {
    const token = await messaging().getToken();
    console.log('FCM Token:', token);

    await this.updateFCMToken(token);
    return token;
  }

  private async updateFCMToken(token: string) {
    try {
      // Save locally
      await AsyncStorage.setItem('fcm_token', token);

      // Send to server
      if (this.apiClient) {
        await this.apiClient.request({
          method: 'POST',
          url: '/api/users/fcm-token',
          data: { token, platform: Platform.OS },
        });
      }
    } catch (error) {
      console.error('Error updating FCM token:', error);
    }
  }

  async createChannels() {
    // Messages channel
    await notifee.createChannel({
      id: 'messages',
      name: 'Messages',
      importance: AndroidImportance.HIGH,
      sound: 'message_sound',
      vibration: true,
      lights: true,
      lightColor: '#667eea',
    });

    // Calls channel
    await notifee.createChannel({
      id: 'calls',
      name: 'Calls',
      importance: AndroidImportance.HIGH,
      sound: 'call_sound',
      vibration: true,
      vibrationPattern: [300, 500],
    });

    // Voice channel
    await notifee.createChannel({
      id: 'voice_channel',
      name: 'Voice Channel',
      importance: AndroidImportance.LOW,
      sound: false,
    });

    // Friend requests
    await notifee.createChannel({
      id: 'social',
      name: 'Social',
      importance: AndroidImportance.DEFAULT,
      sound: 'default',
    });
  }

  async displayNotification(remoteMessage: any) {
    const { notification, data } = remoteMessage;
    const notifData: NotificationData = data as NotificationData;

    const channelId = this.getChannelId(notifData.type);

    const notificationConfig: any = {
      title: notification?.title || notifData.title,
      body: notification?.body || notifData.body,
      android: {
        channelId: channelId,
        smallIcon: 'ic_notification',
        color: '#667eea',
        pressAction: {
          id: 'default',
          launchActivity: 'default',
        },
        actions: this.getActions(notifData.type, notifData),
      },
      ios: {
        categoryId: notifData.type.toUpperCase(),
        attachments: notifData.imageUrl
          ? [
              {
                url: notifData.imageUrl,
                thumbnailHidden: false,
              },
            ]
          : undefined,
        sound: this.getSound(notifData.type),
      },
      data: data,
    };

    await notifee.displayNotification(notificationConfig);
  }

  private getChannelId(type: string): string {
    switch (type) {
      case 'call':
        return 'calls';
      case 'voice_channel':
        return 'voice_channel';
      case 'friend_request':
        return 'social';
      case 'message':
      default:
        return 'messages';
    }
  }

  private getActions(type: string, data: NotificationData) {
    if (Platform.OS !== 'android') return undefined;

    switch (type) {
      case 'message':
        return [
          {
            title: 'Reply',
            pressAction: { id: 'reply' },
            input: {
              placeholder: 'Type a message...',
              allowFreeFormInput: true,
            },
          },
          {
            title: 'Mark as Read',
            pressAction: { id: 'mark_read' },
          },
        ];

      case 'call':
        return [
          {
            title: 'Answer',
            pressAction: { id: 'answer_call' },
          },
          {
            title: 'Decline',
            pressAction: { id: 'decline_call' },
          },
        ];

      case 'friend_request':
        return [
          {
            title: 'Accept',
            pressAction: { id: 'accept_friend' },
          },
          {
            title: 'Decline',
            pressAction: { id: 'decline_friend' },
          },
        ];

      default:
        return undefined;
    }
  }

  private getSound(type: string): string {
    switch (type) {
      case 'call':
        return 'call_sound.wav';
      case 'message':
        return 'message_sound.wav';
      default:
        return 'default';
    }
  }

  private async handleNotificationEvent(type: EventType, detail: any) {
    const { notification, pressAction, input } = detail;

    if (type === EventType.PRESS) {
      // User tapped notification
      const data = notification?.data;
      console.log('Notification pressed:', data);
      // Navigate to appropriate screen
    }

    if (type === EventType.ACTION_PRESS && pressAction) {
      await this.handleAction(pressAction.id, notification?.data, input);
    }

    if (type === EventType.DISMISSED) {
      console.log('Notification dismissed');
    }
  }

  private async handleAction(actionId: string, data: any, input?: string) {
    if (!this.apiClient) return;

    try {
      switch (actionId) {
        case 'reply':
          if (input && data?.conversationId) {
            await this.apiClient.sendMessage(data.conversationId, input);
          }
          break;

        case 'mark_read':
          if (data?.conversationId) {
            await this.apiClient.request({
              method: 'POST',
              url: `/api/conversations/${data.conversationId}/read`,
            });
          }
          break;

        case 'answer_call':
          if (data?.callId) {
            await this.apiClient.joinCall(data.callId);
          }
          break;

        case 'decline_call':
          if (data?.callId) {
            await this.apiClient.request({
              method: 'POST',
              url: `/api/calls/${data.callId}/decline`,
            });
          }
          break;

        case 'accept_friend':
          if (data?.requestId) {
            await this.apiClient.acceptFriendRequest(data.requestId);
          }
          break;

        case 'decline_friend':
          if (data?.requestId) {
            await this.apiClient.request({
              method: 'POST',
              url: `/api/nexus/friends/reject/${data.requestId}`,
            });
          }
          break;
      }
    } catch (error) {
      console.error('Error handling notification action:', error);
    }
  }

  async cancelNotification(notificationId: string) {
    await notifee.cancelNotification(notificationId);
  }

  async cancelAllNotifications() {
    await notifee.cancelAllNotifications();
  }

  async getBadgeCount(): Promise<number> {
    if (Platform.OS === 'ios') {
      return await notifee.getBadgeCount();
    }
    return 0;
  }

  async setBadgeCount(count: number) {
    if (Platform.OS === 'ios') {
      await notifee.setBadgeCount(count);
    }
  }
}

export default new PushNotificationService();
