import { useEffect, useState, useCallback } from 'react';
import dayjs from 'dayjs';
import {
  Tabs, Typography, Table, Button, Modal, Form, Input, Select,
  Switch, Checkbox, Popconfirm, message, Card, Tag, Space, Divider, InputNumber, Badge, Row, Col, Radio, Alert, Descriptions,
} from 'antd';
import {
  UserOutlined, FileTextOutlined, ThunderboltOutlined,
  PlusOutlined, DeleteOutlined, EditOutlined, CloudUploadOutlined,
  HistoryOutlined, MinusCircleOutlined, CopyOutlined, KeyOutlined,
  QrcodeOutlined, UnorderedListOutlined, PrinterOutlined, GlobalOutlined,
  TagsOutlined, ApiOutlined, ReloadOutlined,
} from '@ant-design/icons';
import type { ColumnsType } from 'antd/es/table';
import type { FormInstance } from 'antd';
import {
  settingsApi,
  type SettingDocType, type SettingPostprocessing, type SettingUserClient,
  type SettingDocField, type SettingPostprocessingAction, type SettingExportTarget,
  type SettingPostprocessingLog, type FilterGroup, type FilterCondition,
  INBOX_ACTION_LABELS,
  type InboxAction, type InboxActionType,
  agrarmonitorApi, type AgrarmonitorStatusData,
  type SettingClient, type AgrarmonitorPollingConfig, type AgrarmonitorPollingResult,
  type SyncConflict,
} from '../api/settings';
import { clientsApi, type Client } from '../api/inbox';
import { apiKeysApi, type ApiKey } from '../api/api-keys';
import { webhookApi, type WebhookStatus } from '../api/webhook';
import {
  barcodeTemplatesApi,
  type BarcodeTemplate,
  type LabelInputField,
} from '../api/barcode-templates';
import { labelPrintAgentApi } from '../api/labelPrintAgent';
import {
  paperlessApi, type PaperlessTag, type PaperlessDocType,
  type PaperlessCustomField, type PaperlessCorrespondent,
} from '../api/paperless';
import TaskLogPage from './TaskLogPage';

const { Title } = Typography;

// ═══════════════════════════════════════════════════════════════════
// Filter Builder Component
// ═══════════════════════════════════════════════════════════════════

const FIELD_OPTIONS = [
  { value: 'document_type', label: 'Dokumenttyp' },
  { value: 'correspondent', label: 'Absender' },
  { value: 'owner', label: 'Eigentümer' },
  { value: 'tag', label: 'Tag' },
  { value: 'title', label: 'Titel' },
  { value: 'archive_serial_number', label: 'Ablagenummer' },
];

const OPERATOR_OPTIONS = [
  { value: 'equals', label: '=' },
  { value: 'not_equals', label: '≠' },
  { value: 'contains', label: 'enthält' },
  { value: 'not_contains', label: 'enthält nicht' },
  { value: 'is_set', label: 'ist gesetzt' },
  { value: 'is_not_set', label: 'ist nicht gesetzt' },
  { value: 'gt', label: '>' },
  { value: 'lt', label: '<' },
];

function isFilterGroup(rule: FilterCondition | FilterGroup): rule is FilterGroup {
  return 'combinator' in rule;
}

interface FilterBuilderProps {
  value: FilterGroup;
  onChange: (val: FilterGroup) => void;
  tags: PaperlessTag[];
  docTypes: PaperlessDocType[];
  correspondents: PaperlessCorrespondent[];
  customFields: PaperlessCustomField[];
}

function FilterBuilder({ value, onChange, tags, docTypes, correspondents, customFields }: FilterBuilderProps) {
  const allFieldOptions = [
    ...FIELD_OPTIONS,
    ...customFields.map(cf => ({ value: `custom_field_${cf.id}`, label: `CF: ${cf.name}` })),
  ];

  const updateRule = (index: number, updated: FilterCondition | FilterGroup) => {
    const newRules = [...value.rules];
    newRules[index] = updated;
    onChange({ ...value, rules: newRules });
  };

  const removeRule = (index: number) => {
    const newRules = value.rules.filter((_, i) => i !== index);
    onChange({ ...value, rules: newRules });
  };

  const addCondition = () => {
    onChange({
      ...value,
      rules: [...value.rules, { field: 'document_type', operator: 'equals', value: null }],
    });
  };

  const addGroup = () => {
    onChange({
      ...value,
      rules: [...value.rules, { combinator: 'AND', rules: [] }],
    });
  };

  const renderValueInput = (cond: FilterCondition, onUpdate: (val: any) => void) => {
    if (cond.operator === 'is_set' || cond.operator === 'is_not_set') return null;

    if (cond.field === 'document_type') {
      return (
        <Select value={cond.value ?? undefined} onChange={onUpdate} style={{ minWidth: 160 }} showSearch optionFilterProp="children" allowClear>
          {(docTypes || []).map(d => <Select.Option key={d.id} value={d.id}>{d.name}</Select.Option>)}
        </Select>
      );
    }
    if (cond.field === 'correspondent') {
      return (
        <Select value={cond.value ?? undefined} onChange={onUpdate} style={{ minWidth: 160 }} showSearch optionFilterProp="children" allowClear>
          {(correspondents || []).map(c => <Select.Option key={c.id} value={c.id}>{c.name}</Select.Option>)}
        </Select>
      );
    }
    if (cond.field === 'tag') {
      return (
        <Select value={cond.value ?? undefined} onChange={onUpdate} style={{ minWidth: 160 }} showSearch optionFilterProp="children" allowClear>
          {(tags || []).map(t => <Select.Option key={t.id} value={t.id}>{t.name}</Select.Option>)}
        </Select>
      );
    }
    if (cond.field.startsWith('custom_field_')) {
      const cfId = parseInt(cond.field.replace('custom_field_', ''), 10);
      const cf = (customFields || []).find(c => c.id === cfId);
      const selectOptions = cf?.extra_data?.select_options;
      if (Array.isArray(selectOptions)) {
        return (
          <Select value={cond.value ?? undefined} onChange={onUpdate} style={{ minWidth: 160 }} showSearch optionFilterProp="children" allowClear>
            {selectOptions.filter(opt => opt && (opt.id || opt.label)).map((opt: any) => (
              <Select.Option key={opt.id ?? opt.label} value={opt.label}>{opt.label}</Select.Option>
            ))}
          </Select>
        );
      }
    }

    return <Input value={cond.value ?? ''} onChange={e => onUpdate(e.target.value)} style={{ minWidth: 160 }} placeholder="Wert" />;
  };

  return (
    <div style={{ border: '1px solid #d9d9d9', borderRadius: 8, padding: 12, background: '#fafafa' }}>
      <Space style={{ marginBottom: 8 }}>
        <Select
          value={value.combinator}
          onChange={c => onChange({ ...value, combinator: c })}
          style={{ width: 80 }}
        >
          <Select.Option value="AND">UND</Select.Option>
          <Select.Option value="OR">ODER</Select.Option>
        </Select>
        <span style={{ color: '#888', fontSize: 12 }}>Alle Bedingungen dieser Gruppe müssen zutreffen</span>
      </Space>

      {value.rules.map((rule, idx) => (
        <div key={idx} style={{ marginBottom: 8 }}>
          {isFilterGroup(rule) ? (
            <div style={{ marginLeft: 16 }}>
              <FilterBuilder
                value={rule}
                onChange={updated => updateRule(idx, updated)}
                tags={tags} docTypes={docTypes} correspondents={correspondents} customFields={customFields}
              />
              <Button type="link" danger icon={<MinusCircleOutlined />} onClick={() => removeRule(idx)} size="small">
                Gruppe entfernen
              </Button>
            </div>
          ) : (
            <Space wrap>
              <Select
                value={rule.field}
                onChange={f => updateRule(idx, { ...rule, field: f, value: null })}
                style={{ minWidth: 160 }}
                showSearch optionFilterProp="children"
              >
                {allFieldOptions.map(o => <Select.Option key={o.value} value={o.value}>{o.label}</Select.Option>)}
              </Select>
              <Select
                value={rule.operator}
                onChange={op => updateRule(idx, { ...rule, operator: op })}
                style={{ width: 140 }}
              >
                {OPERATOR_OPTIONS.map(o => <Select.Option key={o.value} value={o.value}>{o.label}</Select.Option>)}
              </Select>
              {renderValueInput(rule, val => updateRule(idx, { ...rule, value: val }))}
              <Button type="text" danger icon={<MinusCircleOutlined />} onClick={() => removeRule(idx)} />
            </Space>
          )}
        </div>
      ))}

      <Space style={{ marginTop: 4 }}>
        <Button type="dashed" size="small" icon={<PlusOutlined />} onClick={addCondition}>Bedingung</Button>
        <Button type="dashed" size="small" icon={<PlusOutlined />} onClick={addGroup}>Gruppe</Button>
      </Space>
    </div>
  );
}

// ═══════════════════════════════════════════════════════════════════
// Benutzer & Betriebe Tab
// ═══════════════════════════════════════════════════════════════════

function UserClientsTab() {
  const [data, setData] = useState<SettingUserClient[]>([]);
  const [clients, setClients] = useState<Client[]>([]);
  const [allClients, setAllClients] = useState<SettingClient[]>([]);
  const [loading, setLoading] = useState(true);
  const [clientsLoading, setClientsLoading] = useState(false);
  const [modalOpen, setModalOpen] = useState(false);
  const [form] = Form.useForm();

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const [ucs, cls] = await Promise.all([
        settingsApi.getUserClients(),
        clientsApi.getMyClients(),
      ]);
      setData(ucs);
      setClients(cls);
    } finally { setLoading(false); }
  }, []);

  const loadAllClients = useCallback(async () => {
    setClientsLoading(true);
    try {
      const cls = await settingsApi.getClients();
      setAllClients(cls);
    } finally { setClientsLoading(false); }
  }, []);

  useEffect(() => { load(); loadAllClients(); }, [load, loadAllClients]);

  const handleAdd = async () => {
    const values = await form.validateFields();
    await settingsApi.createUserClient(values);
    message.success('Zuordnung erstellt');
    setModalOpen(false);
    form.resetFields();
    load();
  };

  const handleDelete = async (id: number) => {
    await settingsApi.deleteUserClient(id);
    message.success('Gelöscht');
    load();
  };

  const handleUpdateBetriebId = async (id: number, val: number | null) => {
    try {
      const updated = await settingsApi.updateClient(id, val);
      setAllClients(prev => prev.map(c => c.Id === id ? updated : c));
    } catch {
      message.error('Speichern fehlgeschlagen');
    }
  };

  const allClientColumns: ColumnsType<SettingClient> = [
    { title: 'Name', dataIndex: 'Name', key: 'name' },
    {
      title: 'Agrarmonitor-BetriebId',
      dataIndex: 'AgrarmonitorBetriebId',
      key: 'betriebId',
      render: (val: number | null, record) => (
        <InputNumber
          value={val ?? undefined}
          placeholder="–"
          min={1}
          style={{ width: 120 }}
          onBlur={(e) => {
            const parsed = e.target.value ? parseInt(e.target.value, 10) : null;
            const current = val ?? null;
            if (parsed !== current) handleUpdateBetriebId(record.Id, isNaN(parsed as number) ? null : parsed);
          }}
        />
      ),
    },
  ];

  const columns: ColumnsType<SettingUserClient> = [
    { title: 'User ID', dataIndex: 'UserId', key: 'userId' },
    {
      title: 'Betrieb',
      key: 'client',
      render: (_, r) => clients.find(c => c.Id === r.ClientId)?.Name ?? r.ClientId,
    },
    {
      title: 'Rolle',
      dataIndex: 'Role',
      key: 'role',
      render: (r: string) => <Tag color={r === 'admin' ? 'red' : r === 'editor' ? 'blue' : 'default'}>{r}</Tag>,
    },
    {
      title: '',
      key: 'actions',
      width: 80,
      render: (_, record) => (
        <Popconfirm title="Wirklich löschen?" onConfirm={() => handleDelete(record.Id)}>
          <Button danger icon={<DeleteOutlined />} size="small" />
        </Popconfirm>
      ),
    },
  ];

  return (
    <>
      <Button type="primary" icon={<PlusOutlined />} onClick={() => setModalOpen(true)} style={{ marginBottom: 16 }}>
        Zuordnung hinzufügen
      </Button>
      <Table dataSource={data} columns={columns} loading={loading} rowKey="Id" size="small" pagination={false} />

      <Divider />
      <Typography.Title level={5} style={{ marginBottom: 8 }}>Betriebe — Agrarmonitor-Zuordnung</Typography.Title>
      <Typography.Text type="secondary" style={{ display: 'block', marginBottom: 12 }}>
        Ordne jedem Betrieb die zugehörige Agrarmonitor-BetriebId zu. Wird beim Polling verwendet.
      </Typography.Text>
      <Table
        dataSource={allClients}
        columns={allClientColumns}
        loading={clientsLoading}
        rowKey="Id"
        size="small"
        pagination={false}
      />

      <Modal title="Neue Zuordnung" open={modalOpen} onOk={handleAdd} onCancel={() => setModalOpen(false)}>
        <Form form={form} layout="vertical">
          <Form.Item name="UserId" label="User ID (Authentik)" rules={[{ required: true }]}>
            <Input />
          </Form.Item>
          <Form.Item name="ClientId" label="Betrieb" rules={[{ required: true }]}>
            <Select>
              {clients.map(c => <Select.Option key={c.Id} value={c.Id}>{c.Name}</Select.Option>)}
            </Select>
          </Form.Item>
          <Form.Item name="Role" label="Rolle" initialValue="editor">
            <Select>
              <Select.Option value="viewer">Viewer</Select.Option>
              <Select.Option value="editor">Editor</Select.Option>
              <Select.Option value="admin">Admin</Select.Option>
            </Select>
          </Form.Item>
        </Form>
      </Modal>
    </>
  );
}

