import { type StatusTone, STATUS_TONE_COLOR } from '@ema-platform/shared';
import { useRef, useState } from 'react';
import { useApiQuery } from '@ema-platform/api';
import {
  Alert,
  Badge,
  Box,
  Button,
  Card,
  FileButton,
  Group,
  List,
  Modal,
  Paper,
  Stack,
  Text,
  TextInput,
  ThemeIcon,
  Title,
} from '@mantine/core';
import {
  IconAlertTriangle,
  IconBook2,
  IconCalendar,
  IconCheck,
  IconCircleCheck,
  IconDownload,
  IconInfoCircle,
  IconRefresh,
  IconShieldCheck,
  IconTrash,
  IconUpload,
} from '@tabler/icons-react';
import { StatusBadge, notify } from '@ema-platform/ui';
import { useTranslation } from 'react-i18next';

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------
interface BSTRecord {
  issuer: string;
  issueDate: string;
  expiryDate: string;
  certNumber: string;
  fileName: string;
  status: 'Valid' | 'Expiring' | 'Expired' | 'Pending Verification';
}

const STATUS_TONE: Record<string, StatusTone> = {
  Valid: 'success',
  Expiring: 'pending',
  Expired: 'danger',
  'Pending Verification': 'warning',
};

/** Progress across the five STCW A-VI/1 modules, as `/bst/my` reports it. */
interface BstProgress {
  modules: { key: string; label: string; licenseTypeKey: string; done: boolean }[];
  completed: number;
  total: number;
  complete: boolean;
}

// `short` doubles as the key the API reports each module under, so the two
// stay matched without a second lookup table between them.
const BST_COMPONENTS = [
  { label: 'Personal Survival Techniques', short: 'PST', course: 'IMO 1.19' },
  { label: 'Fire Prevention & Fire Fighting', short: 'FPFF', course: 'IMO 1.20' },
  { label: 'Elementary First Aid', short: 'EFA', course: 'IMO 1.13' },
  { label: 'Personal Safety & Social Responsibility', short: 'PSSR', course: 'IMO 1.21' },
  { label: 'Security Awareness', short: 'SSA', course: 'STCW A-VI/6' },
];

function formatDate(dateStr: string) {
  return new Date(dateStr).toLocaleDateString('en-GB', {
    day: '2-digit',
    month: 'short',
    year: 'numeric',
  });
}

function daysUntil(dateStr: string) {
  return Math.ceil((new Date(dateStr).getTime() - Date.now()) / (1000 * 60 * 60 * 24));
}

// ---------------------------------------------------------------------------
// Upload modal
// ---------------------------------------------------------------------------
function UploadModal({
  opened,
  onClose,
  onUploaded,
}: {
  opened: boolean;
  onClose: () => void;
  onUploaded: (record: BSTRecord) => void;
}) {
  const [file, setFile] = useState<File | null>(null);
  const [issuer, setIssuer] = useState('');
  const [certNumber, setCertNumber] = useState('');
  const [issueDate, setIssueDate] = useState('');
  const [expiryDate, setExpiryDate] = useState('');
  const [submitting, setSubmitting] = useState(false);
  const resetRef = useRef<() => void>(null);

  const reset = () => {
    setFile(null);
    setIssuer('');
    setCertNumber('');
    setIssueDate('');
    setExpiryDate('');
    resetRef.current?.();
  };

  const handleSubmit = async () => {
    if (!file || !issuer || !certNumber || !issueDate || !expiryDate) {
      notify.error('Please fill all required fields and upload the certificate file.');
      return;
    }
    setSubmitting(true);
    await new Promise((r) => setTimeout(r, 1000));
    setSubmitting(false);
    onUploaded({
      issuer,
      issueDate,
      expiryDate,
      certNumber,
      fileName: file.name,
      status: 'Pending Verification',
    });
    notify.success('Basic Safety Training certificate submitted for verification.');
    reset();
    onClose();
  };

  return (
    <Modal
      opened={opened}
      onClose={() => {
        reset();
        onClose();
      }}
      title="Upload Basic Safety Training Certificate"
      size="md"
      centered
    >
      <Stack gap="sm">
        <Alert variant="light" color="blue" icon={<IconInfoCircle size={15} />} p="xs">
          <Text fz="xs">
            Upload your combined BST certificate issued by an EMA-approved training institution.
            The certificate must cover all 5 components (PST, FPFF, EFA, PSSR, SHPT).
          </Text>
        </Alert>

        <TextInput
          label="Issuing Institution"
          placeholder="e.g. Bahirdar Maritime School"
          required
          value={issuer}
          onChange={(e) => setIssuer(e.currentTarget.value)}
          size="sm"
        />
        <TextInput
          label="Certificate Number"
          placeholder="e.g. BST-2024-BMS-001"
          required
          value={certNumber}
          onChange={(e) => setCertNumber(e.currentTarget.value)}
          size="sm"
        />
        <Group grow>
          <TextInput
            label="Issue Date"
            type="date"
            required
            value={issueDate}
            onChange={(e) => setIssueDate(e.currentTarget.value)}
            size="sm"
          />
          <TextInput
            label="Expiry Date"
            type="date"
            required
            value={expiryDate}
            onChange={(e) => setExpiryDate(e.currentTarget.value)}
            size="sm"
          />
        </Group>

        <div>
          <Text fz="sm" fw={500} mb={4}>
            Certificate File <Text span c="red">*</Text>
          </Text>
          {file ? (
            <Card withBorder radius="sm" p="xs">
              <Group gap="xs">
                <IconCircleCheck size={14} color="var(--mantine-color-teal-6)" />
                <Text fz="xs" flex={1} truncate>
                  {file.name}
                </Text>
                <Button
                  size="xs"
                  variant="subtle"
                  color="red"
                  onClick={() => {
                    setFile(null);
                    resetRef.current?.();
                  }}
                >
                  <IconTrash size={12} />
                </Button>
              </Group>
            </Card>
          ) : (
            <FileButton
              resetRef={resetRef}
              onChange={setFile}
              accept="application/pdf,image/jpeg,image/png"
            >
              {(props) => (
                <Button
                  size="sm"
                  variant="default"
                  leftSection={<IconUpload size={13} />}
                  fullWidth
                  {...props}
                >
                  Choose File (PDF / JPG / PNG)
                </Button>
              )}
            </FileButton>
          )}
        </div>

        <Group justify="flex-end" mt="xs">
          <Button
            variant="default"
            onClick={() => {
              reset();
              onClose();
            }}
          >
            Cancel
          </Button>
          <Button
            onClick={handleSubmit}
            loading={submitting}
            leftSection={<IconCheck size={14} />}
          >
            Submit
          </Button>
        </Group>
      </Stack>
    </Modal>
  );
}

