import {
  Alert,
  Badge,
  Button,
  Card,
  Group,
  List,
  Stack,
  Text,
  ThemeIcon,
  Title,
} from '@mantine/core';
import {
  IconArrowRight,
  IconCircleCheck,
  IconCircleX,
  IconInfoCircle,
} from '@tabler/icons-react';
import { useNavigate } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import {
  STATUS_COLORS,
  STATUS_LABELS,
  TERMINAL_STATUSES,
  extractErrorMessage,
  useLocalized,
  useBypassPaymentMutation,
  useGetCertificateUrlMutation,
  useGetMyApplicationsQuery,
  useGetMyLicensesQuery,
} from '@ema-platform/api';
import { useCurrentProfile } from '@ema-platform/auth';
import { AdvancedTable, PageLoader, notify, useServerTable } from '@ema-platform/ui';
import { useDateDisplayer } from '@ema-platform/shared';
import { useApplicationPayment } from '../../payments/hooks/useApplicationPayment';
import { endorsementColumns } from './columns';

// ENDORSEMENT_SEAFARER covers CoC and GOC together and is the only type new
// applications file against; the other two stay listed so an application or
// licence filed before the switch keeps showing up here.
const ENDORSEMENT_TYPE_KEYS = [
  'ENDORSEMENT_SEAFARER',
  'ENDORSEMENT_COC',
  'ENDORSEMENT_GOC',
];

function EligibilityItem({ ok, label }: { ok: boolean; label: string }) {
  return (
    <List.Item
      icon={
        <ThemeIcon
          color={ok ? 'teal' : 'red'}
          variant="light"
          size="sm"
          radius="xl"
        >
          {ok ? <IconCircleCheck size={14} /> : <IconCircleX size={14} />}
        </ThemeIcon>
      }
    >
      {label}
    </List.Item>
  );
}

/**
 * Endorsements home, mirroring CertificatesPage: eligibility at a glance, the
 * two application entry points (CoC / GOC), and the seafarer's endorsement
 * applications and issued endorsements. The wizard itself is the
 * config-driven licensing flow.
 */