// ═══════════════════════════════════════════════════════════════════
// Document Fields Tab
// ═══════════════════════════════════════════════════════════════════

const FIELD_TYPE_OPTIONS = [
  { value: 1, label: 'Absender' },
  { value: 2, label: 'Belegdatum' },
  { value: 3, label: 'Ablagenummer' },
  { value: 4, label: 'Custom Field' },
  { value: 5, label: 'Titel' },
];

function DocTypeFieldsTable({ docTypeId }: { docTypeId: number }) {
  const [fields, setFields] = useState<SettingDocField[]>([]);
  const [customFields, setCustomFields] = useState<PaperlessCustomField[]>([]);
  const [loading, setLoading] = useState(true);
  const [editField, setEditField] = useState<SettingDocField | null>(null);
  const [isNew, setIsNew] = useState(false);
  const [form] = Form.useForm();
  const [fieldType, setFieldType] = useState(4);

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const [f, cf] = await Promise.all([
        settingsApi.getDocFields(docTypeId),
        paperlessApi.getCustomFields(),
      ]);
      setFields(f);
      setCustomFields(cf);
    } finally { setLoading(false); }
  }, [docTypeId]);

  useEffect(() => { load(); }, [load]);

  const openNew = () => {
    setIsNew(true);
    setFieldType(4);
    form.resetFields();
    form.setFieldsValue({ Type: 4, TypeIndex: null, IsRequired: false, IsRequiredPosteingang: false, VisiblePosteingang: true, Hinweis: '' });
    setEditField({} as any);
  };

  const openEdit = (f: SettingDocField) => {
    setIsNew(false);
    setFieldType(f.Type);
    form.setFieldsValue(f);
    setEditField(f);
  };

  const handleSave = async () => {
    const values = await form.validateFields();
    // For non-custom-field types, TypeIndex is not relevant
    if (values.Type !== 4) values.TypeIndex = null;

    if (isNew) {
      await settingsApi.createDocField(docTypeId, values);
      message.success('Feld erstellt');
    } else if (editField) {
      await settingsApi.updateDocField(editField.Id, values);
      message.success('Feld gespeichert');
    }
    setEditField(null);
    load();
  };

  const handleDelete = async (id: number) => {
    await settingsApi.deleteDocField(id);
    message.success('Feld gelöscht');
    load();
  };

  const handleToggle = async (id: number, key: string, val: boolean) => {
    await settingsApi.updateDocField(id, { [key]: val } as any);
    load();
  };

  const getFieldLabel = (record: SettingDocField) => {
    switch (record.Type) {
      case 1: return <Tag>Absender</Tag>;
      case 2: return <Tag>Belegdatum</Tag>;
      case 3: return <Tag>Ablagenummer</Tag>;
      case 4:
        const cf = customFields.find(c => c.id === record.TypeIndex);
        return <Tag color="blue">{cf ? cf.name : `CF #${record.TypeIndex}`}</Tag>;
      case 5: return <Tag>Titel</Tag>;
      default: return <Tag>Unbekannt ({record.Type})</Tag>;
    }
  };

  const columns: ColumnsType<SettingDocField> = [
    { title: 'Feldtyp', key: 'type', render: (_, record) => getFieldLabel(record) },
    {
      title: 'Pflichtfeld', dataIndex: 'IsRequired', key: 'req', width: 100,
      render: (v, r) => <Switch checked={v} size="small" onChange={val => handleToggle(r.Id, 'IsRequired', val)} />,
    },
    {
      title: 'Pflicht (Posteingang)', dataIndex: 'IsRequiredPosteingang', key: 'reqPE', width: 140,
      render: (v, r) => <Switch checked={v} size="small" onChange={val => handleToggle(r.Id, 'IsRequiredPosteingang', val)} />,
    },
    {
      title: 'Sichtbar (Posteingang)', dataIndex: 'VisiblePosteingang', key: 'visPE', width: 150,
      render: (v, r) => <Switch checked={v} size="small" onChange={val => handleToggle(r.Id, 'VisiblePosteingang', val)} />,
    },
    { title: 'Hinweis', dataIndex: 'Hinweis', key: 'hinweis', ellipsis: true },
    {
      title: '', key: 'actions', width: 100,
      render: (_, rec) => (
        <Space>
          <Button icon={<EditOutlined />} size="small" onClick={() => openEdit(rec)} />
          <Popconfirm title="Feld wirklich löschen?" onConfirm={() => handleDelete(rec.Id)}>
            <Button danger icon={<DeleteOutlined />} size="small" />
          </Popconfirm>
        </Space>
      ),
    },
  ];

  return (
    <>
      <Button type="dashed" size="small" icon={<PlusOutlined />} onClick={openNew} style={{ marginBottom: 8 }}>
        Feld hinzufügen
      </Button>
      <Table dataSource={fields} columns={columns} pagination={false} size="small" loading={loading} rowKey="Id" scroll={{ x: 'max-content' }} />

      <Modal
        title={isNew ? 'Neues Feld' : 'Feld bearbeiten'}
        open={!!editField}
        onOk={handleSave}
        onCancel={() => setEditField(null)}
        width={500}
      >
        <Form form={form} layout="vertical">
          <Form.Item name="Type" label="Feldtyp" rules={[{ required: true }]}>
            <Select onChange={(v: number) => setFieldType(v)}>
              {FIELD_TYPE_OPTIONS.map(o => (
                <Select.Option key={o.value} value={o.value}>{o.label}</Select.Option>
              ))}
            </Select>
          </Form.Item>
          {fieldType === 4 && (
            <Form.Item name="TypeIndex" label="Custom Field" rules={[{ required: true, message: 'Bitte Custom Field auswählen' }]}>
              <Select showSearch optionFilterProp="children" placeholder="Custom Field wählen...">
                {customFields.map(cf => (
                  <Select.Option key={cf.id} value={cf.id}>{cf.name}</Select.Option>
                ))}
              </Select>
            </Form.Item>
          )}
          <Form.Item name="IsRequired" label="Pflichtfeld" valuePropName="checked">
            <Switch />
          </Form.Item>
          <Form.Item name="IsRequiredPosteingang" label="Pflichtfeld (Posteingang)" valuePropName="checked">
            <Switch />
          </Form.Item>
          <Form.Item name="VisiblePosteingang" label="Sichtbar im Posteingang" valuePropName="checked">
            <Switch />
          </Form.Item>
          <Form.Item name="Hinweis" label="Hinweis">
            <Input placeholder="Optionaler Hinweistext für Benutzer" />
          </Form.Item>
        </Form>
      </Modal>
    </>
  );
}

// ═══════════════════════════════════════════════════════════════════
// Dokumenttypen Tab
// ═══════════════════════════════════════════════════════════════════

function DocTypesTab() {
  const [data, setData] = useState<SettingDocType[]>([]);
  const [tags, setTags] = useState<PaperlessTag[]>([]);
  const [docTypes, setDocTypes] = useState<PaperlessDocType[]>([]);
  const [loading, setLoading] = useState(true);
  const [editing, setEditing] = useState<SettingDocType | null>(null);
  const [form] = Form.useForm();

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const [docs, fetchedTags, fetchedDocTypes] = await Promise.all([
        settingsApi.getDocTypes(),
        paperlessApi.getTags(),
        paperlessApi.getDocumentTypes()
      ]);
      setData(docs);
      setTags(fetchedTags);
      setDocTypes(fetchedDocTypes);
    }
    finally { setLoading(false); }
  }, []);

  useEffect(() => { load(); }, [load]);

  const handleSave = async () => {
    if (!editing) return;
    const values = await form.validateFields();
    await settingsApi.updateDocType(editing.Id, values);
    message.success('Gespeichert');
    setEditing(null);
    load();
  };

  const getTagName = (id: number | null) => {
    if (!id) return '—';
    const tag = tags.find(t => t.id === id);
    return tag ? <Tag color={tag.color}>{tag.name}</Tag> : id;
  };

  const getDocTypeName = (id: number) => {
    const dt = docTypes.find(d => d.id === id);
    return dt ? dt.name : id;
  };

  const columns: ColumnsType<SettingDocType> = [
    { title: 'Dokumenttyp', dataIndex: 'DocumentTypeId', key: 'id', render: getDocTypeName },
    { title: 'Titel-Template', dataIndex: 'TitelTemplate', key: 'template', ellipsis: true },
    { title: 'Tag (nicht bereit)', dataIndex: 'TagNotReady', key: 'tagNR', render: getTagName },
    { title: 'Tag (bereit)', dataIndex: 'TagReady', key: 'tagR', render: getTagName },
    {
      title: 'Freigabe erf.',
      dataIndex: 'FreigabeErforderlich',
      key: 'freigabe',
      render: (v: boolean | null) => v ? <Tag color="blue">Ja</Tag> : '—',
    },
    {
      title: '',
      key: 'actions',
      width: 60,
      render: (_, rec) => (
        <Button icon={<EditOutlined />} size="small" onClick={() => { setEditing(rec); form.setFieldsValue(rec); }} />
      ),
    },
  ];

  return (
    <>
      <Table 
        dataSource={data} 
        columns={columns} 
        loading={loading} 
        rowKey="Id" 
        size="small" 
        pagination={false} 
      />
      <Modal 
        title="Dokumenttyp bearbeiten" 
        open={!!editing} 
        onOk={handleSave} 
        onCancel={() => setEditing(null)}
        width={900}
      >
        <Form form={form} layout="vertical">
          <Form.Item 
            name="TitelTemplate" 
            label="Titel-Template"
            tooltip="Verfügbare Platzhalter: {{CUSTOM[ID]}} (Wert eines Custom Fields), {{DATE}} (Datum im Format DD.MM.YYYY), {{ZEITSTEMPEL}} (aktueller Zeitstempel)"
          >
            <Input placeholder="z.B. Rechnung_{{CUSTOM[5]}}_{{DATE}}" />
          </Form.Item>
          <Form.Item name="TagNotReady" label="Tag (nicht bereit)">
            <Select allowClear showSearch optionFilterProp="children">
              {tags.map(t => <Select.Option key={t.id} value={t.id}>{t.name}</Select.Option>)}
            </Select>
          </Form.Item>
          <Form.Item name="TagReady" label="Tag (bereit)">
            <Select allowClear showSearch optionFilterProp="children">
              {tags.map(t => <Select.Option key={t.id} value={t.id}>{t.name}</Select.Option>)}
            </Select>
          </Form.Item>
          <Form.Item name="FreigabeErforderlich" valuePropName="checked" label="Freigabe erforderlich">
            <Checkbox />
          </Form.Item>
        </Form>
        
        {editing && (
          <div style={{ marginTop: 24 }}>
            <h4>Dokumentenfelder</h4>
            <DocTypeFieldsTable key={editing.DocumentTypeId} docTypeId={editing.DocumentTypeId} />
          </div>
        )}
      </Modal>
    </>
  );
}

// ═══════════════════════════════════════════════════════════════════
// Action Editor (Sub-component for Postprocessing)
// ═══════════════════════════════════════════════════════════════════

const ACTION_TYPE_LABELS: Record<number, string> = {
  1: 'Export (FTP/WebDAV)',
  2: 'Mail versenden',
  3: 'Tags setzen/entfernen',
  4: 'Custom Field setzen',
  5: 'Webhook',
  6: 'Notiz hinzufügen',
};

