import { useRef, useState } from 'react';
import { useApiQuery } from '@ema-platform/api';
import {
  Alert,
  Badge,
  Box,
  Button,
  Card,
  FileButton,
  Group,
  Paper,
  Progress,
  SimpleGrid,
  Stack,
  Text,
  TextInput,
  ThemeIcon,
  Timeline,
  Title,
} from '@mantine/core';
import {
  IconAlertCircle,
  IconAlertTriangle,
  IconCalendar,
  IconCheck,
  IconCircleCheck,
  IconDownload,
  IconFileDescription,
  IconHeart,
  IconInfoCircle,
  IconTrash,
  IconUpload,
} from '@tabler/icons-react';
import { notify } from '@ema-platform/ui';

interface MedicalCert {
  id: string;
  issuedBy: string;
  issuedDate: string;
  expiryDate: string;
  status: 'Valid' | 'Expiring' | 'Expired' | 'Pending' | 'Rejected';
  restrictions: string;
  /** Days left, computed server-side so every screen agrees on the date. */
  daysRemaining?: number;
}

/** The medical card's whole state, as `/medical/my` returns it. */
interface MedicalOverview {
  current: MedicalCert | null;
  history: MedicalCert[];
  warningDays: number;
}

const STATUS_COLOR: Record<string, string> = {
  Valid: 'teal', Expiring: 'orange', Expired: 'red', Pending: 'yellow',
};

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

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

