import {
  Alert,
  Badge,
  Button,
  Card,
  Group,
  Loader,
  SimpleGrid,
  Stack,
  Text,
  Title,
} from '@mantine/core';
import { IconArrowRight, 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,
  useGetCertificateUrlMutation,
  useGetMyApplicationsQuery,
  useGetMyLicensesQuery,
} from '@ema-platform/api';
import { AdvancedTable, notify, useServerTable } from '@ema-platform/ui';
import { useDateDisplayer } from '@ema-platform/shared';
import {
  PORTAL_PERMISSIONS,
  RequirePermission,
  usePermissions,
} from '@ema-platform/auth';
import { waiverLetterColumns } from './columns';

const WAIVER_TYPE_KEYS = ['PRE_WAIVER', 'POST_WAIVER'];

/**
 * Maritime waiver home (US-WAV-001/002/009).
 *
 * The two waiver kinds are seeded licence types, so the application itself is
 * the config-driven wizard and this page only has to be the door: which kind
 * applies, what is in flight, and the issued letters (US-WAV-007) with their
 * verifiable references (US-WAV-010).
 */
export function WaiverPage() {
  const { t } = useTranslation();
  const navigate = useNavigate();
  const { data: applications, isLoading } = useGetMyApplicationsQuery();
  const { data: licenses, refetch } = useGetMyLicensesQuery();
  const [getCertificateUrl] = useGetCertificateUrlMutation();
  const showDate = useDateDisplayer();
  const localized = useLocalized();
  const lettersTable = useServerTable();
  const { can } = usePermissions();

  const waiverApplications = (applications?.items ?? []).filter((app) =>
    WAIVER_TYPE_KEYS.includes(app.licenseType?.key ?? ''),
  );
  const inFlight = waiverApplications.filter(
    (app) => !TERMINAL_STATUSES.includes(app.status),
  );
  const letters = (licenses?.items ?? []).filter((license) =>
    WAIVER_TYPE_KEYS.includes(license.licenseType?.key ?? ''),
  );

  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('waiver.fetchFailed', 'Could not fetch the letter')));
    }
  }

  if (isLoading) {
    return (
      <Group justify="center" py="xl">
        <Loader />
      </Group>
    );
  }

  const pagedLetters = lettersTable.paginate(letters);

  return (
    <Stack maw={900} mx="auto">
      <div>
        <Title order={2}>{t('waiver.title', 'Maritime Waiver')}</Title>
        <Text size="sm" c="dimmed">
          {t(
            'waiver.subtitle',
            'Apply for a waiver when Ethiopian Shipping & Logistics cannot carry your shipment. Approval issues the bank waiver letter.',
          )}
        </Text>
      </div>

      <SimpleGrid cols={{ base: 1, sm: 2 }} spacing="md">
        <Card withBorder radius="md" p="lg">
          <Text fw={600}>{t('waiver.preWaiver.title', 'Pre-waiver')}</Text>
          <Text size="sm" c="dimmed" mt={4} mb="md">
            {t(
              'waiver.preWaiver.body',
              'The cargo has not yet arrived. Applying before arrival avoids the post-waiver penalty.',
            )}
          </Text>
          <RequirePermission anyOf={[PORTAL_PERMISSIONS.APPLY_WAIVER]} hideOnly>
            <Button
              rightSection={<IconArrowRight size={16} />}
              onClick={() => navigate('/licensing/PRE_WAIVER/apply')}
            >
              {t('waiver.preWaiver.apply', 'Apply for a pre-waiver')}
            </Button>
          </RequirePermission>
        </Card>

        <Card withBorder radius="md" p="lg">
          <Text fw={600}>{t('waiver.postWaiver.title', 'Post-waiver')}</Text>
          <Text size="sm" c="dimmed" mt={4} mb="md">
            {t(
              'waiver.postWaiver.body',
              'The cargo has already arrived. Granted once per shipment, and only against a settled penalty with the receipt attached.',
            )}
          </Text>
          <RequirePermission anyOf={[PORTAL_PERMISSIONS.APPLY_WAIVER]} hideOnly>
            <Button
              variant="light"
              rightSection={<IconArrowRight size={16} />}
              onClick={() => navigate('/licensing/POST_WAIVER/apply')}
            >
              {t('waiver.postWaiver.apply', 'Apply for a post-waiver')}
            </Button>
          </RequirePermission>
        </Card>
      </SimpleGrid>

      <Alert color="blue" icon={<IconInfoCircle size={16} />}>
        {t(
          'waiver.oneShipmentNotice',
          'Each waiver covers one shipment, identified by its bill of lading. A second application quoting the same bill of lading is refused while the first is live.',
        )}
      </Alert>

      {inFlight.length > 0 && (
        <Stack gap="xs">
          <Title order={4}>{t('waiver.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>
                  <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('waiver.issuedLetters', 'Issued waiver letters')}</Title>
        <AdvancedTable
          tableName={t('waiver.issuedLetters', 'Issued waiver letters')}
          columns={waiverLetterColumns({
            t,
            can,
            localized,
            showDate,
            onDownload: (license) => download(license.id),
          })}
          data={pagedLetters.rows}
          itemCount={pagedLetters.itemCount}
          pageIndex={pagedLetters.pageIndex}
          onPageChange={lettersTable.setPageIndex}
          pageSize={lettersTable.pageSize}
          refresh={refetch}
          emptyText={t('waiver.emptyLetters', 'No waiver letters issued yet.')}
        />
      </Stack>
    </Stack>
  );
}

export default WaiverPage;
