import { useEffect } from 'react';
import { Center, Loader } from '@mantine/core';
import { Navigate, useLocation, useParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { notify } from '@ema-platform/ui';
import {
  PROFILE_FIELD_SECTION,
  useCurrentProfile,
  type ProfileRequirement,
} from '@ema-platform/auth';

/**
 * Seafarer registration is filled in from the profile (nationality, ID,
 * names, contact details) — the server refuses an application missing them,
 * so they're asked for up front instead of at submit time.
 *
 * Only the fields the Personal, Maritime Profile and Address tabs actually
 * mark required — matches `profileSchema` / `addressSchema`, so the gate is
 * always satisfiable by finishing those tabs and never blocks on an optional
 * field (place of birth, region/city/woreda, emergency contact) the forms
 * don't star.
 */
export const SEAFARER_PROFILE_REQUIREMENT: ProfileRequirement = {
  fields: [
    'firstName',
    'middleName',
    'lastName',
    'gender',
    'dob',
    'maritalStatus',
    'professionId',
    'idType',
    'idNumber',
    'nationality',
    'primaryPhoneNumber',
    'email',
  ],
  reason:
    'Seafarer registration is built from your profile — these details fill it in for you.',
};

const REGISTRATION_TYPE_KEY = 'SEAFARER_REGISTRATION';

/**
 * Sends an applicant with an incomplete profile to `/profile` before they can
 * reach seafarer registration. Wraps `/seafarer-registration` directly and
 * `/licensing/:typeCode/apply` when `typeCode` is the seafarer type — the
 * latter is the shared wizard route every licence type renders through, so
 * without it the gate is a decoration a deep link skips.
 *
 * Fires before the wizard starts, not mid-application, so nothing is lost —
 * unlike the case `ProfileRequirementGate`'s doc comment warns against
 * (mid-flow redirects on the old, deleted setup wizard).
 */
export function RequireSeafarerProfile({ children }: { children: React.ReactNode }) {
  const { t } = useTranslation();
  const { typeCode } = useParams();
  const { pathname } = useLocation();
  const { isLoading, isFetching, error, gapsFor } = useCurrentProfile();

  // Shared wizard route — only the seafarer type is gated here.
  const gated = !typeCode || typeCode === REGISTRATION_TYPE_KEY;
  const gaps = gated ? gapsFor(SEAFARER_PROFILE_REQUIREMENT) : [];
  const redirecting = gated && !isLoading && !error && !isFetching && gaps.length > 0;

  useEffect(() => {
    if (!redirecting) return;
    const fields = gaps.map((field) => t(`profileFields.${field}`, field)).join(', ');
    notify.info(t('profileGate.seafarerRedirect', { fields }));
    // Fire once per redirect, not on every render while gaps/gapsFor are
    // recreated — the toast content is captured at the moment it fires.
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [redirecting, pathname]);

  if (!gated) return <>{children}</>;

  if (isLoading) {
    return (
      <Center h={200}>
        <Loader />
      </Center>
    );
  }

  // A failed lookup must not lock anyone out — the server still refuses the
  // application for a profile it can't fill in from.
  if (error) return <>{children}</>;

  if (gaps.length === 0) return <>{children}</>;

  // Gaps while a save is still landing are not an answer yet. Saving a
  // profile tab invalidates this query and the applicant may already be
  // headed back here in the same tick — deciding on the pre-save cache would
  // bounce them off the screen they just finished.
  if (isFetching) {
    return (
      <Center h={200}>
        <Loader />
      </Center>
    );
  }

  const target = PROFILE_FIELD_SECTION[gaps[0]];
  return <Navigate to={`/profile#${target}`} replace />;
}
