import { useState } from 'react';
import {
  Badge,
  Button,
  Card,
  Center,
  Container,
  Group,
  Loader,
  Modal,
  Select,
  Stack,
  Table,
  Text,
  TextInput,
  Textarea,
  Title,
  Tooltip,
} from '@mantine/core';
import { IconSearch, IconShieldCog } from '@tabler/icons-react';
import { notify } from '@ema-platform/ui';
import { useDateDisplayer } from '@ema-platform/shared';
import {
  extractErrorMessage,
  localized,
  useGetLicensesQuery,
  useReinstateLicenseMutation,
  useRevokeLicenseMutation,
  useSuspendLicenseMutation,
} from '@ema-platform/api';
import type { IssuedLicense } from '@ema-platform/api';

const LICENSE_STATUS_COLORS: Record<string, string> = {
  ACTIVE: 'green',
  EXPIRED: 'yellow',
  SUSPENDED: 'orange',
  CANCELLED: 'red',
  SUPERSEDED: 'gray',
};

type LifecycleAction = 'suspend' | 'revoke' | 'reinstate';

const ACTIONS: Record<
  LifecycleAction,
  { label: string; color: string; confirm: string }
> = {
  suspend: {
    label: 'Suspend',
    color: 'orange',
    confirm: 'Temporarily withdraws the right to trade. Reversible.',
  },
  revoke: {
    label: 'Revoke',
    color: 'red',
    confirm: 'Permanently cancels the licence. This cannot be undone.',
  },
  reinstate: {
    label: 'Reinstate',
    color: 'green',
    confirm: 'Restores a suspended licence to active.',
  },
};

/** Which lifecycle actions make sense from each current status. */
function actionsFor(license: IssuedLicense): LifecycleAction[] {
  switch (license.status) {
    case 'ACTIVE':
    case 'EXPIRED':
      return ['suspend', 'revoke'];
    case 'SUSPENDED':
      return ['reinstate', 'revoke'];
    default:
      return [];
  }
}

function LifecycleModal({
  license,
  onClose,
}: {
  license: IssuedLicense | null;
  onClose: () => void;
}) {
  const [action, setAction] = useState<LifecycleAction | null>(null);
  const [reason, setReason] = useState('');
  const [suspend, { isLoading: suspending }] = useSuspendLicenseMutation();
  const [revoke, { isLoading: revoking }] = useRevokeLicenseMutation();
  const [reinstate, { isLoading: reinstating }] = useReinstateLicenseMutation();

  const available = license ? actionsFor(license) : [];

  const submit = async () => {
    if (!license || !action) return;
    const run =
      action === 'suspend' ? suspend : action === 'revoke' ? revoke : reinstate;
    try {
      await run({ id: license.id, reason }).unwrap();
      notify.success(`Licence ${ACTIONS[action].label.toLowerCase()}d`);
      onClose();
      setAction(null);
      setReason('');
    } catch (error) {
      notify.error(extractErrorMessage(error, 'Could not update the licence'));
    }
  };

  return (
    <Modal
      opened={Boolean(license)}
      onClose={onClose}
      title={`Licence ${license?.certificateNumber ?? ''}`}
      centered
    >
      <Stack>
        <Text size="sm" c="dimmed">
          {license?.companyName} — currently {license?.status}. The reason is
          recorded verbatim on the licence and in the audit trail, and the
          holder is able to see it.
        </Text>
        <Select
          label="Action"
          required
          data={available.map((a) => ({ value: a, label: ACTIONS[a].label }))}
          value={action}
          onChange={(value) => setAction(value as LifecycleAction | null)}
        />
        {action && (
          <Text size="sm" c={ACTIONS[action].color}>
            {ACTIONS[action].confirm}
          </Text>
        )}
        <Textarea
          label="Reason"
          required
          minRows={2}
          value={reason}
          onChange={(e) => setReason(e.target.value)}
        />
        <Group justify="flex-end">
          <Button variant="default" onClick={onClose}>
            Cancel
          </Button>
          <Button
            color={action ? ACTIONS[action].color : undefined}
            disabled={!action || reason.trim().length < 3}
            loading={suspending || revoking || reinstating}
            onClick={submit}
          >
            Confirm
          </Button>
        </Group>
      </Stack>
    </Modal>
  );
}

