import { useMemo, useState } from 'react';
import { ActionIcon, Alert, Badge, Button, Card, Group, Modal, Stack, Text, Title } from '@mantine/core';
import { IconAlertCircle, IconDownload, IconEdit, IconPlus, IconTrash } from '@tabler/icons-react';
import { useTranslation } from 'react-i18next';
import { EmptyState, ErrorState, ModalFooter, PageLoader } from '@ema-platform/ui';
import {
  extractErrorMessage,
  useCreateDocumentRequirementMutation,
  useDeleteDocumentRequirementMutation,
  useGetDocumentRequirementsQuery,
  useGetFormSchemaPaletteQuery,
  useLocalized,
  useUpdateDocumentRequirementMutation,
  type ApplicationKind,
  type DocumentRequirement,
  type LicenseType,
} from '@ema-platform/api';
import { collectConditionTargets } from '../config/schema-paths';
import { useRequirementActions } from '../hooks/useRequirementActions';
import { describeCondition } from './ConditionBuilder';
import {
  DocumentRequirementEditorDrawer,
  type DraftRequirement,
} from './DocumentRequirementEditorDrawer';
import { ImportPersonalDocumentsModal } from './ImportPersonalDocumentsModal';

/** Every kind the server validates a document set for, so each can be configured. */
const KINDS: ApplicationKind[] = ['NEW', 'RENEWAL', 'REISSUE'];

const KIND_LABEL: Record<ApplicationKind, [string, string]> = {
  NEW: ['certReq.doc.kindNew', 'New application'],
  RENEWAL: ['certReq.doc.kindRenewal', 'Renewal'],
  REISSUE: ['certReq.doc.kindReissue', 'Damaged / reissue'],
};

const MODE_COLOR: Record<DocumentRequirement['mode'], string> = {
  ALWAYS: 'blue',
  CONDITIONAL: 'violet',
  OPTIONAL: 'gray',
};

/**
 * Document upload requirements for one licence type, grouped by application
 * kind (a new-application slot and its renewal counterpart are different
 * rows even when they share a key). Every edit is a real CRUD call the
 * moment the admin confirms it — there is no separate "save all" step here,
 * unlike the form schema tab's whole-document replace.
 */
