import { useState } from 'react';
import {
  Anchor,
  Badge,
  Button,
  Card,
  Container,
  Divider,
  Group,
  Loader,
  SimpleGrid,
  Stack,
  Tabs,
  Text,
  ThemeIcon,
  Title,
} from '@mantine/core';
import {
  IconAnchor,
  IconCertificate,
  IconEye,
  IconHeartbeat,
  IconIdBadge2,
  IconPaperclip,
} from '@tabler/icons-react';
import { useTranslation } from 'react-i18next';
import { useDateDisplayer } from '@ema-platform/shared';
import { FilePreviewModal, notify } from '@ema-platform/ui';
import {
  extractErrorMessage,
  useGetAttachmentsQuery,
  useGetCertificateUrlMutation,
  useGetMyLicensesQuery,
  useGetMyMedicalCertificatesQuery,
  useGetMySeaServiceRecordsQuery,
  useGetMySeafarerDocumentsQuery,
  useLazyGetMySeafarerDocumentDownloadQuery,
  type SeafarerDocument,
  type SeafarerRecordStatus,
} from '@ema-platform/api';
import { LicenseCard, useRenewLicense } from '../../licensing/components/LicenseCard';
import { PersonalDocumentSlots } from '../components/PersonalDocumentSlots';

/** What the viewer needs: the link, a caption, and how to render it. */
type Preview = { url: string; title: string; mimeType?: string | null };

const RECORD_STATUS_COLOR: Record<SeafarerRecordStatus, string> = {
  SUBMITTED: 'blue',
  VERIFIED: 'teal',
  REJECTED: 'red',
};

/**
 * Placeholder until this feature has a backend.
 *
 * This page previously rendered invented figures/records that were
 * indistinguishable from real ones.
 */
function RecordFiles({
  ownerType,
  ownerId,
  onPreview,
}: {
  ownerType: 'SEA_SERVICE_RECORD' | 'MEDICAL_CERTIFICATE' | 'SEAFARER_REGISTRATION';
  ownerId: string;
  onPreview: (preview: Preview) => void;
}) {
  const { t } = useTranslation();
  const { data, isLoading } = useGetAttachmentsQuery({ ownerType, ownerId });
  const files = (data ?? []).flatMap((a) => a.files);

  if (isLoading) return <Loader size="xs" type="oval" />;
  if (files.length === 0)
    return (
      <Text fz="xs" c="dimmed">
        {t('documents.files.none')}
      </Text>
    );

  return (
    <Stack gap={4}>
      {files.map((file) => (
        <Group key={file.id} gap={6} wrap="nowrap">
          <IconPaperclip size={14} />
          {file.url ? (
            <Anchor
              component="button"
              type="button"
              fz="xs"
              onClick={() =>
                onPreview({
                  url: file.url as string,
                  title: file.originalName,
                  mimeType: file.mimeType,
                })
              }
            >
              {file.originalName}
            </Anchor>
          ) : (
            <Text fz="xs">{file.originalName}</Text>
          )}
        </Group>
      ))}
    </Stack>
  );
}

function FieldRow({ label, value }: { label: string; value: string }) {
  return (
    <Group justify="space-between" gap="xs" wrap="nowrap">
      <Text fz="xs" c="dimmed">
        {label}
      </Text>
      <Text fz="xs" fw={500} ta="right">
        {value}
      </Text>
    </Group>
  );
}

/** Seaman Book / BTC — issued on their own workflow, not as licences. */
function IssuedDocumentCard({
  document,
  onPreview,
}: {
  document: SeafarerDocument;
  onPreview: (preview: Preview) => void;
}) {
  const { t } = useTranslation();
  const showDate = useDateDisplayer();
  const [download, { isFetching }] = useLazyGetMySeafarerDocumentDownloadQuery();
  const issued = document.status === 'ISSUED';

  async function open() {
    try {
      const { url } = await download(document.id).unwrap();
      onPreview({ url, title: t(`documents.kind.${document.kind}`) });
    } catch (err) {
      notify.error(extractErrorMessage(err), t('documents.openFailed'));
    }
  }

  return (
    <Card withBorder radius="md" padding="md">
      <Group justify="space-between" align="flex-start" wrap="nowrap">
        <Group gap="sm" wrap="nowrap">
          <ThemeIcon size="lg" variant="light" color={issued ? 'teal' : 'gray'} radius="md">
            <IconCertificate size={18} stroke={1.5} />
          </ThemeIcon>
          <div>
            <Text fz="sm" fw={600}>
              {t(`documents.kind.${document.kind}`)}
            </Text>
            <Text fz="xs" c="dimmed">
              {document.documentNumber ?? document.requestNumber}
            </Text>
          </div>
        </Group>
        <Badge size="sm" variant="light" color={issued ? 'teal' : 'gray'} style={{ flexShrink: 0 }}>
          {t(`documents.documentStatus.${document.status}`, { defaultValue: document.status })}
        </Badge>
      </Group>

      <Divider my="sm" />

      <Stack gap={4}>
        {document.issueDate && (
          <FieldRow label={t('seaRecords.columns.issued')} value={showDate(document.issueDate)} />
        )}
        {document.expiryDate && (
          <FieldRow label={t('seaRecords.columns.expires')} value={showDate(document.expiryDate)} />
        )}
      </Stack>

      <Button
        mt="sm"
        size="xs"
        variant="light"
        fullWidth
        leftSection={<IconEye size={14} />}
        disabled={!issued}
        loading={isFetching}
        onClick={open}
      >
        {issued ? t('documents.view') : t('documents.notIssued')}
      </Button>
    </Card>
  );
}