function ActionEditor({
  ppId,
  tags,
  customFields,
  exportTargets,
}: {
  ppId: number;
  tags: PaperlessTag[];
  customFields: PaperlessCustomField[];
  exportTargets: SettingExportTarget[];
}) {
  const [actions, setActions] = useState<SettingPostprocessingAction[]>([]);
  const [loading, setLoading] = useState(true);
  const [editAction, setEditAction] = useState<SettingPostprocessingAction | null>(null);
  const [isNew, setIsNew] = useState(false);
  const [form] = Form.useForm();
  const [actionType, setActionType] = useState(1);

  const load = useCallback(async () => {
    setLoading(true);
    try { setActions(await settingsApi.getActions(ppId)); }
    finally { setLoading(false); }
  }, [ppId]);

  useEffect(() => { load(); }, [load]);

  const openNew = () => {
    setIsNew(true);
    setActionType(1);
    form.resetFields();
    form.setFieldsValue({ ActionType: 1, IsActive: true, Order: actions.length + 1, Content: {} });
    setEditAction({} as any);
  };

  const openEdit = (a: SettingPostprocessingAction) => {
    setIsNew(false);
    setActionType(a.ActionType);
    form.setFieldsValue({ ActionType: a.ActionType, IsActive: a.IsActive, Order: a.Order, ...a.Content });
    setEditAction(a);
  };

  const buildContent = (values: any): Record<string, any> => {
    const { ActionType: _, IsActive: __, Order: ___, ...rest } = values;
    return rest;
  };

  const handleSave = async () => {
    const values = await form.validateFields();
    const content = buildContent(values);
    if (isNew) {
      await settingsApi.createAction(ppId, {
        ActionType: values.ActionType,
        Content: content,
        Order: values.Order,
        IsActive: values.IsActive,
      });
      message.success('Aktion erstellt');
    } else if (editAction) {
      await settingsApi.updateAction(editAction.Id, {
        ActionType: values.ActionType,
        Content: content,
        Order: values.Order,
        IsActive: values.IsActive,
      });
      message.success('Aktion gespeichert');
    }
    setEditAction(null);
    load();
  };

  const handleDelete = async (id: number) => {
    await settingsApi.deleteAction(id);
    message.success('Gelöscht');
    load();
  };

  const columns: ColumnsType<SettingPostprocessingAction> = [
    { title: '#', dataIndex: 'Order', key: 'order', width: 50 },
    { title: 'Typ', key: 'type', render: (_, r) => <Tag>{ACTION_TYPE_LABELS[r.ActionType] || r.ActionType}</Tag> },
    { title: 'Aktiv', key: 'active', width: 60, render: (_, r) => <Switch size="small" checked={r.IsActive} disabled /> },
    {
      title: '', key: 'actions', width: 100,
      render: (_, r) => (
        <Space>
          <Button icon={<EditOutlined />} size="small" onClick={() => openEdit(r)} />
          <Popconfirm title="Löschen?" onConfirm={() => handleDelete(r.Id)}>
            <Button danger icon={<DeleteOutlined />} size="small" />
          </Popconfirm>
        </Space>
      ),
    },
  ];

  const renderContentFields = () => {
    switch (actionType) {
      case 1: // Export
        return (
          <>
            <Form.Item name="exportTargetId" label="Export-Ziel" rules={[{ required: true }]}>
              <Select>
                {exportTargets.filter(t => t.IsActive).map(t => (
                  <Select.Option key={t.Id} value={t.Id}>{t.Name} ({t.Protocol})</Select.Option>
                ))}
              </Select>
            </Form.Item>
            <Form.Item name="fileType" label="Datei-Typ" initialValue="archive">
              <Select>
                <Select.Option value="archive">Archiv (OCR)</Select.Option>
                <Select.Option value="original">Original</Select.Option>
              </Select>
            </Form.Item>
            <Form.Item
              name="filenameTemplate"
              label="Dateiname"
              tooltip="Platzhalter: {titel}, {absender_name}, {dokumenttyp_name}, {datum}, {jahr}, {monat}, {tag}, {id}, {ablagenummer}, {besitzer}, {custom_field_<ID>}, {zeitstempel}"
            >
              <Input placeholder="z.B. {datum}_{absender_name}_{titel}" />
            </Form.Item>
            <div style={{ marginTop: -16, marginBottom: 16, fontSize: 12, color: '#888' }}>
              Verfügbare Platzhalter: <code>{'{titel}'}</code> <code>{'{absender_name}'}</code> <code>{'{dokumenttyp_name}'}</code> <code>{'{datum}'}</code> <code>{'{jahr}'}</code> <code>{'{monat}'}</code> <code>{'{tag}'}</code> <code>{'{id}'}</code> <code>{'{ablagenummer}'}</code> <code>{'{besitzer}'}</code> <code>{'{custom_field_<ID>}'}</code>
            </div>
          </>
        );
      case 2: // Mail
        return (
          <>
            <Form.Item name="to" label="Empfänger" rules={[{ required: true, type: 'email' }]}>
              <Input />
            </Form.Item>
            <Form.Item 
              name="subject" 
              label="Betreff" 
              tooltip="Platzhalter: {titel}, {absender_name}, {dokumenttyp_name}, {datum}, {jahr}, {monat}, {tag}, {id}, {ablagenummer}, {besitzer}, {custom_field_<ID>}, {zeitstempel}"
            >
              <Input placeholder="z.B. Rechnung {absender_name} vom {datum}" />
            </Form.Item>
            <Form.Item 
              name="body" 
              label="Text" 
              tooltip="Platzhalter: {titel}, {absender_name}, {dokumenttyp_name}, {datum}, {jahr}, {monat}, {tag}, {id}, {ablagenummer}, {besitzer}, {custom_field_<ID>}, {zeitstempel}"
            >
              <Input.TextArea rows={3} placeholder="z.B. Anbei die Rechnung {titel} von {absender_name}." />
            </Form.Item>
            <Form.Item name="fileType" label="Anhang-Typ" initialValue="archive">
              <Select>
                <Select.Option value="archive">Archiv (OCR)</Select.Option>
                <Select.Option value="original">Original</Select.Option>
              </Select>
            </Form.Item>
            <Form.Item
              name="filenameTemplate"
              label="Dateiname (Anhang)"
              tooltip="Platzhalter: {titel}, {absender_name}, {dokumenttyp_name}, {datum}, {jahr}, {monat}, {tag}, {id}, {ablagenummer}, {besitzer}, {custom_field_<ID>}, {zeitstempel}"
            >
              <Input placeholder="z.B. {datum}_{absender_name}_{titel}" />
            </Form.Item>
          </>
        );
      case 3: // Tags
        return (
          <>
            <Form.Item name="addTags" label="Tags hinzufügen">
              <Select mode="multiple" allowClear showSearch optionFilterProp="children">
                {tags.map(t => <Select.Option key={t.id} value={t.id}>{t.name}</Select.Option>)}
              </Select>
            </Form.Item>
            <Form.Item name="removeTags" label="Tags entfernen">
              <Select mode="multiple" allowClear showSearch optionFilterProp="children">
                {tags.map(t => <Select.Option key={t.id} value={t.id}>{t.name}</Select.Option>)}
              </Select>
            </Form.Item>
          </>
        );
      case 4: // Custom Field
        return (
          <>
            <Form.Item name="fieldId" label="Custom Field" rules={[{ required: true }]}>
              <Select showSearch optionFilterProp="children">
                {customFields.map(cf => <Select.Option key={cf.id} value={cf.id}>{cf.name}</Select.Option>)}
              </Select>
            </Form.Item>
            <Form.Item name="value" label="Wert"><Input /></Form.Item>
          </>
        );
      case 5: // Webhook
        return (
          <>
            <Form.Item name="url" label="URL" rules={[{ required: true, type: 'url' }]}><Input /></Form.Item>
            <Form.Item name="method" label="HTTP Methode" initialValue="POST">
              <Select>
                <Select.Option value="GET">GET</Select.Option>
                <Select.Option value="POST">POST</Select.Option>
                <Select.Option value="PUT">PUT</Select.Option>
              </Select>
            </Form.Item>
          </>
        );
      case 6: // Note
        return (
          <>
            <Form.Item
              name="note"
              label="Notiz"
              rules={[{ required: true }]}
              tooltip="Platzhalter: {titel}, {absender_name}, {dokumenttyp_name}, {datum}, {jahr}, {monat}, {tag}, {id}, {ablagenummer}, {besitzer}, {custom_field_<ID>}"
            >
              <Input.TextArea rows={3} placeholder="z.B. Dokument wurde automatisch exportiert am {datum}." />
            </Form.Item>
          </>
        );
      default: return null;
    }
  };

  return (
    <div style={{ marginTop: 16 }}>
      <Space style={{ marginBottom: 8 }}>
        <h4 style={{ margin: 0 }}>Aktionen</h4>
        <Button type="dashed" size="small" icon={<PlusOutlined />} onClick={openNew}>Aktion hinzufügen</Button>
      </Space>
      <Table dataSource={actions} columns={columns} loading={loading} rowKey="Id" size="small" pagination={false} />

      <Modal
        title={isNew ? 'Neue Aktion' : 'Aktion bearbeiten'}
        open={!!editAction}
        onOk={handleSave}
        onCancel={() => setEditAction(null)}
        width={600}
      >
        <Form form={form} layout="vertical">
          <Space style={{ width: '100%' }}>
            <Form.Item name="ActionType" label="Aktionstyp" rules={[{ required: true }]}>
              <Select style={{ width: 200 }} onChange={v => setActionType(v)}>
                {Object.entries(ACTION_TYPE_LABELS).map(([k, l]) => (
                  <Select.Option key={k} value={Number(k)}>{l}</Select.Option>
                ))}
              </Select>
            </Form.Item>
            <Form.Item name="Order" label="Reihenfolge"><InputNumber min={1} /></Form.Item>
            <Form.Item name="IsActive" label="Aktiv" valuePropName="checked"><Switch /></Form.Item>
          </Space>
          <Divider />
          {renderContentFields()}
        </Form>
      </Modal>
    </div>
  );
}

// ═══════════════════════════════════════════════════════════════════
// Postprocessing Tab
// ═══════════════════════════════════════════════════════════════════

function PostprocessingTab() {
  const [data, setData] = useState<SettingPostprocessing[]>([]);
  const [tags, setTags] = useState<PaperlessTag[]>([]);
  const [docTypes, setDocTypes] = useState<PaperlessDocType[]>([]);
  const [correspondents, setCorrespondents] = useState<PaperlessCorrespondent[]>([]);
  const [customFields, setCustomFields] = useState<PaperlessCustomField[]>([]);
  const [exportTargets, setExportTargets] = useState<SettingExportTarget[]>([]);
  const [loading, setLoading] = useState(true);
  const [editing, setEditing] = useState<SettingPostprocessing | null>(null);
  const [isNew, setIsNew] = useState(false);
  const [form] = Form.useForm();
  const [filterJson, setFilterJson] = useState<FilterGroup>({ combinator: 'AND', rules: [] });

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const [pp, t, dt, c, cf, et] = await Promise.all([
        settingsApi.getPostprocessing(),
        paperlessApi.getTags(),
        paperlessApi.getDocumentTypes(),
        paperlessApi.getCorrespondents(),
        paperlessApi.getCustomFields(),
        settingsApi.getExportTargets(),
      ]);
      setData(pp);
      setTags(t);
      setDocTypes(dt);
      setCorrespondents(c);
      setCustomFields(cf);
      setExportTargets(et);
    } finally { setLoading(false); }
  }, []);

  useEffect(() => { load(); }, [load]);

  const openNew = () => {
    setIsNew(true);
    const emptyFilter: FilterGroup = { combinator: 'AND', rules: [] };
    setFilterJson(emptyFilter);
    form.resetFields();
    form.setFieldsValue({ Name: '', IsActive: true, NoFurther: false, Order: data.length + 1 });
    setEditing({} as any);
  };

  const openEdit = (pp: SettingPostprocessing) => {
    setIsNew(false);
    setFilterJson(pp.FilterJson || { combinator: 'AND', rules: [] });
    form.setFieldsValue({ Name: pp.Name, IsActive: pp.IsActive, NoFurther: pp.NoFurther, Order: pp.Order });
    setEditing(pp);
  };

  const handleSave = async () => {
    const values = await form.validateFields();
    const payload = { ...values, FilterJson: filterJson };

    if (isNew) {
      await settingsApi.createPostprocessing(payload);
      message.success('Regel erstellt');
    } else if (editing) {
      await settingsApi.updatePostprocessing(editing.Id, payload);
      message.success('Gespeichert');
    }
    setEditing(null);
    load();
  };

  const handleToggle = async (id: number, active: boolean) => {
    await settingsApi.updatePostprocessing(id, { IsActive: active });
    load();
  };

  const handleDelete = async (id: number) => {
    await settingsApi.deletePostprocessing(id);
    message.success('Gelöscht');
    load();
  };

  const handleDuplicate = async (id: number) => {
    await settingsApi.duplicatePostprocessing(id);
    message.success('Regel dupliziert');
    load();
  };

  const columns: ColumnsType<SettingPostprocessing> = [
    { title: '#', dataIndex: 'Order', key: 'order', width: 50 },
    { title: 'Name', dataIndex: 'Name', key: 'name' },
    {
      title: 'Bedingungen',
      key: 'conditions',
      render: (_, r) => <Tag>{r.FilterJson?.rules?.length || 0}</Tag>,
    },
    {
      title: 'Aktiv',
      key: 'active',
      width: 70,
      render: (_, r) => <Switch size="small" checked={r.IsActive} onChange={v => handleToggle(r.Id, v)} />,
    },
    {
      title: 'Stop',
      dataIndex: 'NoFurther',
      key: 'stop',
      width: 50,
      render: (v: boolean) => v ? <Tag color="red">Stop</Tag> : null,
    },
    {
      title: '',
      key: 'actions',
      width: 130,
      render: (_, rec) => (
        <Space>
          <Button icon={<EditOutlined />} size="small" onClick={() => openEdit(rec)} />
          <Button icon={<CopyOutlined />} size="small" onClick={() => handleDuplicate(rec.Id)} />
          <Popconfirm title="Wirklich löschen?" onConfirm={() => handleDelete(rec.Id)}>
            <Button danger icon={<DeleteOutlined />} size="small" />
          </Popconfirm>
        </Space>
      ),
    },
  ];

  return (
    <>
      <Button type="primary" icon={<PlusOutlined />} onClick={openNew} style={{ marginBottom: 16 }}>
        Regel hinzufügen
      </Button>
      <Table dataSource={data} columns={columns} loading={loading} rowKey="Id" size="small" pagination={false} />

      <Modal
        title={isNew ? 'Neue Postprocessing-Regel' : 'Regel bearbeiten'}
        open={!!editing}
        onOk={handleSave}
        onCancel={() => setEditing(null)}
        width={900}
        styles={{ body: { maxHeight: '70vh', overflowY: 'auto' } }}
      >
        <Form form={form} layout="vertical">
          <Space style={{ width: '100%' }}>
            <Form.Item name="Name" label="Name" rules={[{ required: true }]} style={{ minWidth: 300 }}>
              <Input />
            </Form.Item>
            <Form.Item name="Order" label="Reihenfolge"><InputNumber min={1} /></Form.Item>
            <Form.Item name="IsActive" label="Aktiv" valuePropName="checked"><Switch /></Form.Item>
            <Form.Item name="NoFurther" label="Stop nach Treffer" valuePropName="checked"><Switch /></Form.Item>
          </Space>
        </Form>

        <Divider>Filter</Divider>
        <FilterBuilder
          value={filterJson}
          onChange={setFilterJson}
          tags={tags}
          docTypes={docTypes}
          correspondents={correspondents}
          customFields={customFields}
        />

        {editing && !isNew && (
          <>
            <Divider />
            <ActionEditor
              ppId={editing.Id}
              tags={tags}
              customFields={customFields}
              exportTargets={exportTargets}
            />
          </>
        )}
      </Modal>
    </>
  );
}

