import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import {
  Alert,
  Badge,
  Button,
  Card,
  Divider,
  Group,
  Loader,
  Paper,
  SimpleGrid,
  Stack,
  Table,
  Text,
  ThemeIcon,
  Title,
  Tooltip,
  rem,
} from '@mantine/core';
import { notifications } from '@mantine/notifications';
import {
  IconArrowRight,
  IconBook2,
  IconCertificate,
  IconClock,
  IconDownload,
  IconEye,
  IconInfoCircle,
  IconShieldCheck,
} from '@tabler/icons-react';
import { authStorage, useCurrentProfile } from '@ema-platform/auth';
import { useApiQuery } from '@ema-platform/api';
import {
  useGetMySeaServiceRecordsQuery,
  useGetMyMedicalCertificatesQuery,
} from '@ema-platform/api';
import { PdfPreviewModal } from '@ema-platform/ui';

// ---------------------------------------------------------------------------
// Mock data
// ---------------------------------------------------------------------------
/** What `/certificates/my` returns: what is held, and what is still in flight. */
interface CertificatesOverview {
  certificates: {
    id: string;
    type: string;
    issued: string;
    expiry: string;
    status: string;
  }[];
  applications: {
    id: string;
    applicationId: string;
    type: string;
    submitted: string;
    status: string;
  }[];
}

/**
 * Badge colour per workflow status.
 *
 * Keyed by the values the API reports rather than display strings, so an
 * unmapped status falls back to grey instead of rendering colourless.
 */
const STATUS_COLOR: Record<string, string> = {
  DRAFT: 'gray',
  SUBMITTED: 'blue',
  UNDER_REVIEW: 'yellow',
  UNDER_EVALUATION: 'yellow',
  RESUBMIT_REQUIRED: 'orange',
  INSPECTION_PENDING: 'grape',
  INSPECTION_COMPLETED: 'grape',
  ELIGIBILITY_APPROVED: 'teal',
  EXAM_PAYMENT_PENDING: 'orange',
  EXAM_PAID: 'blue',
  EXAM_SCHEDULED: 'indigo',
  EXAM_PASSED: 'teal',
  EXAM_FAILED: 'red',
  APPROVED: 'teal',
  REJECTED: 'red',
  PAYMENT_PENDING: 'orange',
  PAID: 'blue',
  PAYMENT_CONFIRMED: 'blue',
  CERTIFICATE_ISSUED: 'teal',
  COMPLETED: 'teal',
  ACTIVE: 'teal',
  EXPIRED: 'red',
  SUSPENDED: 'orange',
  CANCELLED: 'gray',
  SUPERSEDED: 'gray',
};

/** Turns `EXAM_PAYMENT_PENDING` into something a person reads. */
function humanStatus(status: string): string {
  return status
    .toLowerCase()
    .split('_')
    .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
    .join(' ');
}

function formatDate(value: string | null | undefined): string {
  if (!value) return '—';
  return new Date(value).toLocaleDateString('en-GB', {
    day: '2-digit',
    month: 'short',
    year: 'numeric',
  });
}

const API_BASE =
  (import.meta as { env?: Record<string, string> }).env?.['VITE_BASE_API_URL'] ??
  'http://localhost:3000/api';

async function generateCertificate(profileId: string): Promise<Blob> {
  const token = authStorage.getToken();
  if (!token) throw new Error('No auth token found');
  const res = await fetch(
    `${API_BASE}/profiles/generate-seafarer-certificate/${profileId}`,
    { headers: { Authorization: `Bearer ${token}` } },
  );
  if (!res.ok) throw new Error(`Failed to generate certificate (${res.status})`);
  return res.blob();
}

function downloadBlob(blob: Blob, filename: string) {
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = filename;
  a.click();
  URL.revokeObjectURL(url);
}

