import { useNavigate } from 'react-router-dom';
import { useApiQuery } from '@ema-platform/api';
import {
  Alert,
  Badge,
  Box,
  Button,
  Card,
  Divider,
  Group,
  Paper,
  SimpleGrid,
  Stack,
  Stepper,
  Text,
  ThemeIcon,
  Title,
} from '@mantine/core';
import {
  IconAlertCircle,
  IconBook2,
  IconCheck,
  IconCircleCheck,
  IconClock,
  IconFileDescription,
  IconHeart,
  IconInfoCircle,
  IconPrinter,
  IconShield,
  IconX,
} from '@tabler/icons-react';

/** The seaman-book page's whole state, as `/seaman-book/my` returns it. */
interface SeamanBookOverview {
  application: {
    id: string;
    applicationId: string;
    status: string;
    submittedAt: string;
  } | null;
  book: {
    id: string;
    issuedDate: string;
    expiryDate: string;
    status: string;
  } | null;
  eligibility: {
    hasProfile: boolean;
    hasSeafarerNumber: boolean;
    hasMedical: boolean;
    medicalExpiry: string | null;
    bstComplete: boolean;
    bstModules: { key: string; label: string; done: boolean }[];
  };
  eligible: boolean;
}

/**
 * The stages an application passes through, for the progress stepper.
 *
 * Derived from the application's status rather than stored as a timeline:
 * the status is what the workflow actually moves, so a second record of the
 * same journey would only drift out of step with it.
 */
const STAGES: { label: string; statuses: string[] }[] = [
  { label: 'Submitted', statuses: ['SUBMITTED', 'UNDER_REVIEW', 'UNDER_EVALUATION'] },
  { label: 'Under Review', statuses: ['UNDER_REVIEW', 'UNDER_EVALUATION'] },
  { label: 'Inspection', statuses: ['INSPECTION_PENDING', 'INSPECTION_COMPLETED'] },
  { label: 'Approved', statuses: ['APPROVED', 'PAYMENT_PENDING', 'PAID', 'PAYMENT_CONFIRMED'] },
  { label: 'Issued', statuses: ['CERTIFICATE_ISSUED', 'COMPLETED'] },
];

/** How far along the stepper a status sits; -1 for a draft. */
function stageIndexFor(status: string | undefined): number {
  if (!status || status === 'DRAFT') return -1;
  let reached = -1;
  STAGES.forEach((stage, i) => {
    if (stage.statuses.includes(status)) reached = i;
  });
  // A status past the last named stage (e.g. REJECTED) still shows the
  // journey taken rather than collapsing the stepper to nothing.
  return reached;
}

// Keyed by the workflow's own status values, not display strings: the badge
// reads whatever the API reports, and an unmapped status falls back to grey
// rather than vanishing.
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',
  APPROVED: 'teal',
  REJECTED: 'red',
  ON_HOLD: 'orange',
  PAYMENT_PENDING: 'orange',
  PAID: 'blue',
  PAYMENT_CONFIRMED: 'blue',
  CERTIFICATE_ISSUED: 'teal',
  COMPLETED: 'teal',
};

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

function EligibilityItem({ label, ok }: { label: string; ok: boolean }) {
  return (
    <Group gap="xs">
      <ThemeIcon size={22} radius="xl" variant={ok ? 'filled' : 'light'} color={ok ? 'teal' : 'red'}>
        {ok ? <IconCheck size={13} /> : <IconX size={13} />}
      </ThemeIcon>
      <Text fz="sm" c={ok ? undefined : 'dimmed'}>{label}</Text>
    </Group>
  );
}