// ═══════════════════════════════════════════════════════════════════
// Export-Ziele Tab
// ═══════════════════════════════════════════════════════════════════

function ExportTargetsTab() {
  const [data, setData] = useState<SettingExportTarget[]>([]);
  const [loading, setLoading] = useState(true);
  const [editing, setEditing] = useState<SettingExportTarget | null>(null);
  const [isNew, setIsNew] = useState(false);
  const [form] = Form.useForm();
  const [testing, setTesting] = useState<number | null>(null);

  const load = useCallback(async () => {
    setLoading(true);
    try { setData(await settingsApi.getExportTargets()); }
    finally { setLoading(false); }
  }, []);

  useEffect(() => { load(); }, [load]);

  const openNew = () => {
    setIsNew(true);
    form.resetFields();
    form.setFieldsValue({ Protocol: 'ftp', IsActive: true });
    setEditing({} as any);
  };

  const openEdit = (t: SettingExportTarget) => {
    setIsNew(false);
    form.setFieldsValue(t);
    setEditing(t);
  };

  const handleSave = async () => {
    const values = await form.validateFields();
    if (isNew) {
      await settingsApi.createExportTarget(values);
      message.success('Export-Ziel erstellt');
    } else if (editing) {
      await settingsApi.updateExportTarget(editing.Id, values);
      message.success('Gespeichert');
    }
    setEditing(null);
    load();
  };

  const handleDelete = async (id: number) => {
    await settingsApi.deleteExportTarget(id);
    message.success('Gelöscht');
    load();
  };

  const handleTest = async (id: number) => {
    setTesting(id);
    try {
      const result = await settingsApi.testExportTarget(id);
      if (result.success) {
        message.success(result.message);
      } else {
        message.error(result.message);
      }
    } catch {
      message.error('Verbindungstest fehlgeschlagen');
    } finally {
      setTesting(null);
    }
  };

  const columns: ColumnsType<SettingExportTarget> = [
    { title: 'Name', dataIndex: 'Name', key: 'name' },
    { title: 'Protokoll', dataIndex: 'Protocol', key: 'protocol', render: v => <Tag>{v.toUpperCase()}</Tag> },
    { title: 'Host', dataIndex: 'Host', key: 'host' },
    { title: 'Pfad', dataIndex: 'RemotePath', key: 'path', ellipsis: true },
    { title: 'Aktiv', key: 'active', width: 60, render: (_, r) => <Switch size="small" checked={r.IsActive} disabled /> },
    {
      title: '', key: 'actions', width: 160,
      render: (_, rec) => (
        <Space>
          <Button size="small" loading={testing === rec.Id} onClick={() => handleTest(rec.Id)}>
            Test
          </Button>
          <Button icon={<EditOutlined />} size="small" onClick={() => openEdit(rec)} />
          <Popconfirm title="Löschen?" onConfirm={() => handleDelete(rec.Id)}>
            <Button danger icon={<DeleteOutlined />} size="small" />
          </Popconfirm>
        </Space>
      ),
    },
  ];

  return (
    <>
      <Button type="primary" icon={<PlusOutlined />} onClick={openNew} style={{ marginBottom: 16 }}>
        Export-Ziel hinzufügen
      </Button>
      <Table dataSource={data} columns={columns} loading={loading} rowKey="Id" size="small" pagination={false} />

      <Modal title={isNew ? 'Neues Export-Ziel' : 'Export-Ziel bearbeiten'} open={!!editing} onOk={handleSave} onCancel={() => setEditing(null)}>
        <Form form={form} layout="vertical">
          <Form.Item name="Name" label="Name" rules={[{ required: true }]}><Input /></Form.Item>
          <Form.Item name="Protocol" label="Protokoll" rules={[{ required: true }]}>
            <Select>
              <Select.Option value="ftp">FTP</Select.Option>
              <Select.Option value="webdav">WebDAV</Select.Option>
            </Select>
          </Form.Item>
          <Form.Item name="Host" label="Host" rules={[{ required: true }]}><Input /></Form.Item>
          <Form.Item name="Port" label="Port"><InputNumber style={{ width: '100%' }} /></Form.Item>
          <Form.Item name="Username" label="Benutzername"><Input /></Form.Item>
          <Form.Item name="Password" label="Passwort"><Input.Password /></Form.Item>
          <Form.Item name="RemotePath" label="Remote-Pfad"><Input /></Form.Item>
          <Form.Item name="IsActive" label="Aktiv" valuePropName="checked"><Switch /></Form.Item>
        </Form>
      </Modal>
    </>
  );
}

// ═══════════════════════════════════════════════════════════════════
// Postprocessing Logs Tab
// ═══════════════════════════════════════════════════════════════════

function PostprocessingLogsTab() {
  const [data, setData] = useState<SettingPostprocessingLog[]>([]);
  const [total, setTotal] = useState(0);
  const [loading, setLoading] = useState(true);
  const [page, setPage] = useState(1);
  const pageSize = 50;

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const result = await settingsApi.getPostprocessingLogs(pageSize, (page - 1) * pageSize);
      setData(result.data);
      setTotal(result.total);
    } finally { setLoading(false); }
  }, [page]);

  useEffect(() => { load(); }, [load]);

  const columns: ColumnsType<SettingPostprocessingLog> = [
    { title: 'Zeitpunkt', dataIndex: 'CreatedAt', key: 'time', width: 180, render: v => new Date(v).toLocaleString('de-DE') },
    { title: 'Dokument', dataIndex: 'DocumentId', key: 'doc', width: 100 },
    { title: 'Regel', dataIndex: 'PostprocessingId', key: 'rule', width: 80 },
    { title: 'Aktion', dataIndex: 'ActionId', key: 'action', width: 80, render: v => v || '—' },
    {
      title: 'Status', dataIndex: 'Status', key: 'status', width: 100,
      render: (v: string) => (
        <Badge status={v === 'success' ? 'success' : v === 'error' ? 'error' : 'default'} text={v} />
      ),
    },
    { title: 'Nachricht', dataIndex: 'Message', key: 'msg', ellipsis: true },
  ];

  return (
    <Table
      dataSource={data}
      columns={columns}
      loading={loading}
      rowKey="Id"
      size="small"
      pagination={{
        current: page,
        total,
        pageSize,
        onChange: setPage,
        showTotal: t => `${t} Einträge`,
      }}
    />
  );
}

// ═══════════════════════════════════════════════════════════════════
// API Keys Tab
// ═══════════════════════════════════════════════════════════════════

function ApiKeysTab() {
  const [data, setData] = useState<ApiKey[]>([]);
  const [loading, setLoading] = useState(true);
  const [createModalOpen, setCreateModalOpen] = useState(false);
  const [successModalOpen, setSuccessModalOpen] = useState(false);
  const [newKey, setNewKey] = useState<string | null>(null);
  const [form] = Form.useForm();

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const keys = await apiKeysApi.getApiKeys();
      setData(keys);
    } catch (err) {
      console.error('Error loading API keys:', err);
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => { load(); }, [load]);

  const handleCreate = async () => {
    const values = await form.validateFields();
    try {
      const result = await apiKeysApi.createApiKey(values.name);
      setNewKey(result.plainKey);
      setCreateModalOpen(false);
      setSuccessModalOpen(true);
      form.resetFields();
      load();
    } catch (err) {
      message.error('Fehler beim Erstellen des API-Keys');
    }
  };

  const handleDelete = async (id: string) => {
    try {
      await apiKeysApi.deleteApiKey(id);
      message.success('API-Key gelöscht');
      load();
    } catch (err) {
      message.error('Fehler beim Löschen des API-Keys');
    }
  };

  const copyToClipboard = (text: string) => {
    navigator.clipboard.writeText(text);
    message.success('In die Zwischenablage kopiert');
  };

  const columns: ColumnsType<ApiKey> = [
    { title: 'Name', dataIndex: 'name', key: 'name' },
    { title: 'Präfix', dataIndex: 'keyPrefix', key: 'prefix', render: (v) => <Tag>{v}</Tag> },
    { 
      title: 'Erstellt am', 
      dataIndex: 'createdAt', 
      key: 'createdAt',
      render: (v) => dayjs(v).format('DD.MM.YYYY HH:mm')
    },
    { 
      title: 'Zuletzt genutzt', 
      dataIndex: 'lastUsedAt', 
      key: 'lastUsedAt',
      render: (v) => v ? dayjs(v).format('DD.MM.YYYY HH:mm') : 'Nie'
    },
    {
      title: '',
      key: 'actions',
      width: 80,
      render: (_, record) => (
        <Popconfirm title="API-Key wirklich löschen? Er wird sofort ungültig." onConfirm={() => handleDelete(record.id)}>
          <Button danger icon={<DeleteOutlined />} size="small" />
        </Popconfirm>
      ),
    },
  ];

  return (
    <>
      <div style={{ marginBottom: 16 }}>
        <Title level={4}>API Keys</Title>
        <Typography.Paragraph type="secondary">
          Hier kannst du API-Keys verwalten, um externe Dienste anzubinden oder Funktionen über spezialisierte URLs aufzurufen.
        </Typography.Paragraph>
        <Button type="primary" icon={<PlusOutlined />} onClick={() => setCreateModalOpen(true)}>
          Neuen API-Key erstellen
        </Button>
      </div>

      <Table dataSource={data} columns={columns} loading={loading} rowKey="id" size="small" pagination={false} />

      <Modal 
        title="Neuen API-Key erstellen" 
        open={createModalOpen} 
        onOk={handleCreate} 
        onCancel={() => setCreateModalOpen(false)}
      >
        <Form form={form} layout="vertical">
          <Form.Item 
            name="name" 
            label="Anzeigename (z.B. Scanner-Dienst)" 
            rules={[{ required: true, message: 'Bitte gib einen Namen an' }]}
          >
            <Input placeholder="Welchen Zweck hat dieser Key?" />
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title="API-Key erfolgreich erstellt"
        open={successModalOpen}
        footer={[
          <Button key="close" type="primary" onClick={() => setSuccessModalOpen(false)}>
            Ich habe den Key kopiert
          </Button>
        ]}
        closable={false}
        maskClosable={false}
      >
        <Typography.Paragraph type="danger">
          <strong>Wichtig:</strong> Kopiere den API-Key jetzt. Er wird aus Sicherheitsgründen **nie wieder** im Klartext angezeigt!
        </Typography.Paragraph>
        <div style={{ 
          background: '#f5f5f5', 
          padding: '12px', 
          borderRadius: '4px', 
          display: 'flex', 
          justifyContent: 'space-between',
          alignItems: 'center',
          fontFamily: 'monospace',
          border: '1px solid #d9d9d9'
        }}>
          <span>{newKey}</span>
          <Button 
            icon={<CopyOutlined />} 
            onClick={() => newKey && copyToClipboard(newKey)}
          >
            Kopieren
          </Button>
        </div>
      </Modal>
    </>
  );
}

// ═══════════════════════════════════════════════════════════════════
// Correspondents Tab
// ═══════════════════════════════════════════════════════════════════