// ---------------------------------------------------------------------------
// Main page
// ---------------------------------------------------------------------------
export function BasicSafetyTrainingPage() {
  const [record, setRecord] = useState<BSTRecord | null>(null);
  const [modalOpen, setModalOpen] = useState(false);

  // Which of the five modules the seafarer actually holds. The certificate
  // itself is the evidence, so this is read from the issued licences rather
  // than tracked separately — two places to record it would disagree.
  const { data: bst, isLoading: bstLoading } = useApiQuery<BstProgress>({
    url: '/bst/my',
    method: 'GET',
  });
  const doneByKey = new Map(
    (bst?.modules ?? []).map((m) => [m.key, m.done]),
  );

  const days = record?.expiryDate ? daysUntil(record.expiryDate) : null;
  const isExpiringSoon = days !== null && days <= 180 && days > 0;
  const isExpired = days !== null && days <= 0;

  const { t } = useTranslation();

  return (
    <Stack gap="md">
      {/* Header */}
      <Group justify="space-between" align="flex-start" wrap="wrap" gap="sm">
        <div>
          <Title order={3}>Basic Safety Training Certificate</Title>
          <Text fz="sm" c="dimmed">
            STCW Chapter VI/1 — mandatory for all seafarers before joining a vessel.
          </Text>
        </div>
        {record && (
          <StatusBadge
            tone={STATUS_TONE[record.status]}
            label={record.status}
            size="lg"
            variant="light"
            leftSection={<IconShieldCheck size={14} />}
          />
        )}
      </Group>

      {/* Expiry alert */}
      {isExpired && (
        <Alert variant="light" color="red" icon={<IconAlertTriangle size={15} />}>
          <Text fz="sm">
            Your BST certificate has <strong>expired</strong>. Upload a renewed certificate to remain eligible.
          </Text>
        </Alert>
      )}
      {isExpiringSoon && (
        <Alert variant="light" color="orange" icon={<IconAlertTriangle size={15} />}>
          <Text fz="sm">
            Your BST certificate expires in <strong>{days} days</strong>. Renew before it lapses.
          </Text>
        </Alert>
      )}

      {/* Certificate card */}
      {record ? (
        <Paper withBorder radius="lg" p="lg">
          <Group justify="space-between" mb="md" wrap="wrap" gap="sm">
            <Group gap="sm">
              <ThemeIcon size={48} radius="md" color={STATUS_TONE_COLOR[STATUS_TONE[record.status]]} variant="light">
                <IconShieldCheck size={24} />
              </ThemeIcon>
              <div>
                <Text fw={700}>Basic Safety Training (BST)</Text>
                <Text fz="xs" c="dimmed">Combined certificate — all 5 STCW components</Text>
              </div>
            </Group>
            <StatusBadge tone={STATUS_TONE[record.status]} label={record.status} variant="light" />
          </Group>

          <Stack gap="xs" mb="md">
            <Group justify="space-between">
              <Text fz="sm" c="dimmed">Certificate Number</Text>
              <Text fz="sm" fw={600}>{record.certNumber}</Text>
            </Group>
            <Group justify="space-between">
              <Text fz="sm" c="dimmed">Issuing Institution</Text>
              <Text fz="sm">{record.issuer}</Text>
            </Group>
            <Group justify="space-between">
              <Text fz="sm" c="dimmed">Issue Date</Text>
              <Text fz="sm">{formatDate(record.issueDate)}</Text>
            </Group>
            <Group justify="space-between">
              <Text fz="sm" c="dimmed">Expiry Date</Text>
              <Text
                fz="sm"
                fw={600}
                c={isExpired ? 'red' : isExpiringSoon ? 'orange' : undefined}
              >
                {formatDate(record.expiryDate)}
                {days !== null && days > 0 && (
                  <Text span fz="xs" c="dimmed" ml={6}>({days} days remaining)</Text>
                )}
              </Text>
            </Group>
            <Group justify="space-between">
              <Text fz="sm" c="dimmed">File</Text>
              <Text fz="sm">{record.fileName}</Text>
            </Group>
          </Stack>

          <Group gap="xs">
            <Button size="sm" variant="light" leftSection={<IconDownload size={14} />}>
              Download
            </Button>
            <Button
              size="sm"
              variant="subtle"
              color="orange"
              leftSection={<IconRefresh size={14} />}
              onClick={() => setModalOpen(true)}
            >
              Replace / Renew
            </Button>
          </Group>
        </Paper>
      ) : (
        <Paper withBorder radius="lg" p="xl" style={{ borderStyle: 'dashed' }}>
          <Stack align="center" gap="md">
            <ThemeIcon size={64} radius="xl" color="gray" variant="light">
              <IconShieldCheck size={32} />
            </ThemeIcon>
            <div style={{ textAlign: 'center' }}>
              <Text fw={700} fz="lg" mb={4}>No BST Certificate Uploaded</Text>
              <Text fz="sm" c="dimmed" maw={420}>
                You must upload a valid Basic Safety Training certificate issued by an
                EMA-approved institution before applying for a Seaman Book.
              </Text>
            </div>
            <Button
              leftSection={<IconUpload size={16} />}
              onClick={() => setModalOpen(true)}
              size="md"
            >
              Upload BST Certificate
            </Button>
          </Stack>
        </Paper>
      )}

      {/* Components covered */}
      <Paper withBorder radius="lg" p="lg">
        <Group gap="xs" mb="md">
          <IconBook2 size={18} color="var(--mantine-color-blue-6)" />
          <Text fw={700} fz="sm">Certificate Components (STCW VI/1)</Text>
        </Group>
        <Text fz="xs" c="dimmed" mb="sm">
          A combined BST certificate from an EMA-approved institution covers all five components:
        </Text>
        <List
          spacing="xs"
          size="sm"
          icon={
            <ThemeIcon size={18} radius="xl" color="teal" variant="light">
              <IconCheck size={11} />
            </ThemeIcon>
          }
        >
          {BST_COMPONENTS.map((c) => {
            const done = doneByKey.get(c.short);
            return (
              <List.Item
                key={c.short}
                icon={
                  <ThemeIcon
                    size={18}
                    radius="xl"
                    color={done ? 'teal' : 'gray'}
                    variant={done ? 'light' : 'outline'}
                  >
                    <IconCheck size={11} />
                  </ThemeIcon>
                }
              >
                <Group gap="xs" display="inline-flex">
                  <Text fz="sm" fw={600}>{c.short}</Text>
                  <Text fz="sm" c="dimmed">— {c.label}</Text>
                  <Badge size="xs" variant="outline" color="gray">{c.course}</Badge>
                  {/* Only stated once known: an absent badge reads as "not
                      loaded", where a "Not held" badge would read as fact. */}
                  {!bstLoading && (
                    <Badge size="xs" variant="light" color={done ? 'teal' : 'gray'}>
                      {done ? 'Held' : 'Not held'}
                    </Badge>
                  )}
                </Group>
              </List.Item>
            );
          })}
        </List>
      </Paper>

      {/* Info */}
      <Paper withBorder radius="lg" p="lg" bg="var(--mantine-color-blue-light)">
        <Group gap="xs" mb="xs">
          <IconCalendar size={16} color="var(--mantine-color-blue-6)" />
          <Text fw={700} fz="sm">Validity & Renewal</Text>
        </Group>
        <Box>
          <Text fz="xs" c="dimmed" lh={1.6}>
            BST certificates are typically valid for <strong>5 years</strong>. PST and FPFF components
            require evidence of maintained competence at the 5-year point (STCW Reg. VI/1).
            EFA and PSSR do not have a mandatory 5-year revalidation under STCW but your
            institution's combined certificate carries a unified expiry date.
            Certificates must be from <strong>EMA-approved training institutions</strong>.
          </Text>
        </Box>
      </Paper>

      <UploadModal
        opened={modalOpen}
        onClose={() => setModalOpen(false)}
        onUploaded={(rec) => setRecord(rec)}
      />
    </Stack>
  );
}
