import { useMemo, useState } from 'react';
import {
  ActionIcon,
  Alert,
  Badge,
  Button,
  Card,
  Checkbox,
  Group,
  Loader,
  Modal,
  ScrollArea,
  SegmentedControl,
  Select,
  Stack,
  Table,
  Text,
  TextInput,
  Tooltip,
} from '@mantine/core';
import {
  IconAdjustments,
  IconAlertCircle,
  IconCheck,
  IconDownload,
  IconInfoCircle,
  IconSearch,
} from '@tabler/icons-react';
import { useTranslation } from 'react-i18next';
import { ModalFooter } from '@ema-platform/ui';
import {
  useCreateDocumentRequirementMutation,
  useGetLicenseTypesQuery,
  useGetPersonalDocumentsQuery,
  useLocalized,
  type ApplicationKind,
  type DocumentRequirement,
  type LicenseType,
  type PersonalDocumentGroup,
} from '@ema-platform/api';
import { useRequirementActions } from '../hooks/useRequirementActions';
import type { DraftRequirement } from './DocumentRequirementEditorDrawer';

const MIME_LABELS: Record<string, string> = {
  'application/pdf': 'PDF',
  'application/msword': 'DOC',
  'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'DOCX',
  'application/vnd.ms-excel': 'XLS',
  'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'XLSX',
};

function shortMime(mime: string): string {
  return MIME_LABELS[mime] ?? mime.split('/')[1]?.toUpperCase() ?? mime;
}

interface ImportPersonalDocumentsModalProps {
  opened: boolean;
  onClose: () => void;
  licenseType: LicenseType;
  applicationKind: ApplicationKind;
  existingKeys: string[];
  currentMaxSortOrder: number;
  onCustomizeAndAdd: (draft: Partial<DraftRequirement>) => void;
}