function CorrespondentsTab() {
  const [data, setData] = useState<any[]>([]);
  const [loading, setLoading] = useState(true);
  const [total, setTotal] = useState(0);
  const [currentPage, setCurrentPage] = useState(1);
  const [pageSize, setPageSize] = useState(50);
  const [searchText, setSearchText] = useState('');
  const [createModalOpen, setCreateModalOpen] = useState(false);
  const [syncLoading, setSyncLoading] = useState(false);
  const [conflicts, setConflicts] = useState<SyncConflict[]>([]);
  const [conflictsModalOpen, setConflictsModalOpen] = useState(false);
  const [conflictSelections, setConflictSelections] = useState<Record<number, number>>({});
  const [mergeLoading, setMergeLoading] = useState(false);
  const [form] = Form.useForm();

  const load = useCallback(async (page: number, size: number, search?: string) => {
    setLoading(true);
    try {
      const result = await settingsApi.getCorrespondents(page, size, search);
      setData(result.data);
      setTotal(result.total);
    } catch (err) {
      message.error('Fehler beim Laden der Korrespondenten');
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    load(currentPage, pageSize, searchText);
  }, [currentPage, pageSize, searchText, load]);

  const handleCreate = async () => {
    const values = await form.validateFields();
    try {
      await settingsApi.createCorrespondent({ name: values.name });
      message.success('Korrespondent erstellt');
      setCreateModalOpen(false);
      form.resetFields();
      load(currentPage, pageSize, searchText);
    } catch (err) {
      message.error('Fehler beim Erstellen des Korrespondenten');
    }
  };

  const handleSync = async () => {
    setSyncLoading(true);
    try {
      const result = await agrarmonitorApi.syncCorrespondents();
      const parts: string[] = [
        `${result.matched} zugeordnet`,
        `${result.unmatched} ohne Treffer`,
      ];
      if (result.autoMerged > 0) parts.push(`${result.autoMerged} automatisch bereinigt`);
      message.success(`Abgleich abgeschlossen: ${parts.join(', ')} (${result.total} gesamt)`);
      load(currentPage, pageSize, searchText);
      if (result.conflicts.length > 0) {
        setConflicts(result.conflicts);
        setConflictSelections(
          Object.fromEntries(result.conflicts.map(c => [c.agrarmonitorId, c.correspondents[0].id]))
        );
        setConflictsModalOpen(true);
      }
    } catch (err) {
      message.error('Fehler beim Agrarmonitor-Abgleich');
    } finally {
      setSyncLoading(false);
    }
  };

  const handleMergeConflicts = async () => {
    setMergeLoading(true);
    try {
      for (const conflict of conflicts) {
        const keepId = conflictSelections[conflict.agrarmonitorId];
        if (keepId === undefined) continue;
        const deleteIds = conflict.correspondents.map(c => c.id).filter(id => id !== keepId);
        for (const deleteId of deleteIds) {
          await agrarmonitorApi.mergeCorrespondents(keepId, deleteId);
        }
      }
      message.success(`${conflicts.length} Konflikt(e) aufgelöst`);
      setConflictsModalOpen(false);
      setConflicts([]);
      load(currentPage, pageSize, searchText);
    } catch (err) {
      message.error('Fehler beim Zusammenführen');
    } finally {
      setMergeLoading(false);
    }
  };

  const updateAgrarmonitorId = async (id: number, val: number | null) => {
    try {
      await settingsApi.updateCorrespondentSetting(id, val);
      message.success('ID aktualisiert');
      // No full reload needed to keep focus, but sync might be better. 
      // We update local state to reflect change immediately without glitchy reload
      setData(prev => prev.map(item => item.id === id ? { ...item, agrarmonitorId: val } : item));
    } catch (err) {
      message.error('Fehler beim Aktualisieren der ID');
    }
  };

  const columns: ColumnsType<any> = [
    { title: 'Name', dataIndex: 'name', key: 'name', sorter: false }, // Sorting is tricky with server-side pagination unless implemented in backend
    { title: 'Paperless ID', dataIndex: 'id', key: 'id', width: 120 },
    { 
      title: 'Agrarmonitor ID', 
      dataIndex: 'agrarmonitorId', 
      key: 'agrarmonitorId',
      width: 200,
      render: (val, record) => (
        <InputNumber 
          value={val} 
          placeholder="AM ID" 
          style={{ width: '100%' }} 
          onBlur={(e) => {
            const v = e.target.value ? parseInt(e.target.value.replace(/\D/g, ''), 10) : null;
            if (v !== val) updateAgrarmonitorId(record.id, v);
          }}
          controls={false}
        />
      )
    },
    { 
      title: 'Dokumente', 
      dataIndex: 'document_count', 
      key: 'docCount', 
      width: 100,
      render: (v) => <Badge count={v} showZero color="#108ee9" />
    },
  ];

  return (
    <>
      <div style={{ marginBottom: 16 }}>
        <Title level={4}>Korrespondenten</Title>
        <Typography.Paragraph type="secondary">
          Hier kannst du Korrespondenten verwalten und deren Agrarmonitor-ID hinterlegen. 
          Neue Korrespondenten werden direkt in Paperless erstellt.
        </Typography.Paragraph>
        <Space style={{ marginBottom: 16, display: 'flex', justifyContent: 'space-between' }}>
          <Input.Search 
            placeholder="Suchen..." 
            allowClear
            onSearch={(v) => { setSearchText(v); setCurrentPage(1); }}
            style={{ width: 300 }}
          />
          <Space>
            <Button icon={<GlobalOutlined />} loading={syncLoading} onClick={handleSync}>
              Agrarmonitor-Abgleich
            </Button>
            <Button type="primary" icon={<PlusOutlined />} onClick={() => setCreateModalOpen(true)}>
              Neuen Korrespondenten anlegen
            </Button>
          </Space>
        </Space>
      </div>

      <Table 
        dataSource={data} 
        columns={columns} 
        loading={loading} 
        rowKey="id" 
        size="small" 
        pagination={{ 
          current: currentPage,
          pageSize: pageSize,
          total: total,
          showSizeChanger: true,
          onChange: (page, size) => {
            setCurrentPage(page);
            setPageSize(size);
          }
        }} 
      />

      <Modal
        title="Neuen Korrespondenten anlegen"
        open={createModalOpen}
        onOk={handleCreate}
        onCancel={() => setCreateModalOpen(false)}
      >
        <Form form={form} layout="vertical">
          <Form.Item
            name="name"
            label="Name des Korrespondenten"
            rules={[{ required: true, message: 'Bitte gib einen Namen an' }]}
          >
            <Input placeholder="Vollständiger Name" />
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title="Doppelte Korrespondenten – Namenskonflikt"
        open={conflictsModalOpen}
        onOk={handleMergeConflicts}
        onCancel={() => setConflictsModalOpen(false)}
        okText="Zusammenführen"
        cancelText="Abbrechen"
        confirmLoading={mergeLoading}
        width={560}
      >
        <Alert
          type="warning"
          style={{ marginBottom: 16 }}
          message="Mehrere Korrespondenten haben dieselbe Agrarmonitor-ID, aber unterschiedliche Namen. Wähle jeweils den Namen, der behalten werden soll. Alle Dokumente des anderen werden übertragen, der leere Eintrag wird gelöscht."
        />
        {conflicts.map((conflict, idx) => (
          <div key={conflict.agrarmonitorId} style={{ marginBottom: idx < conflicts.length - 1 ? 24 : 0 }}>
            <div style={{ marginBottom: 8, color: '#888', fontSize: 12 }}>
              Agrarmonitor-ID: {conflict.agrarmonitorId}
            </div>
            <Radio.Group
              value={conflictSelections[conflict.agrarmonitorId]}
              onChange={e => setConflictSelections(prev => ({ ...prev, [conflict.agrarmonitorId]: e.target.value as number }))}
            >
              <Space direction="vertical">
                {conflict.correspondents.map(c => (
                  <Radio key={c.id} value={c.id}>
                    <strong>{c.name}</strong>
                    <span style={{ marginLeft: 8, color: '#888' }}>({c.documentCount} Dokumente)</span>
                  </Radio>
                ))}
              </Space>
            </Radio.Group>
          </div>
        ))}
      </Modal>
    </>
  );
}

// ═══════════════════════════════════════════════════════════════════
// Inbox-Aktionen pro Barcode-Vorlage (Sub-Editor)
// ═══════════════════════════════════════════════════════════════════

const VARIABLE_HINT =
  'Platzhalter: {datum} {jahr} {monat} {tag} {zeitstempel}, {barcode} (gesamter Barcode-Wert), {barcode.<Gruppe>} für Named Capture Groups der Regex (z.B. (?<Gruppe>\\d+))';

function InboxActionsForTemplateEditor({ templateId }: { templateId: number }) {
  const [actions, setActions] = useState<InboxAction[]>([]);
  const [loading, setLoading] = useState(true);
  const [editing, setEditing] = useState<InboxAction | null>(null);
  const [isNew, setIsNew] = useState(false);
  const [actionType, setActionType] = useState<InboxActionType>('MAIL');
  const [tags, setTags] = useState<PaperlessTag[]>([]);
  const [docTypes, setDocTypes] = useState<PaperlessDocType[]>([]);
  const [correspondents, setCorrespondents] = useState<PaperlessCorrespondent[]>([]);
  const [customFields, setCustomFields] = useState<PaperlessCustomField[]>([]);
  const [users, setUsers] = useState<{ id: number; username: string }[]>([]);
  const [exportTargets, setExportTargets] = useState<SettingExportTarget[]>([]);
  const [form] = Form.useForm();

  const load = useCallback(async () => {
    setLoading(true);
    try {
      setActions(await settingsApi.listInboxActionsForTemplate(templateId));
    } finally {
      setLoading(false);
    }
  }, [templateId]);

  useEffect(() => { load(); }, [load]);

  useEffect(() => {
    Promise.all([
      paperlessApi.getTags().catch(() => []),
      paperlessApi.getDocumentTypes().catch(() => []),
      paperlessApi.getCorrespondents().catch(() => []),
      paperlessApi.getCustomFields().catch(() => []),
      paperlessApi.getUsers().catch(() => []),
      settingsApi.getExportTargets().catch(() => []),
    ]).then(([t, dt, c, cf, u, et]) => {
      setTags(t);
      setDocTypes(dt);
      setCorrespondents(c);
      setCustomFields(cf);
      setUsers(u as { id: number; username: string }[]);
      setExportTargets(et);
    });
  }, []);

  const openNew = () => {
    setIsNew(true);
    setEditing({} as InboxAction);
    setActionType('MAIL');
    form.resetFields();
    form.setFieldsValue({ ActionType: 'MAIL', IsActive: true, Order: actions.length + 1 });
  };

  const openEdit = (a: InboxAction) => {
    setIsNew(false);
    setEditing(a);
    setActionType(a.ActionType);
    form.setFieldsValue({ ActionType: a.ActionType, IsActive: a.IsActive, Order: a.Order, ...a.Content });
  };

  const buildContent = (values: any): Record<string, any> => {
    const { ActionType: _, IsActive: __, Order: ___, ...rest } = values;
    return rest;
  };

  const handleDelete = async (id: number) => {
    await settingsApi.deleteInboxAction(id);
    message.success('Gelöscht');
    load();
  };

  useEffect(() => {
    if (!editing) return;
    if (isNew) { form.setFieldsValue({ customFieldsList: [] }); return; }
    const cf = (editing.Content?.customFields ?? {}) as Record<string, string>;
    form.setFieldsValue({
      customFieldsList: Object.entries(cf).map(([fieldId, value]) => ({ fieldId: Number(fieldId), value })),
    });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [editing, isNew]);

  const handleSaveWrapped = async () => {
    const values = await form.validateFields();
    if (values.ActionType === 'PAPERLESS' && Array.isArray(values.customFieldsList)) {
      const obj: Record<string, string> = {};
      for (const row of values.customFieldsList) {
        if (row?.fieldId !== undefined && row?.fieldId !== null) obj[String(row.fieldId)] = row.value ?? '';
      }
      values.customFields = obj;
      delete values.customFieldsList;
    }
    const payload = {
      ActionType: values.ActionType as InboxActionType,
      Content: buildContent(values),
      Order: values.Order,
      IsActive: values.IsActive,
    };
    try {
      if (isNew) {
        await settingsApi.createInboxActionForTemplate(templateId, payload);
        message.success('Aktion erstellt');
      } else if (editing) {
        await settingsApi.updateInboxAction(editing.Id, payload);
        message.success('Aktion gespeichert');
      }
      setEditing(null);
      load();
    } catch (err: any) {
      message.error(err?.response?.data?.message ?? 'Speichern fehlgeschlagen');
    }
  };

  const renderContentFields = () => {
    switch (actionType) {
      case 'MAIL':
        return (
          <>
            <Form.Item name="to" label="Empfänger" rules={[{ required: true }]}>
              <Input placeholder="empfaenger@example.com" />
            </Form.Item>
            <Form.Item name="subject" label="Betreff" tooltip={VARIABLE_HINT}>
              <Input placeholder="z.B. Beleg {Beleg}" />
            </Form.Item>
            <Form.Item name="body" label="Text" tooltip={VARIABLE_HINT}>
              <Input.TextArea rows={3} />
            </Form.Item>
            <Form.Item name="filenameTemplate" label="Dateiname (Anhang)" tooltip={VARIABLE_HINT}>
              <Input placeholder="z.B. {datum}_{Beleg}" />
            </Form.Item>
          </>
        );
      case 'EXPORT':
        return (
          <>
            <Form.Item name="exportTargetId" label="Export-Ziel" rules={[{ required: true }]}>
              <Select>
                {exportTargets.filter((t) => t.IsActive).map((t) => (
                  <Select.Option key={t.Id} value={t.Id}>{t.Name} ({t.Protocol})</Select.Option>
                ))}
              </Select>
            </Form.Item>
            <Form.Item name="filenameTemplate" label="Dateiname" tooltip={VARIABLE_HINT}>
              <Input placeholder="z.B. {datum}_{Beleg}" />
            </Form.Item>
          </>
        );
      case 'PAPERLESS':
        return (
          <>
            <Form.Item
              name="interneBelegnummer"
              label="Interne Belegnummer"
              required
              tooltip={VARIABLE_HINT}
              extra="Pflichtfeld. Wird zur Duplikatprüfung verwendet."
            >
              <Input placeholder="{barcode} oder {barcode.nr}" />
            </Form.Item>
            <Form.Item
              name="asn"
              label="ASN"
              tooltip={VARIABLE_HINT}
              extra="Optional. Archivnummer (archive_serial_number) des Dokuments. Überschreibt die aus der Internen Belegnummer abgeleitete ASN."
            >
              <Input placeholder="{barcode.asn} oder feste Zahl" />
            </Form.Item>
            <Form.Item
              name="eingangsdatum"
              label="Eingangsdatum"
              tooltip={VARIABLE_HINT}
              extra="Optional. Datum des Dokumenteneingangs (YYYY-MM-DD oder TT.MM.JJJJ). Leer = heutiges Datum."
            >
              <Input placeholder="{barcode.datum} oder 23.04.2026" />
            </Form.Item>
            <Form.Item name="title" label="Titel" tooltip={VARIABLE_HINT}>
              <Input placeholder="z.B. Beleg {barcode} vom {datum}" />
            </Form.Item>
            <Form.Item name="documentType" label="Dokumenttyp">
              <Select allowClear showSearch optionFilterProp="children">
                {docTypes.map((dt) => (
                  <Select.Option key={dt.id} value={dt.id}>{dt.name}</Select.Option>
                ))}
              </Select>
            </Form.Item>
            <Form.Item name="correspondent" label="Korrespondent">
              <Select allowClear showSearch optionFilterProp="children">
                {correspondents.map((c) => (
                  <Select.Option key={c.id} value={c.id}>{c.name}</Select.Option>
                ))}
              </Select>
            </Form.Item>
            <Form.Item name="owner" label="Besitzer">
              <Select allowClear showSearch optionFilterProp="children">
                {users.map((u) => (
                  <Select.Option key={u.id} value={u.id}>{u.username}</Select.Option>
                ))}
              </Select>
            </Form.Item>
            <Form.Item name="tags" label="Tags">
              <Select mode="multiple" allowClear showSearch optionFilterProp="children">
                {tags.map((t) => (
                  <Select.Option key={t.id} value={t.id}>{t.name}</Select.Option>
                ))}
              </Select>
            </Form.Item>
            <Form.Item label="Custom Fields" tooltip={VARIABLE_HINT}>
              <Form.List name="customFieldsList">
                {(fields, { add, remove }) => (
                  <>
                    {fields.map(({ key, name, ...rest }) => (
                      <Space key={key} align="baseline" style={{ display: 'flex', marginBottom: 4 }}>
                        <Form.Item {...rest} name={[name, 'fieldId']} rules={[{ required: true }]} noStyle>
                          <Select style={{ width: 200 }} placeholder="Feld" showSearch optionFilterProp="children">
                            {customFields.map((cf) => (
                              <Select.Option key={cf.id} value={cf.id}>{cf.name}</Select.Option>
                            ))}
                          </Select>
                        </Form.Item>
                        <Form.Item {...rest} name={[name, 'value']} noStyle>
                          <Input placeholder="Wert / Template" style={{ width: 260 }} />
                        </Form.Item>
                        <Button icon={<MinusCircleOutlined />} onClick={() => remove(name)} />
                      </Space>
                    ))}
                    <Button type="dashed" onClick={() => add()} icon={<PlusOutlined />}>Custom Field</Button>
                  </>
                )}
              </Form.List>
            </Form.Item>
          </>
        );
      default:
        return null;
    }
  };

  const columns: ColumnsType<InboxAction> = [
    { title: '#', dataIndex: 'Order', key: 'order', width: 60 },
    { title: 'Typ', key: 'type', render: (_, r) => <Tag color="blue">{INBOX_ACTION_LABELS[r.ActionType]}</Tag> },
    { title: 'Aktiv', key: 'active', width: 70, render: (_, r) => <Switch size="small" checked={r.IsActive} disabled /> },
    {
      title: '', key: 'edit', width: 110,
      render: (_, r) => (
        <Space>
          <Button size="small" icon={<EditOutlined />} onClick={() => openEdit(r)} />
          <Popconfirm title="Löschen?" onConfirm={() => handleDelete(r.Id)}>
            <Button danger size="small" icon={<DeleteOutlined />} />
          </Popconfirm>
        </Space>
      ),
    },
  ];

  return (
    <div style={{ marginTop: 16 }}>
      <Space style={{ marginBottom: 8 }}>
        <h4 style={{ margin: 0 }}>Weiterverarbeitungs-Aktionen</h4>
        <Button type="dashed" size="small" icon={<PlusOutlined />} onClick={openNew}>Aktion hinzufügen</Button>
      </Space>
      <Table<InboxAction> rowKey="Id" columns={columns} dataSource={actions} loading={loading} pagination={false} size="small" />

      <Modal
        title={isNew ? 'Neue Aktion' : 'Aktion bearbeiten'}
        open={!!editing}
        onOk={handleSaveWrapped}
        onCancel={() => setEditing(null)}
        okText="Speichern"
        cancelText="Abbrechen"
        width={680}
      >
        <Form form={form} layout="vertical">
          <Space style={{ width: '100%' }}>
            <Form.Item name="ActionType" label="Aktionstyp" rules={[{ required: true }]}>
              <Select style={{ width: 220 }} onChange={(v) => setActionType(v)}>
                {(Object.keys(INBOX_ACTION_LABELS) as InboxActionType[]).map((k) => (
                  <Select.Option key={k} value={k}>{INBOX_ACTION_LABELS[k]}</Select.Option>
                ))}
              </Select>
            </Form.Item>
            <Form.Item name="Order" label="Reihenfolge"><InputNumber min={1} /></Form.Item>
            <Form.Item name="IsActive" label="Aktiv" valuePropName="checked"><Switch /></Form.Item>
          </Space>
          <Divider />
          {renderContentFields()}
        </Form>
      </Modal>
    </div>
  );
}

// ═══════════════════════════════════════════════════════════════════
// Eingangsdokumentarten Tab (ehemals Barcode-Vorlagen)
// ═══════════════════════════════════════════════════════════════════

function LabelElementRow({ form, listName, remove }: { form: FormInstance; listName: number; remove: (n: number) => void }) {
  const type = Form.useWatch(['LabelLayout', listName, 'type'], form);

  return (
    <Card
      size="small"
      style={{ marginBottom: 8 }}
      extra={<Button size="small" danger icon={<DeleteOutlined />} onClick={() => remove(listName)} />}
    >
      <Form.Item name={[listName, 'type']} label="Typ" style={{ marginBottom: 8 }}>
        <Select style={{ width: 120 }} options={[
          { value: 'text', label: 'Text' },
          { value: 'qr', label: 'QR-Code' },
          { value: 'line', label: 'Linie' },
        ]} />
      </Form.Item>

      {type === 'text' && (
        <Row gutter={8}>
          <Col span={4}><Form.Item name={[listName, 'x']} label="X (mm)"><InputNumber style={{ width: '100%' }} /></Form.Item></Col>
          <Col span={4}><Form.Item name={[listName, 'y']} label="Y (mm)"><InputNumber style={{ width: '100%' }} /></Form.Item></Col>
          <Col span={4}><Form.Item name={[listName, 'fontSize']} label="Schrift (mm)"><InputNumber min={0.5} step={0.5} style={{ width: '100%' }} /></Form.Item></Col>
          <Col span={4}><Form.Item name={[listName, 'maxWidth']} label="Max. B. (mm)"><InputNumber style={{ width: '100%' }} /></Form.Item></Col>
          <Col span={4}><Form.Item name={[listName, 'bold']} label="Fett" valuePropName="checked"><Checkbox /></Form.Item></Col>
          <Col span={4}><Form.Item name={[listName, 'align']} label="Ausrichtung">
            <Select allowClear style={{ width: '100%' }} options={[
              { value: 'left', label: 'Links' },
              { value: 'center', label: 'Mitte' },
              { value: 'right', label: 'Rechts' },
            ]} />
          </Form.Item></Col>
          <Col span={24}><Form.Item name={[listName, 'content']} label="Inhalt"><Input placeholder="{nummer} oder {datum}" /></Form.Item></Col>
        </Row>
      )}

      {type === 'qr' && (
        <Row gutter={8}>
          <Col span={4}><Form.Item name={[listName, 'x']} label="X (mm)"><InputNumber style={{ width: '100%' }} /></Form.Item></Col>
          <Col span={4}><Form.Item name={[listName, 'y']} label="Y (mm)"><InputNumber style={{ width: '100%' }} /></Form.Item></Col>
          <Col span={4}><Form.Item name={[listName, 'sizeMm']} label="Größe (mm)"><InputNumber style={{ width: '100%' }} /></Form.Item></Col>
          <Col span={12}><Form.Item name={[listName, 'content']} label="Inhalt"><Input placeholder="{number}" /></Form.Item></Col>
        </Row>
      )}

      {type === 'line' && (
        <Row gutter={8}>
          <Col span={4}><Form.Item name={[listName, 'x1']} label="X1 (mm)"><InputNumber style={{ width: '100%' }} /></Form.Item></Col>
          <Col span={4}><Form.Item name={[listName, 'y1']} label="Y1 (mm)"><InputNumber style={{ width: '100%' }} /></Form.Item></Col>
          <Col span={4}><Form.Item name={[listName, 'x2']} label="X2 (mm)"><InputNumber style={{ width: '100%' }} /></Form.Item></Col>
          <Col span={4}><Form.Item name={[listName, 'y2']} label="Y2 (mm)"><InputNumber style={{ width: '100%' }} /></Form.Item></Col>
          <Col span={4}><Form.Item name={[listName, 'lineWidth']} label="Stärke (mm)"><InputNumber step={0.1} style={{ width: '100%' }} /></Form.Item></Col>
        </Row>
      )}
    </Card>
  );
}

function BarcodeTemplatesTab() {
  const [data, setData] = useState<BarcodeTemplate[]>([]);
  const [loading, setLoading] = useState(true);
  const [modalOpen, setModalOpen] = useState(false);
  const [editing, setEditing] = useState<BarcodeTemplate | null>(null);
  const [isNew, setIsNew] = useState(false);
  const [testValue, setTestValue] = useState('');
  const [testPrinting, setTestPrinting] = useState(false);
  const [previewUrl, setPreviewUrl] = useState<string | null>(null);
  const [form] = Form.useForm();

  const load = useCallback(async () => {
    setLoading(true);
    try {
      setData(await barcodeTemplatesApi.list());
    } catch {
      message.error('Vorlagen konnten nicht geladen werden');
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => { load(); }, [load]);

  const openCreate = () => {
    setIsNew(true);
    setEditing(null);
    setTestValue('');
    form.resetFields();
    form.setFieldsValue({
      SplitBefore: false,
      DateinameTemplate: '',
      LabelEnabled: false,
      LabelWidthMm: 57,
      LabelHeightMm: 32,
      LabelInputFields: [],
      LabelLayout: [],
    });
    setModalOpen(true);
  };

  const openEdit = (row: BarcodeTemplate) => {
    setIsNew(false);
    setEditing(row);
    setTestValue('');
    form.setFieldsValue({
      Name: row.Name,
      Regex: row.Regex,
      SplitBefore: row.SplitBefore,
      DateinameTemplate: row.DateinameTemplate ?? '',
      LabelEnabled: row.LabelEnabled ?? false,
      LabelWidthMm: row.LabelWidthMm ?? 57,
      LabelHeightMm: row.LabelHeightMm ?? 32,
      LabelInputFields: row.LabelInputFields ?? [],
      LabelGetUrl: row.LabelGetUrl ?? '',
      LabelPrintedUrl: row.LabelPrintedUrl ?? '',
      LabelReleaseUrl: row.LabelReleaseUrl ?? '',
      LabelLayout: row.LabelLayout ?? [],
    });
    setModalOpen(true);
  };

  const handleSave = async () => {
    const values = await form.validateFields();
    try {
      if (editing) {
        await barcodeTemplatesApi.update(editing.Id, values);
        message.success('Eingangsdokumentart aktualisiert');
      } else {
        await barcodeTemplatesApi.create({ ...values, Actions: [] });
        message.success('Eingangsdokumentart angelegt');
      }
      if (isNew) setModalOpen(false);
      load();
    } catch (err: any) {
      message.error(err?.response?.data?.message ?? 'Speichern fehlgeschlagen');
    }
  };

  const handleTestLabel = async () => {
    if (!editing) return;
    setTestPrinting(true);
    try {
      const values = await form.validateFields();
      await barcodeTemplatesApi.update(editing.Id, values);
      const inputFields: LabelInputField[] = values.LabelInputFields ?? [];
      const testFieldValues: Record<string, string> = {};
      const today = new Date().toISOString().slice(0, 10);
      for (const f of inputFields) {
        if (f.type === 'date') testFieldValues[f.name] = today;
        else if (f.type === 'number') testFieldValues[f.name] = '1';
        else testFieldValues[f.name] = 'Test';
      }
      const url = await labelPrintAgentApi.previewLabel(editing.Id, testFieldValues);
      if (previewUrl) URL.revokeObjectURL(previewUrl);
      setPreviewUrl(url);
      load();
    } catch (err: any) {
      message.error(err?.response?.data?.message ?? 'Vorschau fehlgeschlagen');
    } finally {
      setTestPrinting(false);
    }
  };

  const handleDelete = async (id: number) => {
    await barcodeTemplatesApi.remove(id);
    message.success('Vorlage gelöscht');
    load();
  };

  const columns: ColumnsType<BarcodeTemplate> = [
    { title: 'Name', dataIndex: 'Name', key: 'name' },
    {
      title: 'Regex',
      dataIndex: 'Regex',
      key: 'regex',
      render: (v: string) => <code style={{ fontSize: 12 }}>{v}</code>,
    },
    {
      title: 'Trennen',
      dataIndex: 'SplitBefore',
      key: 'splitBefore',
      width: 100,
      render: (v: boolean) =>
        v ? <Tag color="orange">vor Barcode</Tag> : <Typography.Text type="secondary">—</Typography.Text>,
    },
    {
      title: '',
      key: 'edit',
      width: 140,
      render: (_, row) => (
        <Space>
          <Button size="small" icon={<EditOutlined />} onClick={() => openEdit(row)} />
          <Popconfirm title="Vorlage löschen?" onConfirm={() => handleDelete(row.Id)}>
            <Button danger size="small" icon={<DeleteOutlined />} />
          </Popconfirm>
        </Space>
      ),
    },
  ];

  const currentRegex = Form.useWatch('Regex', form);
  let testResult: { valid: boolean; matches: boolean } | null = null;
  if (currentRegex && testValue) {
    try {
      testResult = { valid: true, matches: new RegExp(currentRegex).test(testValue) };
    } catch {
      testResult = { valid: false, matches: false };
    }
  }

  return (
    <>
      <Space style={{ marginBottom: 16 }}>
        <Button type="primary" icon={<PlusOutlined />} onClick={openCreate}>
          Neue Eingangsdokumentart
        </Button>
      </Space>

      <Table<BarcodeTemplate>
        rowKey="Id"
        columns={columns}
        dataSource={data}
        loading={loading}
        pagination={false}
      />

      <Modal
        title={editing ? 'Eingangsdokumentart bearbeiten' : 'Neue Eingangsdokumentart'}
        open={modalOpen}
        onCancel={() => { setModalOpen(false); setEditing(null); }}
        width={720}
        footer={[
          ...(editing && !isNew ? [
            <Button key="test" icon={<PrinterOutlined />} loading={testPrinting} onClick={handleTestLabel}>
              Testetikett erstellen
            </Button>,
          ] : []),
          <Button key="cancel" onClick={() => { setModalOpen(false); setEditing(null); }}>Abbrechen</Button>,
          <Button key="save" type="primary" onClick={handleSave}>Speichern</Button>,
        ]}
      >
        <Form form={form} layout="vertical">
          <Form.Item name="Name" label="Name" rules={[{ required: true, message: 'Name ist erforderlich' }]}>
            <Input placeholder="z. B. Lager-Etikett" />
          </Form.Item>

          <Form.Item
            name="Regex"
            label="Regex"
            rules={[
              { required: true, message: 'Regex ist erforderlich' },
              {
                validator: (_, value) => {
                  if (!value) return Promise.resolve();
                  try { new RegExp(value); return Promise.resolve(); }
                  catch { return Promise.reject(new Error('Ungültige Regex')); }
                },
              },
            ]}
            extra="JavaScript-Syntax, z. B. ^\d{4}-\d{6}-\d{8}$ oder ^AM-\d{8}$"
          >
            <Input placeholder="^\d{4}-\d{6}-\d{8}$" />
          </Form.Item>

          <Form.Item label="Regex testen">
            <Input
              placeholder="Beispiel-Barcode-Inhalt eingeben"
              value={testValue}
              onChange={(e) => setTestValue(e.target.value)}
            />
            {testResult && (
              <div style={{ marginTop: 4, fontSize: 12 }}>
                {!testResult.valid ? (
                  <Tag color="red">Regex ungültig</Tag>
                ) : testResult.matches ? (
                  <Tag color="green">Treffer</Tag>
                ) : (
                  <Tag>Kein Treffer</Tag>
                )}
              </div>
            )}
          </Form.Item>

          <Form.Item name="SplitBefore" valuePropName="checked">
            <Checkbox>Vor diesem Barcode ein neues Dokument starten</Checkbox>
          </Form.Item>

          <Form.Item
            name="DateinameTemplate"
            label="Belegname"
            extra="Platzhalter z. B. {barcode}, {datum}, {barcode.gruppe}. Wird als Standard-Belegname bei Export und E-Mail verwendet."
          >
            <Input placeholder="{barcode}_{datum}" />
          </Form.Item>

          <Divider>Etikett</Divider>

          <Form.Item name="LabelEnabled" valuePropName="checked" label="Etikett-Druck aktivieren">
            <Switch />
          </Form.Item>

          <Form.Item noStyle shouldUpdate={(prev, curr) => prev.LabelEnabled !== curr.LabelEnabled}>
            {({ getFieldValue }) =>
              getFieldValue('LabelEnabled') ? (
                <>
                  <Row gutter={16}>
                    <Col span={8}>
                      <Form.Item name="LabelWidthMm" label="Breite (mm)">
                        <InputNumber min={10} max={300} style={{ width: '100%' }} />
                      </Form.Item>
                    </Col>
                    <Col span={8}>
                      <Form.Item name="LabelHeightMm" label="Höhe (mm)">
                        <InputNumber min={10} max={300} style={{ width: '100%' }} />
                      </Form.Item>
                    </Col>
                  </Row>

                  <Form.Item label="Eingabefelder">
                    <Form.List name="LabelInputFields">
                      {(fields, { add, remove }) => (
                        <>
                          {fields.map(({ key, name, ...rest }) => (
                            <Space key={key} style={{ display: 'flex', marginBottom: 6 }} align="baseline">
                              <Form.Item {...rest} name={[name, 'name']} rules={[{ required: true, message: 'Feldname' }]} noStyle>
                                <Input placeholder="Feldname (z. B. datum)" style={{ width: 160 }} />
                              </Form.Item>
                              <Form.Item {...rest} name={[name, 'label']} noStyle>
                                <Input placeholder="Bezeichnung" style={{ width: 160 }} />
                              </Form.Item>
                              <Form.Item {...rest} name={[name, 'type']} noStyle>
                                <Select style={{ width: 110 }} options={[
                                  { value: 'text', label: 'Text' },
                                  { value: 'number', label: 'Nummer' },
                                  { value: 'date', label: 'Datum' },
                                ]} />
                              </Form.Item>
                              <MinusCircleOutlined onClick={() => remove(name)} />
                            </Space>
                          ))}
                          <Button type="dashed" onClick={() => add({ type: 'text' })} icon={<PlusOutlined />} size="small">
                            Feld hinzufügen
                          </Button>
                        </>
                      )}
                    </Form.List>
                  </Form.Item>

                  <Form.Item noStyle shouldUpdate>
                    {({ getFieldValue: gfv }) => {
                      const inputFields: LabelInputField[] = gfv('LabelInputFields') ?? [];
                      const chips: string[] = [];
                      for (const f of inputFields) {
                        if (!f?.name) continue;
                        chips.push(`{${f.name}}`);
                        if (f.type === 'date') {
                          chips.push(`{${f.name}.year}`, `{${f.name}.month}`, `{${f.name}.day}`);
                        }
                      }
                      const chipsWithNumber = [...chips, '{number}'];
                      return (
                        <>
                          <Form.Item name="LabelGetUrl" label="GET-URL (liefert Nummer)"
                            extra={chips.length > 0 ? `Platzhalter: ${chips.join('  ')}` : undefined}>
                            <Input placeholder="https://example.com/nummer?feld={feldname}" />
                          </Form.Item>
                          <Form.Item name="LabelPrintedUrl" label="PRINTED-URL (nach erfolgreichem Druck)"
                            extra={chipsWithNumber.length > 0 ? `Platzhalter: ${chipsWithNumber.join('  ')}` : undefined}>
                            <Input placeholder="https://example.com/gedruckt?nr={number}" />
                          </Form.Item>
                          <Form.Item name="LabelReleaseUrl" label="RELEASE-URL (bei Druckfehler)"
                            extra={chipsWithNumber.length > 0 ? `Platzhalter: ${chipsWithNumber.join('  ')}` : undefined}>
                            <Input placeholder="https://example.com/freigeben?nr={number}" />
                          </Form.Item>

                          <Form.Item label="Layout-Elemente"
                            extra={chipsWithNumber.length > 0 ? `Platzhalter für Inhalt: ${chipsWithNumber.join('  ')}` : undefined}>
                            <Form.List name="LabelLayout">
                              {(layoutFields, { add: addEl, remove: removeEl }) => (
                                <>
                                  {layoutFields.map(({ key, name: elName }) => (
                                    <LabelElementRow key={key} form={form} listName={elName} remove={removeEl} />
                                  ))}
                                  <Space>
                                    <Button size="small" type="dashed" icon={<PlusOutlined />}
                                      onClick={() => addEl({ type: 'text', x: 0, y: 0, fontSize: 3, content: '', bold: false })}>
                                      Text
                                    </Button>
                                    <Button size="small" type="dashed" icon={<PlusOutlined />}
                                      onClick={() => addEl({ type: 'qr', x: 0, y: 0, sizeMm: 20, content: '' })}>
                                      QR-Code
                                    </Button>
                                    <Button size="small" type="dashed" icon={<PlusOutlined />}
                                      onClick={() => addEl({ type: 'line', x1: 0, y1: 0, x2: 50, y2: 0 })}>
                                      Linie
                                    </Button>
                                  </Space>
                                </>
                              )}
                            </Form.List>
                          </Form.Item>
                        </>
                      );
                    }}
                  </Form.Item>
                </>
              ) : null
            }
          </Form.Item>
        </Form>

        {editing && !isNew && (
          <>
            <Divider />
            <InboxActionsForTemplateEditor templateId={editing.Id} />
          </>
        )}
      </Modal>

      <Modal
        title="Etikett-Vorschau"
        open={!!previewUrl}
        onCancel={() => { URL.revokeObjectURL(previewUrl!); setPreviewUrl(null); }}
        footer={<Button onClick={() => { URL.revokeObjectURL(previewUrl!); setPreviewUrl(null); }}>Schließen</Button>}
        width={520}
      >
        {previewUrl && (
          <div style={{ background: '#e0e0e0', padding: 24, display: 'flex', justifyContent: 'center', borderRadius: 4 }}>
            <img
              src={previewUrl}
              alt="Etikett-Vorschau"
              style={{ maxWidth: '100%', boxShadow: '0 2px 8px rgba(0,0,0,0.3)', display: 'block' }}
            />
          </div>
        )}
      </Modal>
    </>
  );
}


// ═══════════════════════════════════════════════════════════════════
// Agrarmonitor Tab
// ═══════════════════════════════════════════════════════════════════

function AgrarmonitorTab() {
  const [form] = Form.useForm();
  const [pollingForm] = Form.useForm();
  const [loading, setLoading] = useState(false);
  const [registering, setRegistering] = useState(false);
  const [pollingConfigLoading, setPollingConfigLoading] = useState(false);
  const [pollingSaving, setPollingSaving] = useState(false);
  const [pollingRunning, setPollingRunning] = useState(false);
  const [uploadCheckRunning, setUploadCheckRunning] = useState(false);
  const [status, setStatus] = useState<AgrarmonitorStatusData | null>(null);
  const [registerResult, setRegisterResult] = useState<{ success: boolean; message: string } | null>(null);
  const [pollingResult, setPollingResult] = useState<AgrarmonitorPollingResult | null>(null);
  const [uploadCheckResult, setUploadCheckResult] = useState<AgrarmonitorPollingResult | null>(null);
  const [customFields, setCustomFields] = useState<PaperlessCustomField[]>([]);

  const handleLoadStatus = async () => {
    setLoading(true);
    setRegisterResult(null);
    try {
      const data = await agrarmonitorApi.getStatus();
      setStatus(data);
    } catch (err: any) {
      const msg = err?.code === 'ECONNABORTED'
        ? 'Timeout – Backend antwortet nicht rechtzeitig'
        : (err?.response?.data?.message ?? err?.message ?? 'Netzwerkfehler');
      setStatus({ connected: false, registriert: null, freigeschaltet: null, error: msg });
    } finally {
      setLoading(false);
    }
  };

  const handleRegister = async () => {
    const values = await form.validateFields();
    setRegistering(true);
    setRegisterResult(null);
    try {
      const result = await agrarmonitorApi.registerDevice(values.pcName, values.agrarmonitorId);
      setRegisterResult(result);
      if (result.success) {
        message.success('Gerät erfolgreich registriert');
        await handleLoadStatus();
      }
    } catch {
      setRegisterResult({ success: false, message: 'Registrierung fehlgeschlagen' });
    } finally {
      setRegistering(false);
    }
  };

  const handleLoadPollingConfig = useCallback(async () => {
    setPollingConfigLoading(true);
    try {
      const cfg = await agrarmonitorApi.getPollingConfig();
      pollingForm.setFieldsValue(cfg);
    } catch {
      message.error('Polling-Konfiguration konnte nicht geladen werden');
    } finally {
      setPollingConfigLoading(false);
    }
  }, [pollingForm]);

  useEffect(() => {
    handleLoadPollingConfig();
    paperlessApi.getCustomFields().then(setCustomFields).catch(() => {});
  }, [handleLoadPollingConfig]);

  const handleSavePollingConfig = async () => {
    const values = await pollingForm.validateFields() as AgrarmonitorPollingConfig;
    setPollingSaving(true);
    try {
      await agrarmonitorApi.updatePollingConfig(values);
      message.success('Konfiguration gespeichert');
    } catch {
      message.error('Speichern fehlgeschlagen');
    } finally {
      setPollingSaving(false);
    }
  };

  const handleRunPolling = async () => {
    setPollingRunning(true);
    setPollingResult(null);
    try {
      const result = await agrarmonitorApi.runPolling();
      setPollingResult(result);
    } catch {
      message.error('Polling fehlgeschlagen');
    } finally {
      setPollingRunning(false);
    }
  };

  const handleProcessUploads = async () => {
    setUploadCheckRunning(true);
    setUploadCheckResult(null);
    try {
      const result = await agrarmonitorApi.processUploads();
      setUploadCheckResult(result);
    } catch {
      message.error('Upload-Check fehlgeschlagen');
    } finally {
      setUploadCheckRunning(false);
    }
  };

  const renderStatusTag = (value: boolean | null, labelTrue: string, labelFalse: string) => {
    if (value === null) return <Tag>–</Tag>;
    return value
      ? <Tag color="success">{labelTrue}</Tag>
      : <Tag color="error">{labelFalse}</Tag>;
  };

  return (
    <div style={{ maxWidth: 600 }}>
      <Typography.Title level={4}>Agrarmonitor</Typography.Title>
      <Typography.Paragraph type="secondary">
        Verbindungsstatus und Geräte-Registrierung für die Agrarmonitor-Schnittstelle.
        Zugangsdaten werden in der <code>.env</code> konfiguriert.
      </Typography.Paragraph>

      <Space direction="vertical" style={{ width: '100%' }}>
        <div>
          <Button loading={loading} onClick={handleLoadStatus}>
            Status abrufen
          </Button>
        </div>

        {status && (
          <Card size="small" title="Status">
            <Space direction="vertical">
              <div>
                <strong>Verbindung: </strong>
                {status.connected
                  ? <Tag color="success">Verbunden</Tag>
                  : <Tag color="error">Nicht verbunden</Tag>}
              </div>
              <div>
                <strong>Registriert: </strong>
                {renderStatusTag(status.registriert, 'Ja', 'Nein')}
              </div>
              <div>
                <strong>Freigeschaltet: </strong>
                {renderStatusTag(status.freigeschaltet, 'Ja', 'Nein')}
              </div>
              {status.error && (
                <div style={{ color: '#ff4d4f' }}>{status.error}</div>
              )}
            </Space>
          </Card>
        )}

        {status?.registriert === false && (
          <Card size="small" title="Gerät registrieren">
            <Form form={form} layout="vertical">
              <Form.Item
                name="pcName"
                label="PC-Name"
                rules={[{ required: true, message: 'Bitte PC-Name eingeben' }]}
              >
                <Input placeholder="BUERO-PC-01" />
              </Form.Item>
              <Form.Item
                name="agrarmonitorId"
                label="Agrarmonitor-ID / Firma"
                rules={[{ required: true, message: 'Bitte Agrarmonitor-ID eingeben' }]}
              >
                <Input placeholder="Agrarmonitor-ID" />
              </Form.Item>
              <Button type="primary" loading={registering} onClick={handleRegister}>
                Gerät registrieren
              </Button>
            </Form>
            {registerResult && (
              <div style={{ marginTop: 12 }}>
                <Tag color={registerResult.success ? 'success' : 'error'}>
                  {registerResult.message}
                </Tag>
              </div>
            )}
          </Card>
        )}

        <Card size="small" title="Polling-Konfiguration" loading={pollingConfigLoading}>
          <Form form={pollingForm} layout="vertical">
            <Form.Item
              name="tagFertig"
              label="Tag-ID: Fertig in Agrarmonitor"
              rules={[{ required: true, message: 'Pflichtfeld' }]}
            >
              <Input placeholder="4" style={{ width: 120 }} />
            </Form.Item>
            <Form.Item
              name="tagVerbucht"
              label="Tag-ID: Verbucht"
              rules={[{ required: true, message: 'Pflichtfeld' }]}
            >
              <Input placeholder="9" style={{ width: 120 }} />
            </Form.Item>
            <Form.Item name="tagHochgeladen" label="Tag-ID: Hochgeladen in Agrarmonitor">
              <Input placeholder="3" style={{ width: 120 }} />
            </Form.Item>
            <Form.Item name="tagManuell" label="Tag-ID: Manuell bearbeiten (bei fehlendem AM-Beleg)">
              <Input placeholder="" style={{ width: 120 }} />
            </Form.Item>
            <Form.Item name="linkField" label="Custom Field: Agrarmonitor-Link">
              <Select allowClear placeholder="Kein Feld ausgewählt" style={{ width: 280 }}>
                {customFields.map(f => (
                  <Select.Option key={f.id} value={String(f.id)}>{f.id}: {f.name}</Select.Option>
                ))}
              </Select>
            </Form.Item>
            <Button type="primary" loading={pollingSaving} onClick={handleSavePollingConfig}>
              Speichern
            </Button>
          </Form>
        </Card>

        <Card size="small" title="Polling ausführen">
          <Space direction="vertical" style={{ width: '100%' }}>
            <Button loading={pollingRunning} onClick={handleRunPolling}>
              Jetzt ausführen
            </Button>
            {pollingResult && (
              <div>
                <Tag color="blue">{pollingResult.processed} verarbeitet</Tag>
                <Tag color="success">{pollingResult.updated} aktualisiert</Tag>
                <Tag>{pollingResult.skipped} übersprungen</Tag>
                {pollingResult.errors.length > 0 && (
                  <Tag color="error">{pollingResult.errors.length} Fehler</Tag>
                )}
                {pollingResult.errors.length > 0 && (
                  <ul style={{ marginTop: 8, paddingLeft: 20 }}>
                    {pollingResult.errors.map((e, i) => (
                      <li key={i} style={{ color: '#ff4d4f' }}>{e}</li>
                    ))}
                  </ul>
                )}
              </div>
            )}
          </Space>
        </Card>

        <Card size="small" title="Dokumenten-Verarbeitung">
          <Typography.Text type="secondary" style={{ display: 'block', marginBottom: 12 }}>
            Prüft Belege mit Tag "Hochgeladen in Agrarmonitor" und setzt den Tag auf "AMfertig",
            sobald sie im Agrarmonitor-Buchungssystem erscheinen.
          </Typography.Text>
          <Space direction="vertical" style={{ width: '100%' }}>
            <Button loading={uploadCheckRunning} onClick={handleProcessUploads}>
              Jetzt prüfen
            </Button>
            {uploadCheckResult && (
              <div>
                <Tag color="blue">{uploadCheckResult.processed} geprüft</Tag>
                <Tag color="success">{uploadCheckResult.updated} aktualisiert</Tag>
                <Tag>{uploadCheckResult.skipped} übersprungen</Tag>
                {uploadCheckResult.errors.length > 0 && (
                  <Tag color="error">{uploadCheckResult.errors.length} Fehler</Tag>
                )}
                {uploadCheckResult.errors.length > 0 && (
                  <ul style={{ marginTop: 8, paddingLeft: 20 }}>
                    {uploadCheckResult.errors.map((e, i) => (
                      <li key={i} style={{ color: '#ff4d4f' }}>{e}</li>
                    ))}
                  </ul>
                )}
              </div>
            )}
          </Space>
        </Card>
      </Space>
    </div>
  );
}


// ═══════════════════════════════════════════════════════════════════
// Steuertags Tab
// ═══════════════════════════════════════════════════════════════════

function SteuertagsTab() {
  const [tags, setTags] = useState<PaperlessTag[]>([]);
  const [selected, setSelected] = useState<number[]>([]);
  const [loading, setLoading] = useState(false);
  const [saving, setSaving] = useState(false);

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const [fetchedTags, steuertagIds] = await Promise.all([
        paperlessApi.getTags(),
        settingsApi.getSteuertagIds(),
      ]);
      setTags(fetchedTags);
      setSelected(steuertagIds);
    } catch {
      message.error('Tags konnten nicht geladen werden.');
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    load();
  }, [load]);

  const handleSave = async () => {
    setSaving(true);
    try {
      await settingsApi.updateSteuertagIds(selected);
      message.success('Steuertags gespeichert.');
    } catch {
      message.error('Steuertags konnten nicht gespeichert werden.');
    } finally {
      setSaving(false);
    }
  };

  return (
    <div>
      <Alert
        type="info"
        showIcon
        style={{ marginBottom: 16 }}
        message="Steuertags"
        description="Als Steuertag markierte Tags dienen der Workflow-Steuerung (z. B. Fertig/Nicht fertig, manuell bearbeiten) und werden NICHT als bearbeitbare Chips im Dokument angezeigt. Alle übrigen Tags gelten als inhaltliche Tags und erscheinen unter dem Titel sowie als Auswahlfeld im Bearbeiten-Dialog."
      />
      <Select
        mode="multiple"
        allowClear
        showSearch
        optionFilterProp="label"
        loading={loading}
        style={{ width: '100%', maxWidth: 700 }}
        placeholder="Steuertags auswählen"
        value={selected}
        onChange={setSelected}
        options={tags.map((t) => ({ value: t.id, label: t.name }))}
        optionRender={(opt) => {
          const tag = tags.find((t) => t.id === opt.value);
          return tag ? (
            <Tag color={tag.color} style={{ color: tag.text_color }}>{tag.name}</Tag>
          ) : (
            opt.label
          );
        }}
      />
      <div style={{ marginTop: 16 }}>
        <Button type="primary" loading={saving} onClick={handleSave}>
          Speichern
        </Button>
      </div>
    </div>
  );
}

// ═══════════════════════════════════════════════════════════════════
// Settings Page
// ═══════════════════════════════════════════════════════════════════

// ═══════════════════════════════════════════════════════════════════
// Webhook-Status Tab
// ═══════════════════════════════════════════════════════════════════

function WebhookStatusTab() {
  const [status, setStatus] = useState<WebhookStatus | null>(null);
  const [loading, setLoading] = useState(true);

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const data = await webhookApi.getStatus();
      setStatus(data);
    } catch (err) {
      console.error('Error loading webhook status:', err);
      message.error('Webhook-Status konnte nicht geladen werden');
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => { load(); }, [load]);

  const renderStatusBadge = (s: string) => {
    switch (s) {
      case 'processed': return <Badge status="success" text="Verarbeitet" />;
      case 'skipped': return <Badge status="warning" text="Übersprungen" />;
      case 'error': return <Badge status="error" text="Fehler" />;
      case 'bad-request': return <Badge status="error" text="Ungültige Anfrage" />;
      default: return <Badge status="default" text={s} />;
    }
  };

  const lastCall = status?.lastCall ?? null;

  return (
    <>
      <div style={{ marginBottom: 16 }}>
        <Title level={4}>Webhook-Status</Title>
        <Typography.Paragraph type="secondary">
          Paperless-NGX ruft nach dem Bearbeiten eines Dokuments den Webhook{' '}
          <Typography.Text code>/api/webhook/paperless</Typography.Text> auf
          (per API-Key authentifiziert). Hier siehst du den zuletzt
          verarbeiteten Aufruf. Eine vollständige Historie steht in den
          Backend-Logs.
        </Typography.Paragraph>
        <Button icon={<ReloadOutlined />} loading={loading} onClick={load}>
          Aktualisieren
        </Button>
      </div>

      <Card size="small" title="Letzter Webhook-Aufruf" loading={loading}>
        {lastCall ? (
          <Descriptions column={1} size="small" bordered>
            <Descriptions.Item label="Zeitpunkt">
              {dayjs(lastCall.at).format('DD.MM.YYYY HH:mm:ss')}
            </Descriptions.Item>
            <Descriptions.Item label="Dokument-ID">
              {lastCall.documentId ?? '—'}
            </Descriptions.Item>
            <Descriptions.Item label="Aktion">
              {lastCall.action ? <Tag>{lastCall.action}</Tag> : '—'}
            </Descriptions.Item>
            <Descriptions.Item label="Ergebnis">
              {renderStatusBadge(lastCall.status)}
              {lastCall.reason ? (
                <Typography.Text type="secondary"> ({lastCall.reason})</Typography.Text>
              ) : null}
            </Descriptions.Item>
            {lastCall.message ? (
              <Descriptions.Item label="Meldung">
                <Typography.Text type="danger">{lastCall.message}</Typography.Text>
              </Descriptions.Item>
            ) : null}
          </Descriptions>
        ) : (
          <Typography.Text type="secondary">
            Noch kein Webhook-Aufruf erfolgt.
          </Typography.Text>
        )}
      </Card>
    </>
  );
}

export default function SettingsPage() {
  return (
    <div>
      <Title level={3}>Einstellungen</Title>
      <Card>
        <Tabs
          items={[
            {
              key: 'users',
              label: <span><UserOutlined /> Benutzer & Betriebe</span>,
              children: <UserClientsTab />,
            },
            {
              key: 'doctypes',
              label: <span><FileTextOutlined /> Dokumenttypen</span>,
              children: <DocTypesTab />,
            },
            {
              key: 'postprocessing',
              label: <span><ThunderboltOutlined /> Postprocessing</span>,
              children: <PostprocessingTab />,
            },
            {
              key: 'barcode-templates',
              label: <span><QrcodeOutlined /> Eingangsdokumentarten</span>,
              children: <BarcodeTemplatesTab />,
            },
            {
              key: 'correspondents',
              label: <span><UserOutlined /> Korrespondenten</span>,
              children: <CorrespondentsTab />,
            },
            {
              key: 'steuertags',
              label: <span><TagsOutlined /> Steuertags</span>,
              children: <SteuertagsTab />,
            },
            {
              key: 'export-targets',
              label: <span><CloudUploadOutlined /> Export-Ziele</span>,
              children: <ExportTargetsTab />,
            },
            {
              key: 'logs',
              label: <span><HistoryOutlined /> Logs</span>,
              children: <PostprocessingLogsTab />,
            },
            {
              key: 'task-log',
              label: <span><UnorderedListOutlined /> Task-Log</span>,
              children: <TaskLogPage />,
            },
            {
              key: 'api-keys',
              label: <span><KeyOutlined /> API-Keys</span>,
              children: <ApiKeysTab />,
            },
            {
              key: 'webhook',
              label: <span><ApiOutlined /> Webhook</span>,
              children: <WebhookStatusTab />,
            },
            {
              key: 'agrarmonitor',
              label: <span><GlobalOutlined /> Agrarmonitor</span>,
              children: <AgrarmonitorTab />,
            },
          ]}
        />
      </Card>
    </div>
  );
}