export function DocumentVaultPage() {
  const { t } = useTranslation();
  const showDate = useDateDisplayer();
  const [preview, setPreview] = useState<Preview | null>(null);

  const { data: licences, isLoading: loadingLicences } = useGetMyLicensesQuery();
  const { data: issuedDocuments } = useGetMySeafarerDocumentsQuery();
  const { data: medicals, isLoading: loadingMedicals } = useGetMyMedicalCertificatesQuery();
  const { data: seaService, isLoading: loadingSeaService } = useGetMySeaServiceRecordsQuery();

  const [getCertificateUrl, { isLoading: isDownloadingCert }] = useGetCertificateUrlMutation();
  const { renewLicense, isRenewing } = useRenewLicense();

  async function openCertificate(licenseId: string) {
    try {
      const { url } = await getCertificateUrl(licenseId).unwrap();
      setPreview({ url, title: t('licensing.card.downloadCertificate') });
    } catch (err) {
      notify.error(extractErrorMessage(err), t('documents.openFailed'));
    }
  }

  const licenceItems = licences?.items ?? [];
  const issued = [issuedDocuments?.seamanBook, issuedDocuments?.btc].filter(
    (d): d is SeafarerDocument => Boolean(d),
  );

  return (
    <Container size="lg" py="xl">
      <Stack gap="md">
        <div>
          <Title order={3}>{t('documents.title')}</Title>
          <Text fz="sm" c="dimmed">
            {t('documents.subtitle')}
          </Text>
        </div>

        <Tabs defaultValue="license" variant="outline" radius="md" keepMounted={false}>
          <Tabs.List mb="md">
            <Tabs.Tab value="license" leftSection={<IconCertificate size={16} />}>
              {t('documents.tabs.license')}
            </Tabs.Tab>
            <Tabs.Tab value="medical" leftSection={<IconHeartbeat size={16} />}>
              {t('documents.tabs.medical')}
            </Tabs.Tab>
            <Tabs.Tab value="sea-service" leftSection={<IconAnchor size={16} />}>
              {t('documents.tabs.seaService')}
            </Tabs.Tab>
            <Tabs.Tab value="personal" leftSection={<IconIdBadge2 size={16} />}>
              {t('documents.tabs.personal')}
            </Tabs.Tab>
          </Tabs.List>

          {/* ── Licences and EMA-issued documents ───────────────────────── */}
          <Tabs.Panel value="license">
            <Stack gap="xl">
              {issued.length > 0 && (
                <div>
                  <Text fw={700} fz="sm" mb="sm" tt="uppercase" c="dimmed">
                    {t('documents.issuedTitle')}
                  </Text>
                  <SimpleGrid cols={{ base: 1, sm: 2, lg: 3 }} spacing="md">
                    {issued.map((document) => (
                      <IssuedDocumentCard
                        key={document.id}
                        document={document}
                        onPreview={setPreview}
                      />
                    ))}
                  </SimpleGrid>
                </div>
              )}

              <div>
                <Text fw={700} fz="sm" mb="sm" tt="uppercase" c="dimmed">
                  {t('documents.licensesTitle')}
                </Text>
                {loadingLicences ? (
                  <Loader size="sm" type="oval" />
                ) : licenceItems.length === 0 ? (
                  <Text fz="sm" c="dimmed">
                    {t('documents.empty.licenses')}
                  </Text>
                ) : (
                  // Two per row, not three: licence type names run long
                  // ("Multimodal Transport Operator License") and a third
                  // column truncates them.
                  <SimpleGrid cols={{ base: 1, md: 2 }} spacing="md">
                    {licenceItems.map((licence) => (
                      <LicenseCard
                        key={licence.id}
                        license={licence}
                        isDownloading={isDownloadingCert}
                        isRenewing={isRenewing}
                        onDownload={() => openCertificate(licence.id)}
                        onRenew={() => renewLicense(licence)}
                      />
                    ))}
                  </SimpleGrid>
                )}
              </div>
            </Stack>
          </Tabs.Panel>

          {/* ── Medical certificates ────────────────────────────────────── */}
          <Tabs.Panel value="medical">
            {loadingMedicals ? (
              <Loader size="sm" type="oval" />
            ) : (medicals ?? []).length === 0 ? (
              <Text fz="sm" c="dimmed">
                {t('documents.empty.medical')}
              </Text>
            ) : (
              <SimpleGrid cols={{ base: 1, sm: 2, lg: 3 }} spacing="md">
                {(medicals ?? []).map((record) => (
                  <Card key={record.id} withBorder radius="md" padding="md">
                    <Group justify="space-between" align="flex-start" wrap="nowrap">
                      <Group gap="sm" wrap="nowrap">
                        <ThemeIcon size="lg" variant="light" color="pink" radius="md">
                          <IconHeartbeat size={18} stroke={1.5} />
                        </ThemeIcon>
                        <div>
                          <Text fz="sm" fw={600}>
                            {record.issuerName}
                          </Text>
                          {record.certificateNumber && (
                            <Text fz="xs" c="dimmed">
                              {t('seaRecords.columns.certNumber', {
                                number: record.certificateNumber,
                              })}
                            </Text>
                          )}
                        </div>
                      </Group>
                      <Badge
                        size="sm"
                        variant="light"
                        color={RECORD_STATUS_COLOR[record.status]}
                        style={{ flexShrink: 0 }}
                      >
                        {t(`seaRecords.columns.recordStatus.${record.status}`, {
                          defaultValue: record.status,
                        })}
                      </Badge>
                    </Group>

                    <Divider my="sm" />

                    <Stack gap={4}>
                      <FieldRow
                        label={t('seaRecords.columns.issued')}
                        value={showDate(record.issueDate)}
                      />
                      <FieldRow
                        label={t('seaRecords.columns.expires')}
                        value={showDate(record.expiryDate)}
                      />
                      <FieldRow
                        label={t('seaRecords.columns.fitness')}
                        value={t(`seaRecords.columns.fitnessOptions.${record.fitnessStatus}`, {
                          defaultValue: record.fitnessStatus,
                        })}
                      />
                    </Stack>

                    <Divider my="sm" />
                    <RecordFiles
                      ownerType="MEDICAL_CERTIFICATE"
                      ownerId={record.id}
                      onPreview={setPreview}
                    />
                  </Card>
                ))}
              </SimpleGrid>
            )}
          </Tabs.Panel>

          {/* ── Sea service records ─────────────────────────────────────── */}
          <Tabs.Panel value="sea-service">
            {loadingSeaService ? (
              <Loader size="sm" type="oval" />
            ) : (seaService ?? []).length === 0 ? (
              <Text fz="sm" c="dimmed">
                {t('documents.empty.seaService')}
              </Text>
            ) : (
              <SimpleGrid cols={{ base: 1, sm: 2, lg: 3 }} spacing="md">
                {(seaService ?? []).map((record) => (
                  <Card key={record.id} withBorder radius="md" padding="md">
                    <Group justify="space-between" align="flex-start" wrap="nowrap">
                      <Group gap="sm" wrap="nowrap">
                        <ThemeIcon size="lg" variant="light" color="blue" radius="md">
                          <IconAnchor size={18} stroke={1.5} />
                        </ThemeIcon>
                        <div>
                          <Text fz="sm" fw={600}>
                            {record.vesselName}
                          </Text>
                          {record.imoNumber && (
                            <Text fz="xs" c="dimmed">
                              {t('seaRecords.columns.imo', { number: record.imoNumber })}
                            </Text>
                          )}
                        </div>
                      </Group>
                      <Badge
                        size="sm"
                        variant="light"
                        color={RECORD_STATUS_COLOR[record.status]}
                        style={{ flexShrink: 0 }}
                      >
                        {t(`seaRecords.columns.recordStatus.${record.status}`, {
                          defaultValue: record.status,
                        })}
                      </Badge>
                    </Group>

                    <Divider my="sm" />

                    <Stack gap={4}>
                      <FieldRow label={t('seaRecords.columns.rank')} value={record.rank} />
                      <FieldRow
                        label={t('seaRecords.columns.from')}
                        value={showDate(record.engagementDate)}
                      />
                      <FieldRow
                        label={t('seaRecords.columns.to')}
                        value={showDate(record.dischargeDate)}
                      />
                    </Stack>

                    <Divider my="sm" />
                    <RecordFiles
                      ownerType="SEA_SERVICE_RECORD"
                      ownerId={record.id}
                      onPreview={setPreview}
                    />
                  </Card>
                ))}
              </SimpleGrid>
            )}
          </Tabs.Panel>

          {/* ── The applicant's own document vault ──────────────────────── */}
          <Tabs.Panel value="personal">
            {/* Owned by the profile, not by a registration or an application:
                the slots are configured in the backoffice and the files travel
                with the person. */}
            <PersonalDocumentSlots onPreview={setPreview} />
          </Tabs.Panel>
        </Tabs>
      </Stack>

      <FilePreviewModal
        opened={Boolean(preview)}
        onClose={() => setPreview(null)}
        url={preview?.url ?? ''}
        title={preview?.title}
        mimeType={preview?.mimeType}
        labels={{
          unsupported: t('documents.preview.unsupported'),
          openInNewTab: t('documents.preview.openInNewTab'),
          close: t('documents.preview.close'),
        }}
      />
    </Container>
  );
}

export default DocumentVaultPage;
