/**
 * TrusteeAccountingSettingsView
 *
 * Settings page for configuring the accounting system integration.
 * Allows selecting a connector (RMA, Bexio, Abacus), entering credentials,
 * testing the connection, and removing the integration.
 */

import React, { useState, useEffect, useCallback } from 'react';
import { useSearchParams } from 'react-router-dom';
import { useCurrentInstance } from '../../../hooks/useCurrentInstance';
import { useApiRequest } from '../../../hooks/useApi';
import { useToast } from '../../../contexts/ToastContext';
import { useConfirm } from '../../../hooks/useConfirm';
import { useLanguage } from '../../../providers/language/LanguageContext';
import { useBackgroundJob } from '../../../hooks/useBackgroundJob';
import {
  fetchAccountingConnectors,
  fetchAccountingConfig,
  saveAccountingConfig,
  deleteAccountingConfig,
  testAccountingConnection,
  exportAccountingData,
  type AccountingConnectorInfo,
  type AccountingConfig,
} from '../../../api/trusteeApi';
import { PeriodPicker, type PeriodValue } from '../../../components/PeriodPicker';
import styles from './TrusteeViews.module.css';

const _SETTINGS_TABS = [
  { id: 'settings', icon: '\u2699\uFE0F', color: '#2196F3' },
  { id: 'import-data', icon: '\u2B07\uFE0F', color: '#FF9800' },
];

function _settingsTabLabel(tabId: string, t: (k: string) => string): string {
  switch (tabId) {
    case 'settings': return t('Verbindungseinstellungen');
    case 'import-data': return t('Buchhaltungsdaten importieren');
    default: return tabId;
  }
}

