import { isPaginatedResponse } from '@/shared/types/pagination.types';

export type NotificationChannelKey = 'in_app' | 'email' | 'slack' | 'sms';

export interface NotificationItem {
  id: string;
  type: string;
  type_label: string;
  icon: string;
  color: string;
  title: string;
  message: string;
  data: Record<string, unknown> | null;
  related_type: string | null;
  related_id: string | null;
  is_read: boolean;
  read_at: string | null;
  created_at: string;
  created_at_human: string;
}

export interface NotificationChannels {
  in_app: boolean;
  email: boolean;
  slack: boolean;
  sms: boolean;
}

export interface NotificationPreference {
  id: string;
  notification_type: string;
  notification_type_label: string;
  channels: NotificationChannels;
  enabled_channels: NotificationChannelKey[];
}

export interface NotificationListResult {
  items: NotificationItem[];
  meta?: {
    current_page: number;
    last_page: number;
    per_page: number;
    total: number;
  };
}

export function isNotificationItem(value: unknown): value is NotificationItem {
  if (typeof value !== 'object' || value === null) {
    return false;
  }
  const item = value as Record<string, unknown>;
  return (
    typeof item.id === 'string' &&
    typeof item.title === 'string' &&
    typeof item.message === 'string' &&
    typeof item.is_read === 'boolean'
  );
}

export function isNotificationPreference(value: unknown): value is NotificationPreference {
  if (typeof value !== 'object' || value === null) {
    return false;
  }
  const pref = value as Record<string, unknown>;
  return typeof pref.id === 'string' && typeof pref.notification_type === 'string';
}

export function parseNotificationsList(raw: unknown): NotificationListResult {
  if (isPaginatedResponse(raw, isNotificationItem)) {
    return { items: raw.data, meta: raw.meta };
  }

  if (typeof raw === 'object' && raw !== null && 'data' in raw) {
    const data = (raw as { data: unknown }).data;
    if (Array.isArray(data) && data.every(isNotificationItem)) {
      const meta =
        'meta' in raw && typeof (raw as { meta: unknown }).meta === 'object'
          ? ((raw as { meta: NotificationListResult['meta'] }).meta ?? undefined)
          : undefined;
      return { items: data, meta };
    }
  }

  if (Array.isArray(raw) && raw.every(isNotificationItem)) {
    return { items: raw };
  }

  return { items: [] };
}

export function parseUnreadCount(raw: unknown): number {
  if (typeof raw === 'object' && raw !== null && 'unread_count' in raw) {
    const count = (raw as { unread_count: unknown }).unread_count;
    return typeof count === 'number' ? count : 0;
  }
  return 0;
}

export function parseNotificationPreferences(raw: unknown): NotificationPreference[] {
  if (Array.isArray(raw) && raw.every(isNotificationPreference)) {
    return raw;
  }

  if (typeof raw === 'object' && raw !== null && 'data' in raw) {
    const data = (raw as { data: unknown }).data;
    if (Array.isArray(data) && data.every(isNotificationPreference)) {
      return data;
    }
  }

  return [];
}

export function channelsToEnabledList(channels: NotificationChannels): NotificationChannelKey[] {
  const enabled: NotificationChannelKey[] = [];
  if (channels.in_app) {
    enabled.push('in_app');
  }
  if (channels.email) {
    enabled.push('email');
  }
  if (channels.slack) {
    enabled.push('slack');
  }
  if (channels.sms) {
    enabled.push('sms');
  }
  return enabled;
}

export function getNotificationTicketId(notification: NotificationItem): string | null {
  if (
    notification.related_id &&
    notification.related_type?.toLowerCase().includes('ticket')
  ) {
    return notification.related_id;
  }

  const data = notification.data;
  if (data && typeof data.ticket_id === 'string') {
    return data.ticket_id;
  }

  return null;
}