/**
 * The licence register (US-LOG-017/018): every issued licence with its
 * standing, and the suspend/revoke/reinstate actions that were previously
 * API-only. Queue work stays in the licence queue; this is enforcement.
 */
export function LicenseRegisterPage() {
  const [search, setSearch] = useState('');
  const { data, isLoading } = useGetLicensesQuery(
    search.trim() ? { search: search.trim() } : undefined,
  );
  const [target, setTarget] = useState<IssuedLicense | null>(null);

  const items = data?.items ?? [];
  const showDate = useDateDisplayer();

  return (
    <Container size="xl" py="md">
      <Group justify="space-between" mb="md">
        <div>
          <Title order={3}>Licence register</Title>
          <Text size="sm" c="dimmed">
            {data?.total ?? 0} issued licence{(data?.total ?? 0) === 1 ? '' : 's'}
          </Text>
        </div>
        <TextInput
          placeholder="Certificate № or company"
          leftSection={<IconSearch size={14} />}
          value={search}
          onChange={(e) => setSearch(e.currentTarget.value)}
          w={280}
        />
      </Group>

      <Card withBorder padding={0}>
        {isLoading ? (
          <Center h={200}>
            <Loader />
          </Center>
        ) : items.length === 0 ? (
          <Center h={160}>
            <Text size="sm" c="dimmed">
              {search ? 'No licences match that search.' : 'No licences issued yet.'}
            </Text>
          </Center>
        ) : (
          <Table highlightOnHover>
            <Table.Thead>
              <Table.Tr>
                <Table.Th>Certificate №</Table.Th>
                <Table.Th>Type</Table.Th>
                <Table.Th>Holder</Table.Th>
                <Table.Th>Issued</Table.Th>
                <Table.Th>Expires</Table.Th>
                <Table.Th>Status</Table.Th>
                <Table.Th />
              </Table.Tr>
            </Table.Thead>
            <Table.Tbody>
              {items.map((license) => (
                <Table.Tr key={license.id}>
                  <Table.Td>
                    <Text size="sm" ff="monospace" fw={600}>
                      {license.certificateNumber}
                    </Text>
                  </Table.Td>
                  <Table.Td>
                    <Text size="sm">
                      {localized(license.licenseType?.name)}
                    </Text>
                  </Table.Td>
                  <Table.Td>
                    <Text size="sm">{license.companyName ?? '—'}</Text>
                  </Table.Td>
                  <Table.Td>
                    <Text size="sm" c="dimmed">
                      {showDate(license.issueDate)}
                    </Text>
                  </Table.Td>
                  <Table.Td>
                    <Text size="sm" c="dimmed">
                      {showDate(license.expiryDate)}
                    </Text>
                  </Table.Td>
                  <Table.Td>
                    <Badge
                      size="sm"
                      variant="light"
                      color={LICENSE_STATUS_COLORS[license.status] ?? 'gray'}
                    >
                      {license.status}
                    </Badge>
                  </Table.Td>
                  <Table.Td>
                    {actionsFor(license).length > 0 && (
                      <Tooltip label="Suspend / revoke / reinstate">
                        <Button
                          size="compact-xs"
                          variant="subtle"
                          leftSection={<IconShieldCog size={14} />}
                          onClick={() => setTarget(license)}
                        >
                          Status
                        </Button>
                      </Tooltip>
                    )}
                  </Table.Td>
                </Table.Tr>
              ))}
            </Table.Tbody>
          </Table>
        )}
      </Card>

      <LifecycleModal license={target} onClose={() => setTarget(null)} />
    </Container>
  );
}

export default LicenseRegisterPage;
