import { useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import {Alert, Badge, Button, Center, Container, Divider, Group, Loader, Modal, Paper, Stack, Table, Text, Textarea} from '@mantine/core';
import { IconAlertTriangle, IconArrowLeft, IconCheck } from '@tabler/icons-react';
import {
  SEAFARER_REGISTRATION_DOCUMENTS,
  SEAFARER_REGISTRATION_FIELD_LABELS,
  SEAFARER_REGISTRATION_SECTIONS,
  SEAFARER_REGISTRATION_STATUS_TONES,
  SEAFARER_REGISTRATION_STATUS_LABELS,
  displaySeafarerAnswer,
  extractErrorMessage,
  useApproveSeafarerRegistrationMutation,
  useGetActiveDepartmentsQuery,
  useGetSeafarerRegistrationReviewQuery,
  useLocalized,
  useRejectSeafarerRegistrationMutation,
  useRequestSeafarerRegistrationChangesMutation,
} from '@ema-platform/api';
import { notify, PageHeader, StatusBadge } from '@ema-platform/ui';
import { LICENSE_PERMISSIONS, RequirePermission } from '@ema-platform/auth';
import { applicantName } from './SeafarerRegistrationQueuePage';

type Decision = 'approve' | 'reject' | 'changes';

const DECISION_COPY: Record<Decision, { title: string; label: string; color: string; required: boolean }> = {
  approve: { title: 'Approve registration', label: 'Remark (optional)', color: 'teal', required: false },
  changes: { title: 'Request corrections', label: 'What must the applicant fix?', color: 'orange', required: true },
  reject: { title: 'Reject registration', label: 'Reason (shown to the applicant)', color: 'red', required: true },
};

/** One registration: every answer, every upload, and the officer's actions. */
export function SeafarerRegistrationReviewPage() {
  const { id = '' } = useParams();
  const navigate = useNavigate();
  const localized = useLocalized();
  const { data, isLoading, error } = useGetSeafarerRegistrationReviewQuery(id, { skip: !id });
  const { data: departments } = useGetActiveDepartmentsQuery();
  const departmentOptions = departments?.map((d) => ({ value: d.code, label: localized(d.name) }));

  const [approve, { isLoading: approving }] = useApproveSeafarerRegistrationMutation();
  const [reject, { isLoading: rejecting }] = useRejectSeafarerRegistrationMutation();
  const [requestChanges, { isLoading: requesting }] = useRequestSeafarerRegistrationChangesMutation();

  const [decision, setDecision] = useState<Decision | null>(null);
  const [text, setText] = useState('');

  if (isLoading) {
    return (
      <Center h={300}>
        <Loader />
      </Center>
    );
  }
  if (error || !data) {
    return (
      <Container size="md" py="xl">
        <Alert color="red" icon={<IconAlertTriangle size={16} />}>
          {extractErrorMessage(error, 'Could not load this registration.')}
        </Alert>
      </Container>
    );
  }

  const { registration, attachments } = data;
  // Decided straight off the queue — no claim step. AWAITING_BIOMETRICS is
  // deliberately excluded: approval is blocked on a BSID that only exists once
  // the applicant has been enrolled, so the decision is not the reviewer's to
  // take yet. SUBMITTED stays decidable for files that predate the gate.
  const awaitingBiometrics = registration.status === 'AWAITING_BIOMETRICS';
  const canDecide =
    registration.status === 'UNDER_REVIEW' || registration.status === 'SUBMITTED';
  const busy = approving || rejecting || requesting;

  async function run(action: () => Promise<unknown>, done: string) {
    try {
      await action();
      notify.success(done);
      setDecision(null);
      setText('');
    } catch (err) {
      notify.error(extractErrorMessage(err, 'Could not record the decision'));
    }
  }

  function confirmDecision() {
    const remark = text.trim();
    if (decision === 'approve') {
      run(() => approve({ id, remark: remark || undefined }).unwrap(), 'Registration approved — seafarer numbered.');
    } else if (decision === 'changes') {
      run(() => requestChanges({ id, remark }).unwrap(), 'Sent back for corrections.');
    } else if (decision === 'reject') {
      run(() => reject({ id, reason: remark }).unwrap(), 'Registration rejected.');
    }
  }

  const slots = SEAFARER_REGISTRATION_DOCUMENTS.filter(
    (d) => d.required !== 'passport' || registration.passportNumber,
  );

  return (
    <Container size="lg" py="md">
      <Button variant="subtle" size="xs" leftSection={<IconArrowLeft size={14} />} onClick={() => navigate('/seafarer-registrations')} mb="xs">
        Back to queue
      </Button>
      <PageHeader
        title={applicantName(registration)}
        meta={
          <>
            <Text size="sm" c="dimmed" ff="monospace">
              {registration.registrationNumber}
            </Text>
            <StatusBadge
              tone={SEAFARER_REGISTRATION_STATUS_TONES[registration.status]}
              label={SEAFARER_REGISTRATION_STATUS_LABELS[registration.status]}
            />
            {registration.seafarerNumber && (
              <Badge size="sm" color="teal" leftSection={<IconCheck size={10} />}>
                {registration.seafarerNumber}
              </Badge>
            )}
          </>
        }
        action={
          <Group gap="xs">
          {canDecide && (
            <>
              <RequirePermission anyOf={[LICENSE_PERMISSIONS.REQUEST_ADJUSTMENT]} hideOnly>
                <Button variant="default" onClick={() => setDecision('changes')}>
                  Request corrections
                </Button>
              </RequirePermission>
              <RequirePermission anyOf={[LICENSE_PERMISSIONS.REJECT_APPLICATION]} hideOnly>
                <Button color="red" variant="light" onClick={() => setDecision('reject')}>
                  Reject
                </Button>
              </RequirePermission>
              <RequirePermission anyOf={[LICENSE_PERMISSIONS.APPROVE_APPLICATION]} hideOnly>
                <Button color="teal" onClick={() => setDecision('approve')}>
                  Approve
                </Button>
              </RequirePermission>
            </>
          )}
          </Group>
        }
      />

      {awaitingBiometrics && (
        <Alert
          color="blue"
          icon={<IconAlertTriangle size={16} />}
          title="Awaiting biometric enrolment"
          mb="md"
        >
          This registration cannot be decided yet. The applicant has to be
          enrolled at a counter and issued a BSID first — the registration moves
          to Under Review automatically once that happens.
        </Alert>
      )}
      {registration.status === 'RESUBMIT_REQUIRED' && (
        <Alert color="orange" icon={<IconAlertTriangle size={16} />} title="Awaiting the applicant's corrections" mb="md">
          {registration.reviewRemark}
        </Alert>
      )}
      {registration.status === 'REJECTED' && (
        <Alert color="red" icon={<IconAlertTriangle size={16} />} title="Rejected" mb="md">
          {registration.rejectionReason}
        </Alert>
      )}

      <Paper withBorder p="lg" radius="md">
        <Stack gap="md">
          {SEAFARER_REGISTRATION_SECTIONS.map((section) => (
            <div key={section.key}>
              <Text fw={600} size="sm" mb={4}>
                {section.title}
              </Text>
              <Table variant="vertical">
                <Table.Tbody>
                  {section.fields
                    .filter((f) => f !== 'passportExpiry' || registration.passportNumber)
                    .map((field) => (
                      <Table.Tr key={field}>
                        <Table.Td w="40%">
                          <Text size="xs" c="dimmed">
                            {SEAFARER_REGISTRATION_FIELD_LABELS[field]}
                          </Text>
                        </Table.Td>
                        <Table.Td>
                          <Text size="sm">
                            {displaySeafarerAnswer(field, registration[field], departmentOptions)}
                          </Text>
                        </Table.Td>
                      </Table.Tr>
                    ))}
                </Table.Tbody>
              </Table>
            </div>
          ))}

          <Divider />
          <Text fw={600} size="sm" mb={4}>
            Documents
          </Text>
          <Table variant="vertical">
            <Table.Tbody>
              {slots.map((slot) => {
                const file = attachments.find((a) => a.documentKey === slot.key)?.files?.[0];
                const required = slot.required === 'passport' ? true : slot.required;
                return (
                  <Table.Tr key={slot.key}>
                    <Table.Td w="40%">
                      <Text size="xs" c="dimmed">
                        {slot.name}
                      </Text>
                    </Table.Td>
                    <Table.Td>
                      {file ? (
                        <Group gap="xs">
                          <Text size="sm">{file.originalName}</Text>
                          {file.url && (
                            <Button size="compact-xs" variant="light" component="a" href={file.url} target="_blank" rel="noopener noreferrer">
                              View
                            </Button>
                          )}
                        </Group>
                      ) : (
                        <Text size="sm" c={required ? 'red' : 'dimmed'}>
                          {required ? 'Missing' : '—'}
                        </Text>
                      )}
                    </Table.Td>
                  </Table.Tr>
                );
              })}
            </Table.Tbody>
          </Table>
        </Stack>
      </Paper>

      <Modal
        opened={decision !== null}
        onClose={() => setDecision(null)}
        title={decision ? DECISION_COPY[decision].title : ''}
        centered
      >
        {decision && (
          <Stack>
            <Textarea
              label={DECISION_COPY[decision].label}
              required={DECISION_COPY[decision].required}
              minRows={3}
              value={text}
              onChange={(e) => setText(e.currentTarget.value)}
              data-autofocus
            />
            <Group justify="flex-end">
              <Button variant="default" onClick={() => setDecision(null)}>
                Cancel
              </Button>
              <Button
                color={DECISION_COPY[decision].color}
                loading={busy}
                disabled={DECISION_COPY[decision].required && text.trim().length < 3}
                onClick={confirmDecision}
              >
                Confirm
              </Button>
            </Group>
          </Stack>
        )}
      </Modal>
    </Container>
  );
}

export default SeafarerRegistrationReviewPage;