// ---------------------------------------------------------------------------
// Component
// ---------------------------------------------------------------------------
export function MedicalCertificatePage() {
  // The card's whole state comes from one call: the current certificate, the
  // ones before it, and the validity the server computed. Deriving "expiring"
  // in the browser would let a wrong client clock disagree with the gate that
  // blocks an application.
  const { data: medical } = useApiQuery<MedicalOverview>({
    url: '/medical/my',
    method: 'GET',
  });
  const current = medical?.current ?? null;
  const history = medical?.history ?? [];
  const [uploadedFile, setUploadedFile] = useState<File | null>(null);
  const [doctorName, setDoctorName] = useState('');
  const [issuedDate, setIssuedDate] = useState('');
  const [expiryDate, setExpiryDate] = useState('');
  const [submitting, setSubmitting] = useState(false);
  const resetRef = useRef<() => void>(null);

  // Server's count where it gave one: it is the same figure the eligibility
  // gate uses, and a browser clock that is wrong or in another timezone would
  // otherwise show a different number than the officer sees.
  const days = current
    ? (current.daysRemaining ?? daysUntil(current.expiryDate))
    : 0;
  const progressVal = current
    ? Math.max(0, Math.min(100, (days / 730) * 100))
    : 0;

  const handleSubmit = async () => {
    if (!uploadedFile || !issuedDate || !expiryDate) {
      notify.error('Please fill all fields and upload the certificate file.');
      return;
    }
    setSubmitting(true);
    await new Promise((r) => setTimeout(r, 1200));
    setSubmitting(false);
    notify.success('Medical certificate submitted for verification. EMA will review within 2 working days.');
    setUploadedFile(null);
    setDoctorName('');
    setIssuedDate('');
    setExpiryDate('');
    resetRef.current?.();
  };

  return (
    <Stack gap="md">
      {/* Header */}
      <div>
        <Title order={3}>Medical Certificate</Title>
        <Text fz="sm" c="dimmed">
          STCW requires a valid medical certificate for all seafarers. Valid for 2 years (1 year if under 18).
        </Text>
      </div>

      {/* Validity alert */}
      {current && days <= 90 && days > 0 && (
        <Alert variant="light" color="orange" icon={<IconAlertTriangle size={17} />}>
          Your medical certificate expires in <strong>{days} days</strong> ({formatDate(current.expiryDate)}).
          Please visit an EMA-approved medical centre and upload your renewed certificate below.
        </Alert>
      )}
      {current && days <= 0 && (
        <Alert variant="light" color="red" icon={<IconAlertCircle size={17} />}>
          Your medical certificate <strong>has expired</strong>. You cannot join a vessel until a valid certificate is uploaded and verified.
        </Alert>
      )}
      {!current && (
        <Alert variant="light" color="blue" icon={<IconInfoCircle size={17} />}>
          No medical certificate on record. Upload your certificate below to complete your profile and apply for a Seaman Book.
        </Alert>
      )}

      <SimpleGrid cols={{ base: 1, sm: 2 }} spacing="md">
        {/* Current certificate */}
        <Paper withBorder radius="lg" p="lg">
          <Group mb="md" gap="xs">
            <ThemeIcon variant="light" color="red" size={36} radius="md">
              <IconHeart size={18} />
            </ThemeIcon>
            <Text fw={700}>Current Certificate</Text>
          </Group>

          {current ? (
            <Stack gap="sm">
              <Group justify="space-between">
                <Text fz="xs" c="dimmed" tt="uppercase" fw={600}>Status</Text>
                <Badge color={STATUS_COLOR[current.status]} variant="light">{current.status}</Badge>
              </Group>
              <Group justify="space-between">
                <Text fz="xs" c="dimmed" tt="uppercase" fw={600}>Certificate ID</Text>
                <Text fz="sm">{current.id}</Text>
              </Group>
              <Group justify="space-between">
                <Text fz="xs" c="dimmed" tt="uppercase" fw={600}>Issued By</Text>
                <Text fz="sm" ta="right" maw={200}>{current.issuedBy}</Text>
              </Group>
              <Group justify="space-between">
                <Text fz="xs" c="dimmed" tt="uppercase" fw={600}>Issue Date</Text>
                <Text fz="sm">{formatDate(current.issuedDate)}</Text>
              </Group>
              <Group justify="space-between">
                <Text fz="xs" c="dimmed" tt="uppercase" fw={600}>Expiry Date</Text>
                <Text fz="sm" fw={700} c={days <= 90 ? 'orange' : days <= 0 ? 'red' : undefined}>
                  {formatDate(current.expiryDate)}
                </Text>
              </Group>
              <Group justify="space-between">
                <Text fz="xs" c="dimmed" tt="uppercase" fw={600}>Restrictions</Text>
                <Text fz="sm">{current.restrictions}</Text>
              </Group>

              {/* Validity bar */}
              <Box mt="xs">
                <Group justify="space-between" mb={4}>
                  <Text fz="xs" c="dimmed">Validity remaining</Text>
                  <Text fz="xs" fw={600} c={days <= 90 ? 'orange' : 'teal'}>{Math.max(0, days)} days</Text>
                </Group>
                <Progress
                  value={progressVal}
                  color={days <= 30 ? 'red' : days <= 90 ? 'orange' : 'teal'}
                  radius="xl"
                  size="sm"
                />
              </Box>

              <Button
                size="xs"
                variant="light"
                leftSection={<IconDownload size={13} />}
                mt="xs"
              >
                Download Certificate
              </Button>
            </Stack>
          ) : (
            <Box ta="center" py="xl">
              <ThemeIcon variant="light" color="gray" size={48} radius="xl" mx="auto" mb="sm">
                <IconFileDescription size={22} />
              </ThemeIcon>
              <Text fz="sm" c="dimmed">No certificate on record</Text>
            </Box>
          )}
        </Paper>

        {/* Upload new certificate */}
        <Paper withBorder radius="lg" p="lg">
          <Group mb="md" gap="xs">
            <ThemeIcon variant="light" color="blue" size={36} radius="md">
              <IconUpload size={18} />
            </ThemeIcon>
            <Text fw={700}>{current ? 'Upload Renewal' : 'Upload Certificate'}</Text>
          </Group>

          <Stack gap="sm">
            <TextInput
              label="Issuing Doctor / Medical Centre"
              placeholder="e.g. Dr. Alemu Bekele — EMA Medical Centre"
              value={doctorName}
              onChange={(e) => setDoctorName(e.currentTarget.value)}
              size="sm"
            />
            <SimpleGrid cols={2} spacing="sm">
              <TextInput
                label="Issue Date"
                type="date"
                value={issuedDate}
                onChange={(e) => setIssuedDate(e.currentTarget.value)}
                size="sm"
              />
              <TextInput
                label="Expiry Date"
                type="date"
                value={expiryDate}
                onChange={(e) => setExpiryDate(e.currentTarget.value)}
                size="sm"
              />
            </SimpleGrid>

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

            <Alert variant="light" color="blue" icon={<IconInfoCircle size={15} />} p="xs">
              <Text fz="xs">
                Your certificate will be reviewed by an EMA Medical Officer within <strong>2 working days</strong>.
                Notifications will be sent by email and SMS.
              </Text>
            </Alert>

            <Button
              leftSection={<IconCheck size={15} />}
              onClick={handleSubmit}
              loading={submitting}
              disabled={!uploadedFile || !issuedDate || !expiryDate}
            >
              Submit for Verification
            </Button>
          </Stack>
        </Paper>
      </SimpleGrid>

      {/* Notification schedule */}
      <Paper withBorder radius="lg" p="lg">
        <Group mb="md" gap="xs">
          <ThemeIcon variant="light" color="blue" size={36} radius="md">
            <IconCalendar size={18} />
          </ThemeIcon>
          <Text fw={700}>Expiry Notification Schedule</Text>
        </Group>
        <Timeline active={days <= 30 ? 2 : days <= 60 ? 1 : days <= 90 ? 0 : -1} bulletSize={24} lineWidth={2}>
          <Timeline.Item bullet={<IconAlertCircle size={13} />} title="90 Days Before Expiry">
            <Text fz="xs" c="dimmed">First reminder — time to book your medical examination</Text>
          </Timeline.Item>
          <Timeline.Item bullet={<IconAlertTriangle size={13} />} title="60 Days Before Expiry">
            <Text fz="xs" c="dimmed">Second reminder — urgent renewal required</Text>
          </Timeline.Item>
          <Timeline.Item bullet={<IconAlertCircle size={13} />} title="30 Days Before Expiry">
            <Text fz="xs" c="dimmed">Final reminder — certificate expires very soon</Text>
          </Timeline.Item>
        </Timeline>
      </Paper>

      {/* History */}
      {history.length > 0 && (
        <Paper withBorder radius="lg" p="lg">
          <Text fw={700} mb="md">Certificate History</Text>
          <Stack gap="xs">
            {history.map((cert) => (
              <Card key={cert.id} withBorder radius="sm" p="sm">
                <Group justify="space-between" wrap="wrap" gap="xs">
                  <Group gap="sm">
                    <ThemeIcon variant="light" color="gray" size={32} radius="md">
                      <IconFileDescription size={16} />
                    </ThemeIcon>
                    <div>
                      <Text fz="sm" fw={600}>{cert.id}</Text>
                      <Text fz="xs" c="dimmed">{formatDate(cert.issuedDate)} → {formatDate(cert.expiryDate)}</Text>
                    </div>
                  </Group>
                  <Group gap="xs">
                    <Badge color={STATUS_COLOR[cert.status]} variant="light" size="sm">{cert.status}</Badge>
                    <Button size="xs" variant="subtle" leftSection={<IconDownload size={12} />}>Download</Button>
                  </Group>
                </Group>
              </Card>
            ))}
          </Stack>
        </Paper>
      )}
    </Stack>
  );
}