export function DocumentRequirementsTab({ licenseType }: { licenseType: LicenseType }) {
  const { t } = useTranslation();
  const localized = useLocalized();
  const run = useRequirementActions();

  const { data, isLoading, isError, error, refetch } = useGetDocumentRequirementsQuery();
  const { data: palette } = useGetFormSchemaPaletteQuery();
  const [createRequirement, { isLoading: creating }] = useCreateDocumentRequirementMutation();
  const [updateRequirement, { isLoading: updating }] = useUpdateDocumentRequirementMutation();
  const [deleteRequirement] = useDeleteDocumentRequirementMutation();

  const [editorState, setEditorState] = useState<{ kind: ApplicationKind; requirement: DocumentRequirement | null } | null>(null);
  const [initialDraft, setInitialDraft] = useState<Partial<DraftRequirement> | null>(null);
  const [importModalKind, setImportModalKind] = useState<ApplicationKind | null>(null);
  const [deleteTarget, setDeleteTarget] = useState<DocumentRequirement | null>(null);

  const requirements = useMemo(
    // Personal documents can also name a licence type — they are asked for in
    // the applicant's vault, not on this form, and are edited in Configuration.
    () =>
      (data?.items ?? []).filter(
        (r) => r.licenseTypeId === licenseType.id && !r.isPersonal,
      ),
    [data, licenseType.id],
  );
  const conditionTargets = collectConditionTargets(licenseType.formSchema.sections);

  async function handleSave(draft: Omit<DocumentRequirement, 'id' | 'licenseTypeId' | 'isActive'>) {
    const ok = await run(
      () =>
        editorState?.requirement
          ? updateRequirement({ id: editorState.requirement.id, ...draft }).unwrap()
          : createRequirement({ ...draft, licenseTypeId: licenseType.id }).unwrap(),
      editorState?.requirement
        ? t('certReq.doc.updated', 'Document requirement updated')
        : t('certReq.doc.created', 'Document requirement added'),
    );
    if (ok) setEditorState(null);
  }

  async function confirmDelete() {
    if (!deleteTarget) return;
    const ok = await run(
      () => deleteRequirement(deleteTarget.id).unwrap(),
      t('certReq.doc.deleted', 'Document requirement removed'),
    );
    if (ok) setDeleteTarget(null);
  }

  if (isLoading) return <PageLoader label={t('certReq.doc.loading', 'Loading document requirements…')} height={300} />;

  if (isError) {
    return (
      <ErrorState
        title={t('certReq.doc.loadFailed', 'Could not load document requirements')}
        description={extractErrorMessage(error)}
        onRetry={() => refetch()}
        icon={IconAlertCircle}
      />
    );
  }

  return (
    <Stack gap="lg">
      <Text fz="sm" c="dimmed">
        {t(
          'certReq.doc.subtitle',
          'What an applicant must upload for this licence type, split by new application and renewal.',
        )}
      </Text>

      {KINDS.map((kind) => {
        const rows = requirements
          .filter((r) => r.applicationKind === kind)
          .sort((a, b) => a.sortOrder - b.sortOrder);

        return (
          <Card key={kind} withBorder radius="md" p="md">
            <Group justify="space-between" mb="sm">
              <Title order={5}>{t(...KIND_LABEL[kind])}</Title>
              <Group gap="xs">
                <Button
                  size="xs"
                  variant="outline"
                  leftSection={<IconDownload size={13} />}
                  onClick={() => setImportModalKind(kind)}
                >
                  {t('certReq.doc.importPersonal', 'Import from personal documents')}
                </Button>
                <Button
                  size="xs"
                  variant="light"
                  leftSection={<IconPlus size={13} />}
                  onClick={() => {
                    setInitialDraft(null);
                    setEditorState({ kind, requirement: null });
                  }}
                >
                  {t('certReq.doc.add', 'Add document requirement')}
                </Button>
              </Group>
            </Group>

            {rows.length === 0 ? (
              <Text fz="sm" c="dimmed" ta="center" py="md">
                {t('certReq.doc.emptyKind', 'No document requirements for this application kind yet.')}
              </Text>
            ) : (
              <Stack gap="xs">
                {rows.map((req) => (
                  <Card key={req.id} withBorder radius="sm" p="xs" bg="var(--mantine-color-default-hover)">
                    <Group justify="space-between" wrap="nowrap">
                      <div style={{ minWidth: 0 }}>
                        <Group gap={6}>
                          <Text fz="sm" fw={600} truncate>{localized(req.name) || req.key}</Text>
                          <Badge size="xs" color={MODE_COLOR[req.mode]} variant="light">{req.mode}</Badge>
                          {req.allowMultiple && <Badge size="xs" variant="outline">{t('certReq.doc.multiple', 'multiple')}</Badge>}
                        </Group>
                        <Text fz="xs" c="dimmed" truncate>
                          key: {req.key} · {req.maxSizeMb}MB · {req.allowedMimeTypes.join(', ')}
                        </Text>
                        {req.mode === 'CONDITIONAL' && req.conditionExpression && (
                          <Text fz="xs" c="violet">
                            {t('certReq.doc.when', 'when')} {describeCondition(req.conditionExpression, t)}
                          </Text>
                        )}
                      </div>
                      <Group gap={4} wrap="nowrap">
                        <ActionIcon variant="subtle" color="blue" onClick={() => setEditorState({ kind, requirement: req })}>
                          <IconEdit size={14} />
                        </ActionIcon>
                        <ActionIcon variant="subtle" color="red" onClick={() => setDeleteTarget(req)}>
                          <IconTrash size={14} />
                        </ActionIcon>
                      </Group>
                    </Group>
                  </Card>
                ))}
              </Stack>
            )}
          </Card>
        );
      })}

      {requirements.length === 0 && (
        <EmptyState
          title={t('certReq.doc.empty', 'No document requirements configured')}
          description={t('certReq.doc.emptyBody', 'Add the documents an applicant must upload for this licence type.')}
        />
      )}

      <DocumentRequirementEditorDrawer
        opened={editorState !== null}
        onClose={() => {
          setEditorState(null);
          setInitialDraft(null);
        }}
        requirement={editorState?.requirement ?? null}
        initialDraft={initialDraft}
        defaultApplicationKind={editorState?.kind ?? 'NEW'}
        onSave={handleSave}
        palette={palette}
        conditionTargets={conditionTargets}
        saving={creating || updating}
      />

      {importModalKind && (
        <ImportPersonalDocumentsModal
          opened={importModalKind !== null}
          onClose={() => setImportModalKind(null)}
          licenseType={licenseType}
          applicationKind={importModalKind}
          existingKeys={requirements
            .filter((r) => r.applicationKind === importModalKind)
            .map((r) => r.key)}
          currentMaxSortOrder={requirements
            .filter((r) => r.applicationKind === importModalKind)
            .reduce((max, r) => Math.max(max, r.sortOrder ?? 0), 0)}
          onCustomizeAndAdd={(draft) => {
            setInitialDraft(draft);
            setEditorState({
              kind: (draft.applicationKind as ApplicationKind) ?? importModalKind,
              requirement: null,
            });
          }}
        />
      )}

      <Modal opened={deleteTarget !== null} onClose={() => setDeleteTarget(null)} title={t('certReq.doc.delete', 'Delete document requirement')} size="sm">
        <Stack gap="md">
          <Alert color="yellow" variant="light">
            {t('certReq.doc.deleteWarning', 'Applicants already relying on this slot will no longer see it. This cannot be undone.')}
          </Alert>
          <Text fz="sm">
            {t('certReq.doc.deleteConfirm', 'Remove "{{name}}"?', {
              name: deleteTarget ? localized(deleteTarget.name) || deleteTarget.key : '',
            })}
          </Text>
          <ModalFooter>
            <Button variant="default" onClick={() => setDeleteTarget(null)}>{t('certReq.cancel', 'Cancel')}</Button>
            <Button color="red" onClick={confirmDelete}>{t('certReq.delete', 'Delete')}</Button>
          </ModalFooter>
        </Stack>
      </Modal>
    </Stack>
  );
}