// ---------------------------------------------------------------------------
// Component
// ---------------------------------------------------------------------------
export function SeamanBookPage() {
  const navigate = useNavigate();

  const { data, isLoading } = useApiQuery<SeamanBookOverview>({
    url: '/seaman-book/my',
    method: 'GET',
  });

  const application = data?.application ?? null;
  const eligibility = data?.eligibility;
  const bstItems = eligibility?.bstModules ?? [];
  const bstDone = bstItems.filter((b) => b.done).length;

  // The server decides: the same checklist gates the submission, so a screen
  // that judged eligibility for itself could offer a button the API refuses.
  const isEligible = data?.eligible ?? false;
  const submitted = Boolean(application);

  const activeStep = stageIndexFor(application?.status);

  return (
    <Stack gap="md">
      {/* Header */}
      <div>
        <Title order={3}>My Application — Seaman Book & BTC</Title>
        <Text fz="sm" c="dimmed">
          A Seaman Book is your official maritime identity document. It records your sea service and must be
          held before joining any vessel.
        </Text>
      </div>

      {/* Active application status */}
      {application && (
        <Paper withBorder radius="lg" p="lg">
          <Group justify="space-between" mb="md" wrap="wrap" gap="sm">
            <Group gap="xs">
              <ThemeIcon variant="light" color="blue" size={36} radius="md">
                <IconBook2 size={18} />
              </ThemeIcon>
              <div>
                <Text fw={700}>Application {application.id}</Text>
                <Text fz="xs" c="dimmed">
                  Submitted {formatDate(application.submittedAt)}
                </Text>
              </div>
            </Group>
            <Badge
              color={STATUS_COLOR[application.status] ?? 'gray'}
              variant="light"
              size="lg"
            >
              {application.status.replaceAll('_', ' ')}
            </Badge>
          </Group>

          {/* Progress stepper */}
          <Stepper active={activeStep} size="sm" color="teal">
            {STAGES.map((stage, i) => (
              <Stepper.Step
                key={stage.label}
                label={stage.label}
                description={i <= activeStep ? 'Done' : 'Pending'}
                icon={
                  i <= activeStep ? (
                    <IconCircleCheck size={16} />
                  ) : (
                    <IconClock size={16} />
                  )
                }
              />
            ))}
          </Stepper>

          {data?.book && (
            <Alert variant="light" color="teal" icon={<IconPrinter size={17} />} mt="md">
              Your Seaman Book <strong>{data.book.id}</strong> has been issued.
              Please visit the EMA office to collect it, bringing your National ID.
            </Alert>
          )}
        </Paper>
      )}

      {/* No active application — eligibility + apply */}
      {!submitted && (
        <SimpleGrid cols={{ base: 1, sm: 2 }} spacing="md">
          {/* Eligibility checklist */}
          <Paper withBorder radius="lg" p="lg">
            <Group mb="md" gap="xs">
              <ThemeIcon variant="light" color={isEligible ? 'teal' : 'orange'} size={36} radius="md">
                <IconShield size={18} />
              </ThemeIcon>
              <Text fw={700}>Eligibility Requirements</Text>
            </Group>

            <Stack gap="sm">
              <EligibilityItem
                label="Profile completed (name, DOB, nationality)"
                ok={Boolean(eligibility?.hasProfile)}
              />
              <EligibilityItem
                label="Registered seafarer number issued"
                ok={Boolean(eligibility?.hasSeafarerNumber)}
              />
              <EligibilityItem
                label={
                  eligibility?.medicalExpiry
                    ? `Valid medical certificate (expires ${formatDate(eligibility.medicalExpiry)})`
                    : 'Valid medical certificate uploaded'
                }
                ok={Boolean(eligibility?.hasMedical)}
              />

              <Divider
                label={`Basic Safety Training (all ${bstItems.length || 5} required)`}
                labelPosition="left"
                my={4}
              />
              {bstItems.map((item) => (
                <EligibilityItem key={item.key} label={item.label} ok={item.done} />
              ))}

              {!isLoading && !isEligible && (
                <Alert variant="light" color="orange" icon={<IconAlertCircle size={15} />} mt="xs" p="sm">
                  <Text fz="xs">
                    Complete all requirements above before applying.
                    {bstItems.length > bstDone
                      ? ` Missing BST: ${bstItems.length - bstDone} certificate(s).`
                      : ''}
                  </Text>
                </Alert>
              )}

              {isEligible && (
                <Alert variant="light" color="teal" icon={<IconCircleCheck size={15} />} mt="xs" p="sm">
                  <Text fz="xs">You meet all requirements. You may proceed with your application.</Text>
                </Alert>
              )}
            </Stack>
          </Paper>

          {/* Application form */}
          <Paper withBorder radius="lg" p="lg">
            <Group mb="md" gap="xs">
              <ThemeIcon variant="light" color="blue" size={36} radius="md">
                <IconFileDescription size={18} />
              </ThemeIcon>
              <Text fw={700}>New Application</Text>
            </Group>

            <Stack gap="sm">
              <Text fz="sm" c="dimmed" lh={1.6}>
                Upon submitting your application, EMA Registration Officers will verify your profile,
                documents, medical certificate, and Basic Safety Training certificates. You will be
                notified at each stage by email and SMS.
              </Text>

              <Divider />

              <Text fw={600} fz="sm">What will be verified:</Text>
              <Stack gap={6}>
                {[
                  'Full seafarer profile',
                  'National ID / Fayda authenticity',
                  'Medical certificate validity',
                  'All 5 Basic Safety Training certificates',
                  'Passport size photo',
                ].map((item) => (
                  <Group key={item} gap="xs">
                    <IconCircleCheck size={15} color="var(--mantine-color-teal-6)" />
                    <Text fz="sm">{item}</Text>
                  </Group>
                ))}
              </Stack>

              <Divider />

              <SimpleGrid cols={2} spacing="xs">
                <Card withBorder radius="sm" p="sm">
                  <Group gap="xs">
                    <IconClock size={15} color="var(--mantine-color-blue-6)" />
                    <div>
                      <Text fz="xs" c="dimmed">Processing time</Text>
                      <Text fz="sm" fw={600}>5–7 working days</Text>
                    </div>
                  </Group>
                </Card>
                <Card withBorder radius="sm" p="sm">
                  <Group gap="xs">
                    <IconHeart size={15} color="var(--mantine-color-red-6)" />
                    <div>
                      <Text fz="xs" c="dimmed">Medical validity</Text>
                      <Text fz="sm" fw={600}>2 years (STCW)</Text>
                    </div>
                  </Group>
                </Card>
              </SimpleGrid>

              <Alert variant="light" color="blue" icon={<IconInfoCircle size={15} />} p="xs">
                <Text fz="xs">
                  Application fee will be communicated during the review process. Payment can be made online or at the EMA office.
                </Text>
              </Alert>

              <Button
                leftSection={<IconBook2 size={16} />}
                onClick={() => navigate('/seaman-book/apply')}
                disabled={!isEligible}
                size="md"
              >
                Start Application
              </Button>

              {!isEligible && (
                <Text fz="xs" c="dimmed" ta="center">
                  Complete all eligibility requirements to enable this button.
                </Text>
              )}
            </Stack>
          </Paper>
        </SimpleGrid>
      )}

      {/* Info box */}
      <Paper withBorder radius="lg" p="lg" bg="var(--mantine-color-blue-light)">
        <Group gap="xs" mb="sm">
          <IconInfoCircle size={18} color="var(--mantine-color-blue-6)" />
          <Text fw={700} fz="sm">About the Seaman Book</Text>
        </Group>
        <SimpleGrid cols={{ base: 1, sm: 3 }} spacing="md">
          {[
            { icon: IconBook2, title: 'Official Identity', desc: 'Internationally recognized maritime identity document required before joining any vessel.' },
            { icon: IconFileDescription, title: 'Service Record', desc: 'Records all your sea service, vessel assignments, and employment history.' },
            { icon: IconShield, title: 'STCW Compliance', desc: 'Required under STCW for all seafarers. Must be renewed and kept valid throughout your career.' },
          ].map(({ icon: Icon, title, desc }) => (
            <Box key={title}>
              <Group gap="xs" mb={4}>
                <Icon size={16} color="var(--mantine-color-blue-6)" />
                <Text fz="sm" fw={600}>{title}</Text>
              </Group>
              <Text fz="xs" c="dimmed" lh={1.5}>{desc}</Text>
            </Box>
          ))}
        </SimpleGrid>
      </Paper>
    </Stack>
  );
}
