import * as Notifications from 'expo-notifications';
import Constants from 'expo-constants';
import { pb } from './pocketbase';
import { getOrCreateDeviceId } from './household';

Notifications.setNotificationHandler({
  handleNotification: async () => ({
    shouldShowAlert: true,
    shouldPlaySound: true,
    shouldSetBadge: false,
    shouldShowBanner: true,
    shouldShowList: true,
  }),
});

export async function requestNotificationPermission(): Promise<boolean> {
  const { status } = await Notifications.requestPermissionsAsync();
  return status === 'granted';
}

export async function getFcmToken(): Promise<string | null> {
  try {
    const projectId =
      Constants.expoConfig?.extra?.eas?.projectId ??
      (Constants as any).easConfig?.projectId;
    const token = await Notifications.getExpoPushTokenAsync(
      projectId ? { projectId } : {}
    );
    return token.data;
  } catch {
    return null;
  }
}

export async function updateFcmToken(householdId: string, enabled: boolean): Promise<void> {
  const deviceId = await getOrCreateDeviceId();
  const token = enabled ? await getFcmToken() : null;

  const existing = await pb.collection('members').getFullList({
    filter: `device_id = "${deviceId}" && household = "${householdId}"`,
  });
  if (existing.length === 0) return;

  await pb.collection('members').update(existing[0].id, {
    fcm_token: token,
    notifications_enabled: enabled,
  });
}

export async function sendShoppingListPush(
  householdId: string,
  itemName: string
): Promise<void> {
  try {
    const deviceId = await getOrCreateDeviceId();
    const members = await pb.collection('members').getFullList({
      filter: `household = "${householdId}" && notifications_enabled = true && fcm_token != ""`,
    });
    const tokens = members
      .filter((m) => m.device_id !== deviceId)
      .map((m) => m.fcm_token as string)
      .filter((t) => t?.startsWith('ExponentPushToken'));

    if (tokens.length === 0) return;

    await fetch('https://exp.host/--/api/v2/push/send', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
      body: JSON.stringify(
        tokens.map((to) => ({
          to,
          title: 'Einkaufsliste',
          body: `${itemName} wurde hinzugefügt`,
          sound: 'default',
        }))
      ),
    });
  } catch (e) {
    console.warn('sendShoppingListPush failed:', e);
  }
}

export async function scheduleExpiryCheck(
  items: Array<{ name: string; expiryDate: Date | null }>
) {
  await Notifications.cancelAllScheduledNotificationsAsync();

  const now = new Date();
  const threeDays = 3 * 24 * 60 * 60 * 1000;

  const expiringSoon = items.filter(
    (item) =>
      item.expiryDate &&
      item.expiryDate.getTime() - now.getTime() <= threeDays &&
      item.expiryDate.getTime() > now.getTime()
  );

  for (const item of expiringSoon) {
    await Notifications.scheduleNotificationAsync({
      content: {
        title: 'MHD läuft ab',
        body: `${item.name} läuft in ≤ 3 Tagen ab!`,
        data: {},
      },
      trigger: null,
    });
  }
}
