import { ApolloLink, Observable } from '@apollo/client/core';
import { isCountryBanned, findBannedCountry } from '../../config/bannedCountries';
import { reverseGeocode } from '../../utils/reverseGeocode';

// Chokepoint: intercept every DeviceLocationUpdate mutation, reverse-geocode the
// input coords, and refuse to forward if the country is on Feeld's restricted list.
// This catches paths that bypass the React-level gates (ApiExplorer raw GraphQL,
// scanner loops, anything that calls the mutation directly).

export const bannedCountryLink = new ApolloLink((operation, forward) => {
  if (operation.operationName !== 'DeviceLocationUpdate') {
    return forward(operation);
  }

  const input = (operation.variables as any)?.input ?? {};
  const lat = Number(input.latitude);
  const lng = Number(input.longitude);

  if (!Number.isFinite(lat) || !Number.isFinite(lng)) {
    return forward(operation);
  }

  return new Observable((observer) => {
    let cancelled = false;
    let subscription: { unsubscribe: () => void } | null = null;

    reverseGeocode(lat, lng)
      .then((result) => {
        if (cancelled) return;

        if (result.resolved && isCountryBanned(result.country, result.countryCode)) {
          const hit = findBannedCountry(result.country, result.countryCode);
          const name = hit?.name ?? result.country ?? result.countryCode ?? 'this country';
          const msg = `[bannedCountryLink] Refusing DeviceLocationUpdate — Feeld is not available in ${name} (${lat.toFixed(3)}, ${lng.toFixed(3)})`;
          console.warn(msg);
          observer.error(new Error(`Feeld is not available in ${name}. Pick a different location.`));
          return;
        }

        if (!result.resolved) {
          console.warn(
            `[bannedCountryLink] Could not resolve country for (${lat.toFixed(3)}, ${lng.toFixed(3)}); forwarding mutation.`
          );
        }

        subscription = forward(operation).subscribe(observer);
      })
      .catch((err) => {
        // Reverse-geocode crashed unexpectedly — fail open (forward) to avoid breaking legitimate ops.
        if (cancelled) return;
        console.warn('[bannedCountryLink] Reverse-geocode error, forwarding anyway:', err);
        subscription = forward(operation).subscribe(observer);
      });

    return () => {
      cancelled = true;
      subscription?.unsubscribe();
    };
  });
});