export const TrusteeAccountingSettingsView: React.FC = () => {
  const { t } = useLanguage();
  const { instanceId } = useCurrentInstance();
  const { request } = useApiRequest();
  const { showSuccess, showError } = useToast();
  const [searchParams, setSearchParams] = useSearchParams();

  const activeTab = searchParams.get('tab') || _SETTINGS_TABS[0].id;
  const _setActiveTab = useCallback((tab: string) => {
    setSearchParams({ tab }, { replace: true });
  }, [setSearchParams]);

  const [connectors, setConnectors] = useState<AccountingConnectorInfo[]>([]);
  const [existingConfig, setExistingConfig] = useState<AccountingConfig | null>(null);
  const [selectedType, setSelectedType] = useState<string>('');
  const [displayLabel, setDisplayLabel] = useState('');
  const [configValues, setConfigValues] = useState<Record<string, string>>({});
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [testing, setTesting] = useState(false);
  const [testResult, setTestResult] = useState<{ success: boolean; message?: string } | null>(null);
  const [importing, setImporting] = useState(false);
  const [importDone, setImportDone] = useState(false);
  const [importResult, setImportResult] = useState<Record<string, any> | null>(null);
  const [importStatus, setImportStatus] = useState<Record<string, any> | null>(null);
  const [importJobId, setImportJobId] = useState<string | null>(null);
  const [clearingCache, setClearingCache] = useState(false);
  const [exporting, setExporting] = useState(false);
  const [importPeriod, setImportPeriod] = useState<PeriodValue | null>(null);
  const { confirm, ConfirmDialog } = useConfirm();

  useEffect(() => {
    if (!importDone) return;
    const importResetTimer = setTimeout(() => {
      setImporting(false);
      setImportDone(false);
      setImportJobId(null);
    }, 5000);
    return () => clearTimeout(importResetTimer);
  }, [importDone]);

  const loadData = useCallback(async () => {
    if (!instanceId) return;
    setLoading(true);
    try {
      const [availableConnectors, config] = await Promise.all([
        fetchAccountingConnectors(request, instanceId),
        fetchAccountingConfig(request, instanceId),
      ]);
      setConnectors(availableConnectors || []);
      setExistingConfig(config);
      if (config?.configured && config.connectorType) {
        setSelectedType(config.connectorType);
        setDisplayLabel(config.displayLabel || '');
        if (config.configMasked && typeof config.configMasked === 'object') {
          setConfigValues(config.configMasked as Record<string, string>);
        }
      }
    } catch (err: any) {
      console.error('Failed to load accounting settings:', err);
    } finally {
      setLoading(false);
    }
  }, [instanceId, request]);

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

  const _loadImportStatus = useCallback(async () => {
    if (!instanceId) return;
    try {
      const data = await request({ url: `/api/trustee/${instanceId}/accounting/import-status`, method: 'get' });
      setImportStatus(data);
    } catch (err) {
      console.error('[Trustee] import-status fetch failed:', err);
    }
  }, [instanceId, request]);

  useEffect(() => {
    if (existingConfig?.configured) _loadImportStatus();
  }, [existingConfig, _loadImportStatus]);

  const { job: importJob } = useBackgroundJob(importJobId, {
    enabled: !!importJobId,
    pollMs: 2000,
    onSuccess: (j) => {
      const summary = (j.result || {}) as Record<string, any>;
      setImportResult(summary);
      const errs: string[] = Array.isArray(summary.errors) ? summary.errors : [];
      if (errs.length) {
        showError(t('Import teilweise fehlgeschlagen'), errs.join('; '));
      } else {
        showSuccess(t('Import abgeschlossen'),
          t('{konten} Konten, {buchungen} Buchungen, {kontakte} Kontakte, {salden} Salden importiert.', {
            konten: String(summary.accounts || 0),
            buchungen: String(summary.journalEntries || 0),
            kontakte: String(summary.contacts || 0),
            salden: String(summary.accountBalances || 0),
          }));
      }
      _loadImportStatus();
      void loadData();
      setImportDone(true);
    },
    onError: (j) => {
      showError(t('Import fehlgeschlagen'), j.errorMessage || t('Unbekannter Fehler'));
      setImportDone(true);
    },
  });

  const _getSelectedConnector = (): AccountingConnectorInfo | undefined => {
    return connectors.find(c => c.connectorType === selectedType);
  };

  const handleTypeChange = (newType: string) => {
    setSelectedType(newType);
    setConfigValues({});
    setTestResult(null);
  };

  const handleConfigChange = (key: string, value: string) => {
    setConfigValues(prev => ({ ...prev, [key]: value }));
  };

  const handleSave = async () => {
    if (!instanceId || !selectedType) return;
    setSaving(true);
    try {
      await saveAccountingConfig(request, instanceId, {
        connectorType: selectedType,
        displayLabel,
        config: configValues,
      });
      showSuccess(t('Gespeichert'), t('Die Buchhaltungskonfiguration wurde erfolgreich gespeichert.'));
      await loadData();
    } catch (err: any) {
      showError(t('Fehler'), err.response?.data?.detail || err.message || t('Speichern der Konfiguration fehlgeschlagen.'));
    } finally {
      setSaving(false);
    }
  };

  const handleTestConnection = async () => {
    if (!instanceId) return;
    setTesting(true);
    setTestResult(null);
    try {
      const result = await testAccountingConnection(request, instanceId);
      setTestResult({ success: result.success, message: result.errorMessage });
      if (result.success) {
        showSuccess(t('Verbindung OK'), t('Verbindung zum Buchhaltungssystem erfolgreich.'));
      } else {
        showError(t('Verbindung fehlgeschlagen'), result.errorMessage || t('Keine Verbindung möglich.'));
      }
    } catch (err: any) {
      const msg = err.response?.data?.detail || err.message || t('Verbindungstest fehlgeschlagen.');
      setTestResult({ success: false, message: msg });
      showError(t('Fehler'), msg);
    } finally {
      setTesting(false);
    }
  };

  const handleRemove = async () => {
    if (!instanceId) return;
    const ok = await confirm(t('Buchhaltungsanbindung entfernen? Synchronisierte Daten bleiben erhalten.'), {
      title: t('Anbindung entfernen'),
      confirmLabel: t('Entfernen'),
      variant: 'danger',
    });
    if (!ok) return;
    setSaving(true);
    try {
      await deleteAccountingConfig(request, instanceId);
      showSuccess(t('Entfernt'), t('Buchhaltungsanbindung wurde entfernt.'));
      setSelectedType('');
      setDisplayLabel('');
      setConfigValues({});
      setTestResult(null);
      await loadData();
    } catch (err: any) {
      showError(t('Fehler'), err.message || t('Entfernen der Konfiguration fehlgeschlagen.'));
    } finally {
      setSaving(false);
    }
  };

  const selectedConnector = _getSelectedConnector();

  if (loading) {
    return <div className={styles.loading}>{t('Buchhaltungseinstellungen werden geladen…')}</div>;
  }

  return (
    <div className={styles.listView}>
      <div className={styles.expenseImportSection}>
        <h3 className={styles.sectionTitle}>{t('Buchhaltungssystem-Anbindung')}</h3>

        <div style={{ display: 'flex', gap: '0.25rem', marginBottom: '1.5rem', borderBottom: '2px solid var(--border-color, #e0e0e0)', paddingBottom: 0 }}>
          {_SETTINGS_TABS.map((tab) => (
            <button
              key={tab.id}
              onClick={() => _setActiveTab(tab.id)}
              style={{
                padding: '0.625rem 1rem',
                border: 'none',
                borderBottom: activeTab === tab.id ? `3px solid ${tab.color}` : '3px solid transparent',
                background: 'transparent',
                color: activeTab === tab.id ? 'var(--text-primary, #1a1a1a)' : 'var(--text-secondary, #666)',
                fontWeight: activeTab === tab.id ? 600 : 400,
                fontSize: '0.875rem',
                cursor: 'pointer',
                transition: 'all 0.2s',
                marginBottom: '-2px',
              }}
            >
              <span style={{ marginRight: '0.375rem' }}>{tab.icon}</span>
              {_settingsTabLabel(tab.id, t)}
            </button>
          ))}
        </div>

        {activeTab === 'settings' && (
          <>
            <p className={styles.sectionDescription}>
              {t('Verbinden Sie ein Buchhaltungssystem, um Buchungen aus dieser Trustee-Instanz automatisch zu synchronisieren.')}
            </p>

            {existingConfig?.configured && (
              <div className={styles.successMessage} style={{ marginBottom: '0.5rem' }}>
                <strong>{t('Verbunden:')}</strong> {existingConfig.displayLabel || existingConfig.connectorType}
              </div>
            )}

            {existingConfig?.configured && existingConfig.lastSyncStatus === 'error' && (
          <div className={styles.setupStep} style={{ marginTop: 0, marginBottom: '1rem' }}>
            <div className={styles.stepNumber} style={{ visibility: 'hidden' }}>0</div>
            <div className={styles.stepContent}>
              <h4 style={{ marginTop: 0 }}>{t('Letzter Sync fehlgeschlagen')}</h4>
              <div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>
                {existingConfig.lastSyncAt != null && (
                  <div style={{ fontSize: '0.9rem' }}>
                    <strong>{t('Zeitpunkt:')}</strong>{' '}
                    {new Date(existingConfig.lastSyncAt * 1000).toLocaleString()}
                  </div>
                )}
                <div className={styles.errorMessage} style={{ marginTop: '0.25rem', padding: '0.75rem' }}>
                  {(existingConfig.lastSyncErrorMessage ?? '').trim() !== ''
                    ? existingConfig.lastSyncErrorMessage
                    : t('Der letzte Sync ist fehlgeschlagen. Details pro Position finden Sie unter Positionen (Spalte Sync-Status).')}
                </div>
              </div>
            </div>
          </div>
        )}

        {/* Step 1: Select system */}
        <div className={styles.setupStep}>
          <div className={styles.stepNumber}>1</div>
          <div className={styles.stepContent}>
            <h4>{t('Buchhaltungssystem')}</h4>
            <select
              className={styles.folderSelect}
              value={selectedType}
              onChange={e => handleTypeChange(e.target.value)}
            >
              <option value="">{t('System auswählen…')}</option>
              {connectors.map(c => (
                <option key={c.connectorType} value={c.connectorType}>
                  {c.label || c.connectorType}
                </option>
              ))}
            </select>
          </div>
        </div>

        {/* Step 2: Credentials */}
        {selectedConnector && (
          <div className={styles.setupStep}>
            <div className={styles.stepNumber}>2</div>
            <div className={styles.stepContent}>
              <h4>{t('Zugangsdaten')}</h4>
              <div style={{ display: 'flex', flexDirection: 'column', gap: '0.75rem' }}>
                <div>
                  <label style={{ display: 'block', marginBottom: '0.25rem', fontSize: '0.85rem' }}>
                    {t('Anzeigename')}
                  </label>
                  <input
                    type="text"
                    className={styles.folderSelect}
                    value={displayLabel}
                    onChange={e => setDisplayLabel(e.target.value)}
                    placeholder={t('z. B. Run My Accounts – Muster AG')}
                  />
                </div>
                {selectedConnector.configFields.map(field => {
                  const datalistId = field.suggestions && field.suggestions.length > 0
                    ? `dl-${selectedConnector.connectorType}-${field.key}`
                    : undefined;
                  return (
                    <div key={field.key}>
                      <label style={{ display: 'block', marginBottom: '0.25rem', fontSize: '0.85rem' }}>
                        {field.label || field.key}
                        {field.required && <span style={{ color: 'var(--error-color, #dc2626)' }}> *</span>}
                      </label>
                      <input
                        type={field.secret ? 'password' : 'text'}
                        className={styles.folderSelect}
                        value={configValues[field.key] || ''}
                        onChange={e => handleConfigChange(field.key, e.target.value)}
                        placeholder={field.placeholder || ''}
                        autoComplete={field.secret ? 'new-password' : 'off'}
                        list={datalistId}
                      />
                      {datalistId && (
                        <datalist id={datalistId}>
                          {field.suggestions!.map(s => (
                            <option key={s} value={s} />
                          ))}
                        </datalist>
                      )}
                    </div>
                  );
                })}
              </div>
            </div>
          </div>
        )}

        {/* Step 3: Save & Test */}
        {selectedConnector && (
          <div className={styles.setupStep}>
            <div className={styles.stepNumber}>3</div>
            <div className={styles.stepContent}>
              <h4>{t('Test speichern')}</h4>
              {testResult && (
                <div className={testResult.success ? styles.successMessage : styles.errorMessage} style={{ marginBottom: '0.75rem' }}>
                  {testResult.success ? t('Verbindung erfolgreich!') : t('Verbindung fehlgeschlagen: {message}', { message: testResult.message || t('Unbekannter Fehler') })}
                </div>
              )}
              <div style={{ display: 'flex', gap: '0.5rem', flexWrap: 'wrap' }}>
                <button
                  className={styles.primaryButton}
                  onClick={handleSave}
                  disabled={saving}
                >
                  {saving ? t('Speichern…') : t('Konfiguration speichern')}
                </button>
                {existingConfig?.configured && (
                  <button
                    className={styles.secondaryButton}
                    onClick={handleTestConnection}
                    disabled={testing}
                  >
                    {testing ? t('Teste…') : t('Verbindung testen')}
                  </button>
                )}
                {existingConfig?.configured && (
                  <button
                    className={styles.secondaryButton}
                    onClick={handleRemove}
                    disabled={saving}
                    style={{ color: 'var(--error-color, #dc2626)' }}
                  >
                    {t('Anbindung entfernen')}
                  </button>
                )}
              </div>
            </div>
          </div>
        )}

          </>
        )}

        {activeTab === 'import-data' && (
          <>
            {!existingConfig?.configured && (
              <div className={styles.infoBox}>
                <p>
                  {t('Bevor Sie Daten importieren können, richten Sie zuerst die Verbindung zum Buchhaltungssystem im Tab «Verbindungseinstellungen» ein.')}
                </p>
              </div>
            )}
            {existingConfig?.configured && (
              <div className={styles.setupStep}>
                <div className={styles.stepNumber} style={{ visibility: 'hidden' }}>0</div>
                <div className={styles.stepContent}>
                  <h4 style={{ marginTop: 0 }}>{t('Buchhaltungsdaten importieren')}</h4>
              <p style={{ fontSize: '0.85rem', color: 'var(--text-secondary)', marginBottom: '0.75rem' }}>
                {t('Kontenplan, Buchungen, Kontakte und Salden aus dem Buchhaltungssystem einlesen. Diese Daten stehen anschließend im KI-Workspace für Analysen zur Verfügung.')}
              </p>

              {(() => {
                const lastSyncAt = importStatus?.lastSyncAt as number | null | undefined;
                const winFrom = importStatus?.lastSyncDateFrom as string | undefined;
                const winTo = importStatus?.lastSyncDateTo as string | undefined;
                const counts = (importStatus?.lastSyncCounts || {}) as Record<string, number>;
                const timeWindow = winFrom && winTo
                  ? t('{from} bis {to}', { from: winFrom, to: winTo })
                  : winFrom
                    ? t('ab {from}', { from: winFrom })
                    : winTo
                      ? t('bis {to}', { to: winTo })
                      : null;
                return (
                  <div style={{
                    fontSize: '0.8rem',
                    color: 'var(--text-secondary)',
                    background: 'var(--surface-color, #f5f5f5)',
                    border: '1px solid var(--border-color, #e0e0e0)',
                    borderRadius: '6px',
                    padding: '0.5rem 0.75rem',
                    marginBottom: '0.75rem',
                  }}>
                    {lastSyncAt ? (
                      <>
                        <div>
                          <strong>{t('Letzter Import:')}</strong> {new Date(lastSyncAt * 1000).toLocaleString()}
                          {timeWindow && (
                            <> {' '}&middot; <strong>{t('Zeitfenster:')}</strong> {timeWindow}</>
                          )}
                        </div>
                        <div style={{ marginTop: '0.2rem' }}>
                          {t('{konten} Konten, {buchungen} Buchungen ({zeilen} Zeilen), {kontakte} Kontakte, {salden} Salden', {
                            konten: String(counts.accounts ?? 0),
                            buchungen: String(counts.journalEntries ?? 0),
                            zeilen: String(counts.journalLines ?? 0),
                            kontakte: String(counts.contacts ?? 0),
                            salden: String(counts.accountBalances ?? 0),
                          })}
                        </div>
                      </>
                    ) : (
                      <div>
                        <em>{t('Noch kein Import durchgeführt. Wähle unten ein Zeitfenster und klicke auf «Daten jetzt einlesen».')}</em>
                      </div>
                    )}
                  </div>
                );
              })()}

              <div style={{ display: 'flex', gap: '0.75rem', marginBottom: '0.75rem', flexWrap: 'wrap', alignItems: 'flex-end' }}>
                <div>
                  <label style={{ display: 'block', fontSize: '0.8rem', marginBottom: '0.25rem' }}>{t('Zeitraum (optional)')}</label>
                  <PeriodPicker
                    value={importPeriod}
                    onChange={setImportPeriod}
                    direction="past"
                    placeholder={t('Alle Daten')}
                  />
                </div>
              </div>

              <div style={{ display: 'flex', gap: '0.5rem', flexWrap: 'wrap' }}>
                <button
                  className={styles.primaryButton}
                  disabled={importing}
                  onClick={async () => {
                    if (!instanceId) return;
                    setImporting(true);
                    setImportResult(null);
                    setImportJobId(null);
                    try {
                      const body: Record<string, string> = {};
                      if (importPeriod?.fromDate) body.dateFrom = importPeriod.fromDate;
                      if (importPeriod?.toDate) body.dateTo = importPeriod.toDate;
                      const result = await request({ url: `/api/trustee/${instanceId}/accounting/import-data`, method: 'post', data: body });
                      const newJobId: string | undefined = result?.jobId;
                      if (newJobId) {
                        setImportJobId(newJobId);
                      } else {
                        showError(t('Import fehlgeschlagen'), t('Kein jobId vom Server erhalten'));
                        setImportDone(true);
                      }
                    } catch (err: any) {
                      showError(t('Import fehlgeschlagen'), err.response?.data?.detail || err.message || t('Unbekannter Fehler'));
                      setImportDone(true);
                    }
                  }}
                >
                  {importing
                    ? (importJob?.progressMessage || t('Importiere…'))
                    : t('Daten jetzt einlesen')}
                </button>
                {importing && importJob && (
                  <div style={{ flex: '1 1 100%', marginTop: '0.5rem' }}>
                    <div style={{
                      width: '100%', height: '6px', background: 'var(--surface-color, #eee)',
                      borderRadius: '3px', overflow: 'hidden',
                    }}>
                      <div style={{
                        width: `${Math.max(2, importJob.progress || 0)}%`,
                        height: '100%',
                        background: 'var(--primary-color, #4CAF50)',
                        transition: 'width 0.4s ease',
                      }} />
                    </div>
                    <div style={{ fontSize: '0.75rem', color: 'var(--text-secondary)', marginTop: '0.25rem' }}>
                      {importJob.progress}% {importJob.progressMessage ? `· ${importJob.progressMessage}` : ''}
                    </div>
                  </div>
                )}
                <button
                  className={styles.secondaryButton}
                  disabled={clearingCache}
                  onClick={async () => {
                    if (!instanceId) return;
                    setClearingCache(true);
                    try {
                      const result = await request({ url: `/api/trustee/${instanceId}/accounting/clear-cache`, method: 'post' });
                      showSuccess(t('Cache geleert'), t('{n} gecachte Abfragen entfernt. Die nächste KI-Abfrage liest frische Daten.', { n: String(result?.cleared ?? 0) }));
                    } catch (err: any) {
                      showError(t('Fehler'), err.response?.data?.detail || err.message || t('Cache konnte nicht geleert werden.'));
                    } finally {
                      setClearingCache(false);
                    }
                  }}
                >
                  {clearingCache ? t('Leere…') : t('KI-Cache leeren')}
                </button>
                <button
                  className={styles.secondaryButton}
                  disabled={exporting}
                  onClick={async () => {
                    if (!instanceId) return;
                    setExporting(true);
                    try {
                      await exportAccountingData(request, instanceId);
                      showSuccess(t('Export gestartet'), t('Die Daten werden als JSON-Datei heruntergeladen.'));
                    } catch (err: any) {
                      showError(t('Fehler'), err.response?.data?.detail || err.message || t('Export fehlgeschlagen.'));
                    } finally {
                      setExporting(false);
                    }
                  }}
                >
                  {exporting ? t('Exportiere…') : t('Alle Daten exportieren (JSON)')}
                </button>
              </div>

              {importResult && !importResult.errors?.length && (
                <div className={styles.successMessage} style={{ marginTop: '0.75rem' }}>
                  {t('Import abgeschlossen in {sek}s:', { sek: String(importResult.durationSeconds) })}{' '}
                  {t('{konten} Konten, {buchungen} Buchungen ({zeilen} Zeilen), {kontakte} Kontakte, {salden} Salden', {
                    konten: String(importResult.accounts),
                    buchungen: String(importResult.journalEntries),
                    zeilen: String(importResult.journalLines),
                    kontakte: String(importResult.contacts),
                    salden: String(importResult.accountBalances),
                  })}
                </div>
              )}

              {importStatus && (importStatus.accounts > 0 || importStatus.journalEntries > 0) && (
                <div style={{ marginTop: '0.75rem', fontSize: '0.85rem', color: 'var(--text-secondary)' }}>
                  <strong>{t('Aktueller Datenbestand:')}</strong>{' '}
                  {t('{konten} Konten, {buchungen} Buchungen, {zeilen} Zeilen, {kontakte} Kontakte, {salden} Salden', {
                    konten: String(importStatus.accounts),
                    buchungen: String(importStatus.journalEntries),
                    zeilen: String(importStatus.journalLines),
                    kontakte: String(importStatus.contacts),
                    salden: String(importStatus.accountBalances),
                  })}
                  {importStatus.lastSyncAt && (
                    <> &middot; {t('Letzter Import:')} {new Date(importStatus.lastSyncAt * 1000).toLocaleString()}</>
                  )}
                </div>
              )}
                </div>
              </div>
            )}
          </>
        )}
      </div>
      <ConfirmDialog />
    </div>
  );
};

export default TrusteeAccountingSettingsView;