export function ImportPersonalDocumentsModal({
  opened,
  onClose,
  licenseType,
  applicationKind,
  existingKeys,
  currentMaxSortOrder,
  onCustomizeAndAdd,
}: ImportPersonalDocumentsModalProps) {
  const { t, i18n } = useTranslation();
  const localized = useLocalized();
  const run = useRequirementActions();

  const [search, setSearch] = useState('');
  const [scopeFilter, setScopeFilter] = useState<'all' | 'scoped'>('all');
  const [importMode, setImportMode] = useState<DocumentRequirement['mode']>('ALWAYS');
  const [selectedKeys, setSelectedKeys] = useState<string[]>([]);

  const { data: licenseTypes } = useGetLicenseTypesQuery();
  const { data: personalDocsData, isLoading, isError, refetch } = useGetPersonalDocumentsQuery({
    take: 100,
    locale: i18n.language === 'am' ? 'am' : 'en',
  });

  const [createRequirement, { isLoading: isCreating }] = useCreateDocumentRequirementMutation();

  const groups = useMemo(() => {
    return (personalDocsData?.items ?? []).map((group) => {
      const scopeIds = group.rows
        .map((r) => r.licenseTypeId)
        .filter((id): id is string => id !== null);
      const isGlobal = scopeIds.length === 0;
      const appliesToCurrentType = isGlobal || scopeIds.includes(licenseType.id);
      const isAlreadyAdded = existingKeys.includes(group.key);

      return {
        ...group,
        scopeIds,
        isGlobal,
        appliesToCurrentType,
        isAlreadyAdded,
        mainRow: group.rows[0],
      };
    });
  }, [personalDocsData, licenseType.id, existingKeys]);

  const filteredGroups = useMemo(() => {
    const q = search.trim().toLowerCase();
    return groups.filter((item) => {
      if (scopeFilter === 'scoped' && !item.appliesToCurrentType) {
        return false;
      }
      if (!q) return true;
      const nameEn = item.mainRow.name.en?.toLowerCase() ?? '';
      const nameAm = item.mainRow.name.am?.toLowerCase() ?? '';
      const key = item.key.toLowerCase();
      return nameEn.includes(q) || nameAm.includes(q) || key.includes(q);
    });
  }, [groups, search, scopeFilter]);

  const selectableKeys = useMemo(
    () => filteredGroups.filter((g) => !g.isAlreadyAdded).map((g) => g.key),
    [filteredGroups],
  );

  const allSelected =
    selectableKeys.length > 0 && selectableKeys.every((k) => selectedKeys.includes(k));
  const someSelected =
    selectableKeys.some((k) => selectedKeys.includes(k)) && !allSelected;

  function toggleSelectAll() {
    if (allSelected) {
      setSelectedKeys((prev) => prev.filter((k) => !selectableKeys.includes(k)));
    } else {
      setSelectedKeys((prev) => Array.from(new Set([...prev, ...selectableKeys])));
    }
  }

  function toggleSelectOne(key: string) {
    setSelectedKeys((prev) =>
      prev.includes(key) ? prev.filter((k) => k !== key) : [...prev, key],
    );
  }

  async function handleBatchImport() {
    const itemsToImport = groups.filter(
      (g) => selectedKeys.includes(g.key) && !g.isAlreadyAdded,
    );
    if (itemsToImport.length === 0) return;

    const ok = await run(
      () =>
        Promise.all(
          itemsToImport.map((item, index) =>
            createRequirement({
              key: item.key,
              name: item.mainRow.name,
              description: item.mainRow.description,
              applicationKind,
              mode: importMode,
              allowedMimeTypes:
                item.mainRow.allowedMimeTypes ?? ['application/pdf', 'image/jpeg', 'image/png'],
              maxSizeMb: item.mainRow.maxSizeMb ?? 5,
              requiresValidityDates: item.mainRow.requiresValidityDates ?? false,
              allowMultiple: (item.mainRow.maxFiles ?? 1) !== 1,
              isPersonal: false,
              maxFiles: item.mainRow.maxFiles ?? null,
              sortOrder: currentMaxSortOrder + index + 1,
              licenseTypeId: licenseType.id,
            }).unwrap(),
          ),
        ),
      t('certReq.doc.importSuccess', 'Imported {{count}} personal document(s)', {
        count: itemsToImport.length,
      }),
    );

    if (ok) {
      setSelectedKeys([]);
      onClose();
    }
  }

  function handleCustomizeRow(item: (typeof groups)[number]) {
    onCustomizeAndAdd({
      key: item.key,
      name: { ...item.mainRow.name },
      description: item.mainRow.description ? { ...item.mainRow.description } : undefined,
      applicationKind,
      mode: importMode,
      allowedMimeTypes: [...item.mainRow.allowedMimeTypes],
      maxSizeMb: item.mainRow.maxSizeMb,
      maxFiles: item.mainRow.maxFiles,
      requiresValidityDates: item.mainRow.requiresValidityDates,
      allowMultiple: (item.mainRow.maxFiles ?? 1) !== 1,
      isPersonal: false,
      sortOrder: currentMaxSortOrder + 1,
    });
    onClose();
  }

  return (
    <Modal
      opened={opened}
      onClose={onClose}
      title={
        <div>
          <Text fw={700} fz="lg">
            {t('certReq.doc.importPersonal', 'Import from personal documents')}
          </Text>
          <Text fz="xs" c="dimmed">
            {localized(licenseType.name)} · {applicationKind}
          </Text>
        </div>
      }
      size="lg"
      padding="md"
    >
      <Stack gap="md">
        <Alert
          variant="light"
          color="blue"
          icon={<IconInfoCircle size={16} />}
        >
          <Text fz="xs">
            {t(
              'certReq.doc.importedHelper',
              'Imported from personal documents. The key matches the vault so uploaded files will link automatically.',
            )}
          </Text>
        </Alert>

        <Group justify="space-between" align="center" wrap="wrap" gap="sm">
          <TextInput
            placeholder={t('certReq.personal.searchPlaceholder', 'Search by name or key')}
            leftSection={<IconSearch size={14} />}
            value={search}
            onChange={(e) => setSearch(e.currentTarget.value)}
            size="xs"
            style={{ flex: 1, minWidth: 200 }}
          />

          <SegmentedControl
            size="xs"
            value={scopeFilter}
            onChange={(v) => setScopeFilter(v as 'all' | 'scoped')}
            data={[
              { value: 'all', label: t('certReq.personal.filterAny', 'All personal docs') },
              {
                value: 'scoped',
                label: t('certReq.doc.scopeSelected', 'Relevant to licence'),
              },
            ]}
          />
        </Group>

        <Group justify="space-between" align="center" gap="sm">
          <Select
            label={t('certReq.doc.importMode', 'Requirement mode for imported documents')}
            size="xs"
            w={240}
            data={[
              { value: 'ALWAYS', label: t('certReq.doc.modeAlways', 'Always required') },
              { value: 'OPTIONAL', label: t('certReq.doc.modeOptional', 'Optional upload') },
              {
                value: 'CONDITIONAL',
                label: t('certReq.doc.modeConditional', 'Required when condition holds'),
              },
            ]}
            value={importMode}
            onChange={(v) => v && setImportMode(v as DocumentRequirement['mode'])}
            allowDeselect={false}
          />

          <Text fz="xs" c="dimmed" pt="lg">
            {t('certReq.personal.fileCount', '{{count}} document(s) available', {
              count: selectableKeys.length,
            })}
          </Text>
        </Group>

        {isLoading ? (
          <Group justify="center" py="xl">
            <Loader size="sm" />
            <Text fz="sm" c="dimmed">
              {t('certReq.doc.loading', 'Loading personal documents…')}
            </Text>
          </Group>
        ) : isError ? (
          <Alert color="red" icon={<IconAlertCircle size={16} />}>
            {t('certReq.doc.loadFailed', 'Could not load personal documents')}
            <Button size="xs" variant="subtle" color="red" ml="sm" onClick={() => refetch()}>
              {t('landing.retry', 'Retry')}
            </Button>
          </Alert>
        ) : filteredGroups.length === 0 ? (
          <Card withBorder radius="sm" p="lg" ta="center">
            <Text fz="sm" c="dimmed">
              {search
                ? t('certReq.personal.noMatch', 'No personal document matches those filters.')
                : t('certReq.doc.noPersonalDocs', 'No personal documents configured in Configuration yet.')}
            </Text>
          </Card>
        ) : (
          <ScrollArea.Autosize mah={380} type="auto">
            <Table highlightOnHover verticalSpacing="xs" fz="sm">
              <Table.Thead>
                <Table.Tr>
                  <Table.Th w={40}>
                    <Checkbox
                      checked={allSelected}
                      indeterminate={someSelected}
                      onChange={toggleSelectAll}
                      disabled={selectableKeys.length === 0}
                    />
                  </Table.Th>
                  <Table.Th>{t('certReq.personal.columns.document', 'Document')}</Table.Th>
                  <Table.Th>{t('certReq.doc.allowedTypes', 'Format & Limits')}</Table.Th>
                  <Table.Th>{t('certReq.doc.scope', 'Scope')}</Table.Th>
                  <Table.Th ta="right">{t('certReq.personal.columns.actions', 'Actions')}</Table.Th>
                </Table.Tr>
              </Table.Thead>
              <Table.Tbody>
                {filteredGroups.map((item) => {
                  const isSelected = selectedKeys.includes(item.key);
                  return (
                    <Table.Tr
                      key={item.key}
                      bg={
                        item.isAlreadyAdded
                          ? 'var(--mantine-color-gray-light)'
                          : isSelected
                            ? 'var(--mantine-color-blue-light)'
                            : undefined
                      }
                    >
                      <Table.Td>
                        <Checkbox
                          checked={isSelected || item.isAlreadyAdded}
                          disabled={item.isAlreadyAdded}
                          onChange={() => toggleSelectOne(item.key)}
                        />
                      </Table.Td>
                      <Table.Td>
                        <Group gap="xs" wrap="nowrap">
                          <div>
                            <Group gap={6}>
                              <Text fz="sm" fw={600}>
                                {localized(item.mainRow.name) || item.key}
                              </Text>
                              {item.isAlreadyAdded && (
                                <Badge size="xs" color="gray" variant="light">
                                  {t('certReq.doc.alreadyAdded', 'Already added')}
                                </Badge>
                              )}
                            </Group>
                            <Text fz="xs" c="dimmed">
                              {item.key}
                            </Text>
                          </div>
                        </Group>
                      </Table.Td>
                      <Table.Td>
                        <Text fz="xs">
                          {(item.mainRow.allowedMimeTypes ?? []).slice(0, 3).map(shortMime).join(', ')}
                          {(item.mainRow.allowedMimeTypes ?? []).length > 3 && '...'}
                        </Text>
                        <Text fz="xs" c="dimmed">
                          {item.mainRow.maxSizeMb} MB ·{' '}
                          {item.mainRow.maxFiles === null
                            ? t('certReq.doc.maxFilesUnlimited', 'No limit')
                            : `${item.mainRow.maxFiles} file(s)`}
                          {item.mainRow.requiresValidityDates && ' · Validity'}
                        </Text>
                      </Table.Td>
                      <Table.Td>
                        {item.isGlobal ? (
                          <Badge size="xs" variant="filled" color="gray">
                            {t('certReq.doc.scopeAll', 'All licences')}
                          </Badge>
                        ) : (
                          <Badge size="xs" variant="light" color="blue">
                            {t('certReq.doc.scopeSelected', 'Selected')}
                          </Badge>
                        )}
                      </Table.Td>
                      <Table.Td ta="right">
                        <Tooltip label={t('certReq.doc.customizeAndAdd', 'Customize & add')}>
                          <ActionIcon
                            variant="light"
                            color="blue"
                            size="sm"
                            onClick={() => handleCustomizeRow(item)}
                          >
                            <IconAdjustments size={14} />
                          </ActionIcon>
                        </Tooltip>
                      </Table.Td>
                    </Table.Tr>
                  );
                })}
              </Table.Tbody>
            </Table>
          </ScrollArea.Autosize>
        )}

        <ModalFooter>
          <Button variant="default" onClick={onClose}>
            {t('certReq.cancel', 'Cancel')}
          </Button>
          <Button
            color="teal"
            leftSection={<IconDownload size={15} />}
            disabled={selectedKeys.length === 0}
            loading={isCreating}
            onClick={handleBatchImport}
          >
            {t('certReq.doc.importSelected', 'Import selected ({{count}})', {
              count: selectedKeys.length,
            })}
          </Button>
        </ModalFooter>
      </Stack>
    </Modal>
  );
}