export function CertificatesPage() {
  const navigate = useNavigate();
  const profileId = authStorage.getProfileId() ?? '';
  const [previewUrl, setPreviewUrl] = useState<string | null>(null);
  const [previewTitle, setPreviewTitle] = useState('');
  const [loading, setLoading] = useState(false);

  const { data } = useApiQuery<CertificatesOverview>({
    url: '/certificates/my',
    method: 'GET',
  });
  const certificates = data?.certificates ?? [];
  const applications = data?.applications ?? [];

  // eligibleForCoc is computed server-side (seafarer registration approved,
  // plus a verified sea service record and a verified medical certificate)
  // so the button and the API's own eligibility check can never disagree.
  // The three queries below only build the human-readable reason list for
  // the tooltip/banner — the gate itself is the one boolean.
  const { profile, eligibleForCoc: canApply } = useCurrentProfile();
  const { data: seaServiceRecords } = useGetMySeaServiceRecordsQuery();
  const { data: medicalCertificates } = useGetMyMedicalCertificatesQuery();

  const seafarerApproved = profile?.seafarerStatus === 'ACTIVE';
  const hasVerifiedSeaService = (seaServiceRecords ?? []).some((r) => r.status === 'VERIFIED');
  const hasVerifiedMedical = (medicalCertificates ?? []).some((c) => c.status === 'VERIFIED');

  const missingReasons = [
    !seafarerApproved && 'Your seafarer registration is not yet approved.',
    !hasVerifiedSeaService && 'No verified sea service record on file.',
    !hasVerifiedMedical && 'No verified medical certificate on file.',
  ].filter((r): r is string => Boolean(r));

  const openPreview = async (profileId: string, title: string) => {
    setLoading(true);
    try {
      const blob = await generateCertificate(profileId);
      const url = URL.createObjectURL(blob);
      setPreviewTitle(title);
      setPreviewUrl(url);
    } catch (err) {
      notifications.show({
        color: 'red',
        title: 'Error',
        message: err instanceof Error ? err.message : 'Could not generate certificate',
      });
    } finally {
      setLoading(false);
    }
  };

  const handleDownload = async (profileId: string, title: string) => {
    try {
      const blob = await generateCertificate(profileId);
      downloadBlob(blob, `certificate-${Date.now()}.pdf`);
      notifications.show({
        color: 'teal',
        title: 'Downloaded',
        message: 'Certificate PDF downloaded successfully',
      });
    } catch (err) {
      notifications.show({
        color: 'red',
        title: 'Error',
        message: err instanceof Error ? err.message : 'Could not download certificate',
      });
    }
  };

  return (
    <Stack gap="md">
      <Group justify="space-between" align="flex-start" wrap="wrap" gap="sm">
        <div>
          <Title order={3}>Certificates (CoC / CoP)</Title>
          <Text fz="sm" c="dimmed">Certificate of Competency and Certificate of Proficiency under STCW</Text>
        </div>
        <Tooltip
          label={missingReasons.join(' ')}
          disabled={canApply}
          multiline
          w={260}
          events={{ hover: true, focus: true, touch: true }}
        >
          {/* Tooltip needs a hoverable child even while the button itself is
              disabled, so the reason still shows on hover. */}
          <span>
            <Button
              leftSection={<IconShieldCheck size={15} />}
              rightSection={<IconArrowRight size={15} />}
              onClick={() => navigate('/certificates/apply')}
              disabled={!canApply}
            >
              Apply for CoC / CoP
            </Button>
          </span>
        </Tooltip>
      </Group>

      {!canApply && (
        <Alert variant="light" color="orange" icon={<IconInfoCircle size={15} />}>
          <Text fz="sm" fw={600}>Not yet eligible to apply</Text>
          <Text fz="xs" c="dimmed">{missingReasons.join(' ')}</Text>
        </Alert>
      )}

      {/* Info banner */}
      <Paper withBorder radius="lg" p="md" bg="var(--mantine-color-blue-light)">
        <Group gap="md" wrap="nowrap">
          <ThemeIcon size={48} radius="md" color="blue" variant="light"><IconShieldCheck size={24} /></ThemeIcon>
          <Stack gap={2} style={{ flex: 1 }}>
            <Text fw={700} fz="sm">What is a CoC / CoP?</Text>
            <SimpleGrid cols={{ base: 1, sm: 3 }} spacing="xs">
              {[
                { icon: IconBook2,        color: 'blue',  title: 'Certificate of Competency (CoC)', desc: 'Authorizes the holder to serve as an officer or master on board a ship under STCW.' },
                { icon: IconCertificate,  color: 'teal',  title: 'Certificate of Proficiency (CoP)', desc: 'Certifies completion of specific STCW training for specialized duties on board.' },
                { icon: IconClock,        color: 'orange', title: 'Validity', desc: 'CoC/CoP certificates are valid for 5 years and must be revalidated before expiry.' },
              ].map(({ icon: Icon, color, title, desc }) => (
                <Card key={title} withBorder radius="md" p="sm">
                  <Group gap="xs" mb={4}>
                    <ThemeIcon size={20} radius="sm" color={color} variant="light"><Icon size={12} /></ThemeIcon>
                    <Text fz="xs" fw={700}>{title}</Text>
                  </Group>
                  <Text fz="xs" c="dimmed" lh={1.4}>{desc}</Text>
                </Card>
              ))}
            </SimpleGrid>
          </Stack>
        </Group>
      </Paper>

      {/* Active applications */}
      <Paper withBorder radius="lg" p="xl">
        <Text fw={700} mb="md">My Applications</Text>
        {applications.length === 0 ? (
          <Alert variant="light" color="gray" icon={<IconInfoCircle size={15} />}>
            No active CoC/CoP applications. Click "Apply for CoC / CoP" to start.
          </Alert>
        ) : (
          <Table highlightOnHover fz="sm" verticalSpacing="sm">
            <Table.Thead bg="var(--mantine-color-default-hover)">
              <Table.Tr>
                {['App ID', 'Certificate Type', 'Submitted', 'Exam Date / Status Note', 'Status', ''].map((h) => (
                  <Table.Th key={h} style={{ fontSize: rem(11), textTransform: 'uppercase', color: 'var(--mantine-color-dimmed)' }}>{h}</Table.Th>
                ))}
              </Table.Tr>
            </Table.Thead>
            <Table.Tbody>
              {applications.map((app) => (
                <Table.Tr key={app.id}>
                  <Table.Td><Text fz="xs" fw={600} c="blue.7">{app.id}</Text></Table.Td>
                  <Table.Td><Text fz="xs" fw={500} maw={220} style={{ lineHeight: 1.3 }}>{app.type}</Text></Table.Td>
                  <Table.Td><Text fz="xs">{formatDate(app.submitted)}</Text></Table.Td>
                  <Table.Td>
                    <Text fz="xs" c="dimmed" maw={200} lh={1.3}>
                      {humanStatus(app.status)}
                    </Text>
                  </Table.Td>
                  <Table.Td>
                    <Badge
                      color={STATUS_COLOR[app.status] ?? 'gray'}
                      variant="light"
                      size="sm"
                    >
                      {humanStatus(app.status)}
                    </Badge>
                  </Table.Td>
                  <Table.Td>
                    <Text
                      fz="xs"
                      c="blue"
                      style={{ cursor: 'pointer' }}
                      onClick={() => navigate(`/applications/${app.applicationId}`)}
                    >
                      Details
                    </Text>
                  </Table.Td>
                </Table.Tr>
              ))}
            </Table.Tbody>
          </Table>
        )}
      </Paper>

      {/* Issued certificates */}
      <Paper withBorder radius="lg" p="xl">
        <Text fw={700} mb="md">My Certificates</Text>
        {certificates.length === 0 ? (
          <Alert variant="light" color="gray" icon={<IconInfoCircle size={15} />}>
            No certificates issued yet.
          </Alert>
        ) : (
          <SimpleGrid cols={{ base: 1, sm: 2 }} spacing="md">
            {certificates.map((cert) => (
              <Card key={cert.id} withBorder radius="md" p="md">
                <Group justify="space-between" mb="sm">
                  <Group gap="sm">
                    <ThemeIcon size={36} radius="md" color="blue" variant="light"><IconShieldCheck size={18} /></ThemeIcon>
                    <div>
                      <Text fw={700} fz="sm">{cert.type}</Text>
                      <Text fz="xs" c="dimmed">{cert.id}</Text>
                    </div>
                  </Group>
                  <Badge color={STATUS_COLOR[cert.status] ?? "gray"} variant="light">{cert.status}</Badge>
                </Group>
                <Divider mb="sm" />
                <SimpleGrid cols={2} spacing="xs">
                  <div><Text fz="xs" c="dimmed">Issued</Text><Text fz="sm" fw={500}>{cert.issued}</Text></div>
                  <div><Text fz="xs" c="dimmed">Expires</Text><Text fz="sm" fw={500}>{cert.expiry}</Text></div>
                </SimpleGrid>
                <Group mt="sm" gap="xs">
                  <Button size="xs" variant="light" leftSection={loading ? <Loader size={12} /> : <IconEye size={12} />} onClick={() => openPreview(profileId, cert.type)}>View</Button>
                  <Button size="xs" variant="default" leftSection={<IconDownload size={12} />} onClick={() => handleDownload(profileId, cert.type)}>Download</Button>
                </Group>
              </Card>
            ))}
          </SimpleGrid>
        )}
      </Paper>

      <PdfPreviewModal
        opened={!!previewUrl}
        onClose={() => setPreviewUrl(null)}
        url={previewUrl ?? ''}
        title={previewTitle}
      />
    </Stack>
  );
}
