import Constants from 'expo-constants';
import * as Device from 'expo-device';
import * as Notifications from 'expo-notifications';
import { Platform } from 'react-native';
import { api } from './api';

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

export type PushRegistrationResult =
  | { status: 'registered'; token: string }
  | { status: 'skipped'; reason: string }
  | { status: 'failed'; reason: string };

async function ensureAndroidChannel(): Promise<void> {
  if (Platform.OS !== 'android') return;
  await Notifications.setNotificationChannelAsync('service-updates', {
    name: 'Service updates',
    description: 'Engineer assignment, schedule and service ticket updates.',
    importance: Notifications.AndroidImportance.HIGH,
    vibrationPattern: [0, 250, 250, 250],
    lightColor: '#1FA8E2',
    sound: 'default',
    lockscreenVisibility: Notifications.AndroidNotificationVisibility.PRIVATE,
  });
}

export async function registerForPushNotifications(): Promise<PushRegistrationResult> {
  try {
    await ensureAndroidChannel();

    if (!Device.isDevice) {
      return { status: 'skipped', reason: 'Push registration requires a physical device or supported emulator.' };
    }

    const current = await Notifications.getPermissionsAsync();
    let permission = current.status;
    if (permission !== 'granted') {
      permission = (await Notifications.requestPermissionsAsync()).status;
    }
    if (permission !== 'granted') {
      return { status: 'skipped', reason: 'Notification permission was not granted.' };
    }

    const projectId = Constants.expoConfig?.extra?.eas?.projectId ?? Constants.easConfig?.projectId;
    if (!projectId) {
      return { status: 'skipped', reason: 'EAS project is not linked yet. Run eas init before the production build.' };
    }

    const token = (await Notifications.getExpoPushTokenAsync({ projectId })).data;
    await api.registerPushDevice({
      token,
      platform: Platform.OS,
      deviceName: Device.deviceName ?? 'COLORJET Engineer Android',
      deviceModel: Device.modelName ?? undefined,
      appVersion: Constants.expoConfig?.version ?? undefined,
    });
    return { status: 'registered', token };
  } catch (error) {
    return { status: 'failed', reason: error instanceof Error ? error.message : 'Push registration failed.' };
  }
}

export function addNotificationListeners(input: {
  onReceive?: (notification: Notifications.Notification) => void;
  onResponse?: (response: Notifications.NotificationResponse) => void;
}) {
  const receive = Notifications.addNotificationReceivedListener(notification => input.onReceive?.(notification));
  const response = Notifications.addNotificationResponseReceivedListener(event => input.onResponse?.(event));
  return () => {
    receive.remove();
    response.remove();
  };
}
