import { Platform, AppState, AppStateStatus } from 'react-native';
import type { WSChatMessage, WSNotificationMessage, WSAnnouncementMessage } from '../core/wsService';
import { extractTextFromSegments } from '@/types/dto';
import { getNotificationPreferencesSync } from './notificationPreferences';
import { vibrateOnMessage } from '../platform/messageVibrationService';
import { useMessageStore } from '@/stores/message/store';
import { normalizeConversationId } from '@/stores/message/store';
import { jpushService } from './jpushService';

export type AppNotificationType =
  | 'like_post'
  | 'like_comment'
  | 'like_reply'
  | 'favorite_post'
  | 'comment'
  | 'reply'
  | 'follow'
  | 'mention'
  | 'system'
  | 'announcement'
  | 'announce'
  | 'chat';

export function getNotificationTitle(type: AppNotificationType, operatorName?: string): string {
  const titles: Record<AppNotificationType, string> = {
    like_post: '有人赞了你的帖子',
    like_comment: '有人赞了你的评论',
    like_reply: '有人赞了你的回复',
    favorite_post: '有人收藏了你的帖子',
    comment: '新评论',
    reply: '新回复',
    follow: '新粉丝',
    mention: '@提及',
    system: '系统通知',
    announcement: '公告',
    announce: '公告',
    chat: '新消息',
  };
  return titles[type] || '新通知';
}

class SystemNotificationService {
  private isInitialized: boolean = false;
  private appStateSubscription: any = null;
  private currentAppState: AppStateStatus = 'active';
  private shownNotificationIds: Set<string> = new Set();
  private static readonly MAX_DEDUP_SIZE = 500;

  async initialize(): Promise<boolean> {
    if (this.isInitialized) {
      return true;
    }

    this.currentAppState = AppState.currentState;
    this.appStateSubscription = AppState.addEventListener('change', (nextAppState) => {
      this.currentAppState = nextAppState;
    });

    this.isInitialized = true;
    return true;
  }

  async showNotification(options: {
    title: string;
    body: string;
    data?: Record<string, string | number | object>;
    type: AppNotificationType;
  }): Promise<string | null> {
    try {
      if (!getNotificationPreferencesSync().pushEnabled) {
        return null;
      }

      if (Platform.OS === 'web') {
        // Web: use browser Notification API
        if ('Notification' in window) {
          const permission = await Notification.requestPermission();
          if (permission === 'granted') {
            const notification = new Notification(options.title, {
              body: options.body,
              data: options.data,
            });
            return notification.tag || null;
          }
        }
        return null;
      }

      // Mobile: use JPush local notification
      const extras: Record<string, string> = {};
      if (options.data) {
        for (const [key, value] of Object.entries(options.data)) {
          extras[key] = String(value);
        }
      }
      extras['notification_type'] = options.type;

      const notificationId = `notif_${options.type}_${Date.now()}`;

      jpushService.addLocalNotification({
        messageID: notificationId,
        title: options.title,
        content: options.body,
        extras,
      });

      return notificationId;
    } catch (error) {
      console.error('[SystemNotification] show notification failed:', error);
      return null;
    }
  }

  async showChatNotification(message: WSChatMessage): Promise<string | null> {
    const body = extractTextFromSegments(message.segments);
    return this.showNotification({
      title: '新消息',
      body,
      data: {
        type: 'chat',
        conversationId: message.conversation_id,
        messageId: String(message.id),
        senderId: message.sender_id,
      },
      type: 'chat',
    });
  }

  async showWSNotification(message: WSNotificationMessage | WSAnnouncementMessage): Promise<string | null> {
    const type = message.system_type as AppNotificationType;
    const title = getNotificationTitle(type);
    const body = message.content;

    return this.showNotification({
      title,
      body,
      data: {
        type: message.type,
        id: String(message.id),
        senderId: message.sender_id || '',
        receiverId: message.receiver_id || '',
        systemType: message.system_type || '',
        extraData: JSON.stringify(message.extra_data || {}),
      },
      type,
    });
  }

  async handleWSMessage(message: WSChatMessage | WSNotificationMessage | WSAnnouncementMessage): Promise<void> {
    if (!getNotificationPreferencesSync().pushEnabled) {
      return;
    }

    const msgId = String(message.id || '');
    if (msgId && this.shownNotificationIds.has(msgId)) {
      return;
    }

    if ('is_read' in message && (message as any).is_read) {
      return;
    }

    if (msgId) {
      this.shownNotificationIds.add(msgId);
      if (this.shownNotificationIds.size > SystemNotificationService.MAX_DEDUP_SIZE) {
        const toRemove: string[] = [];
        let count = 0;
        for (const id of this.shownNotificationIds) {
          if (count >= SystemNotificationService.MAX_DEDUP_SIZE / 2) break;
          toRemove.push(id);
          count++;
        }
        for (const id of toRemove) {
          this.shownNotificationIds.delete(id);
        }
      }
    }

    // Only show local notification when app is in background
    if (this.currentAppState !== 'active') {
      if ('segments' in message) {
        const chatMsg = message as WSChatMessage;
        const conversationId = normalizeConversationId(chatMsg.conversation_id);
        const isNotificationMuted = useMessageStore.getState().isNotificationMuted(conversationId);
        if (isNotificationMuted) {
          return;
        }
        await this.showChatNotification(chatMsg);
      } else {
        const notifMsg = message as WSNotificationMessage | WSAnnouncementMessage;
        vibrateOnMessage('notification').catch(() => {});
        await this.showWSNotification(notifMsg);
      }
    } else {
      // App is in foreground: trigger vibration feedback
      if ('segments' in message) {
        const chatMsg = message as WSChatMessage;
        const conversationId = normalizeConversationId(chatMsg.conversation_id);
        const isNotificationMuted = useMessageStore.getState().isNotificationMuted(conversationId);
        if (!isNotificationMuted) {
          vibrateOnMessage('chat').catch(() => {});
        }
      } else {
        vibrateOnMessage('notification').catch(() => {});
      }
    }
  }

  async clearAllNotifications(): Promise<void> {
    jpushService.clearAllNotifications();
  }

  async clearBadge(): Promise<void> {
    jpushService.setBadge(0);
  }

  async setBadgeCount(count: number): Promise<void> {
    jpushService.setBadge(count);
  }

  cleanup(): void {
    if (this.appStateSubscription) {
      this.appStateSubscription.remove();
      this.appStateSubscription = null;
    }
    this.isInitialized = false;
  }

  getAppState(): AppStateStatus {
    return this.currentAppState;
  }
}

export const systemNotificationService = new SystemNotificationService();