export function EndorsementPage() {
  const { t } = useTranslation();
  const navigate = useNavigate();
  const { profile, isLoading: loadingProfile } = useCurrentProfile();
  const { data: applications, isLoading: loadingApplications } =
    useGetMyApplicationsQuery();
  const {
    data: licenses,
    isFetching: fetchingLicenses,
    refetch: refetchLicenses,
  } = useGetMyLicensesQuery();
  const showDate = useDateDisplayer();
  const localized = useLocalized();
  const [getCertificateUrl] = useGetCertificateUrlMutation();
  const { pay, isPaying } = useApplicationPayment();
  const [bypassPayment, { isLoading: bypassing }] = useBypassPaymentMutation();
  const issuedTable = useServerTable();

  const registered =
    Boolean(profile?.seafarerNumber) && profile?.seafarerStatus === 'ACTIVE';

  const endorsementApplications = (applications?.items ?? []).filter((app) =>
    ENDORSEMENT_TYPE_KEYS.includes(app.licenseType?.key ?? ''),
  );
  const inFlight = endorsementApplications.filter(
    (app) => !TERMINAL_STATUSES.includes(app.status),
  );
  const issued = (licenses?.items ?? []).filter((license) =>
    ENDORSEMENT_TYPE_KEYS.includes(license.licenseType?.key ?? ''),
  );
  const issuedPage = issuedTable.paginate(issued);

  async function handleBypass(applicationId: string) {
    try {
      const result = await bypassPayment(applicationId).unwrap();
      notify.success(
        result.certificateIssued
          ? t('endorsement.bypassIssued', 'Payment bypassed — the endorsement has been issued.')
          : t('endorsement.bypassOk', {
              defaultValue: 'Payment bypassed — application is now {{status}}.',
              status: result.status.replace(/_/g, ' ').toLowerCase(),
            }),
      );
    } catch (err) {
      notify.error(extractErrorMessage(err, t('endorsement.bypassFailed', 'Bypass failed')));
    }
  }

  async function download(licenseId: string) {
    try {
      const result = await getCertificateUrl(licenseId).unwrap();
      window.open(result.url, '_blank', 'noopener');
    } catch (error) {
      notify.error(
        extractErrorMessage(error, t('endorsement.fetchFailed', 'Could not fetch endorsement')),
      );
    }
  }

  if (loadingProfile || loadingApplications) {
    return <PageLoader label={t('endorsement.loading', 'Loading Endorsements…')} height={400} />;
  }

  return (
    <Stack maw={860} mx="auto">
      <Title order={2}>{t('endorsement.title', 'My Endorsements')}</Title>

      <Card withBorder radius="md" p="lg">
        <Group justify="space-between" align="flex-start">
          <div>
            <Text fw={600} mb={6}>
              {t('endorsement.eligibility.title', 'Eligibility')}
            </Text>
            <List spacing={4} size="sm">
              <EligibilityItem
                ok={registered}
                label={
                  registered
                    ? t('endorsement.eligibility.registered', {
                        defaultValue: 'Registered seafarer ({{number}})',
                        number: profile?.seafarerNumber,
                      })
                    : t(
                        'endorsement.eligibility.registrationRequired',
                        'Active seafarer registration required',
                      )
                }
              />
            </List>
          </div>
          <Button
            disabled={!registered}
            rightSection={<IconArrowRight size={16} />}
            onClick={() => navigate('/licensing/ENDORSEMENT_SEAFARER/apply')}
          >
            {t('endorsement.apply', 'Apply for an endorsement')}
          </Button>
        </Group>
        {!registered && (
          <Alert color="orange" mt="md" icon={<IconInfoCircle size={16} />}>
            {t('endorsement.registrationNotice.prefix', 'Complete your')}{' '}
            <Text
              component="span"
              c="blue"
              style={{ cursor: 'pointer' }}
              onClick={() => navigate('/seafarer-registration')}
            >
              {t('endorsement.registrationNotice.link', 'seafarer registration')}
            </Text>{' '}
            {t(
              'endorsement.registrationNotice.suffix',
              'first — endorsement applications are refused without it.',
            )}
          </Alert>
        )}
      </Card>

      {inFlight.length > 0 && (
        <Stack gap="xs">
          <Title order={4}>{t('endorsement.inProgress', 'Applications in progress')}</Title>
          {inFlight.map((app) => (
            <Card key={app.id} withBorder radius="md" p="md">
              <Group justify="space-between">
                <div>
                  <Text fw={600}>{app.applicationNumber}</Text>
                  <Text size="xs" c="dimmed">
                    {localized(app.licenseType?.name)}
                  </Text>
                </div>
                <Group>
                  <Badge color={STATUS_COLORS[app.status]}>
                    {t(`applications.status.${app.status}`, STATUS_LABELS[app.status])}
                  </Badge>
                  {app.status === 'PAYMENT_PENDING' && (
                    <>
                      <Button
                        size="compact-sm"
                        color="yellow"
                        loading={isPaying}
                        onClick={() => pay(app.id)}
                      >
                        {t('endorsement.pay', {
                          defaultValue: 'Pay {{amount}} {{currency}}',
                          amount: Number(app.feeAmount ?? 0).toLocaleString(),
                          currency: app.feeCurrency,
                        })}
                      </Button>
                      {/* ponytail: shown unconditionally for the testing
                          phase — the server still refuses it unless
                          ALLOW_PAYMENT_BYPASS is set and NODE_ENV is not
                          production. Re-gate on useGetPaymentCapabilitiesQuery
                          (like MyApplicationsPage) before prod. */}
                      <Button
                        size="compact-sm"
                        variant="default"
                        loading={bypassing}
                        onClick={() => handleBypass(app.id)}
                        title="Testing only — marks the fee paid"
                      >
                        {t('endorsement.bypass', 'Bypass payment')}
                      </Button>
                    </>
                  )}
                  <Button
                    size="compact-sm"
                    variant="light"
                    onClick={() =>
                      navigate(
                        `/licensing/${app.licenseType?.key}/applications/${app.id}`,
                      )
                    }
                  >
                    {app.status === 'DRAFT' || app.status === 'RESUBMIT_REQUIRED'
                      ? t('applications.actions.continue', 'Continue')
                      : t('applications.actions.view', 'View')}
                  </Button>
                </Group>
              </Group>
            </Card>
          ))}
        </Stack>
      )}

      <Stack gap="xs">
        <Title order={4}>{t('endorsement.issuedEndorsements', 'Issued endorsements')}</Title>
        <AdvancedTable
          tableName={t('endorsement.issuedEndorsements', 'Issued endorsements')}
          columns={endorsementColumns({ t, showDate, localized, onDownload: download })}
          data={issuedPage.rows}
          itemCount={issuedPage.itemCount}
          pageIndex={issuedPage.pageIndex}
          onPageChange={issuedTable.setPageIndex}
          pageSize={issuedTable.pageSize}
          refresh={refetchLicenses}
          isLoading={fetchingLicenses}
          emptyText={t('endorsement.emptyIssued', 'No endorsements issued yet.')}
        />
      </Stack>
    </Stack>
  );
}

export default EndorsementPage;
