/**
 * 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, useRef } from 'react';
import { useCurrentInstance } from '../../../hooks/useCurrentInstance';
import { useApiRequest } from '../../../hooks/useApi';
import { useToast } from '../../../contexts/ToastContext';
import {
  fetchAccountingConnectors,
  fetchAccountingConfig,
  saveAccountingConfig,
  deleteAccountingConfig,
  testAccountingConnection,
  type AccountingConnectorInfo,
  type AccountingConfig,
} from '../../../api/trusteeApi';
import styles from './TrusteeViews.module.css';

export const TrusteeAccountingSettingsView: React.FC = () => {
  const { instanceId } = useCurrentInstance();
  const { request } = useApiRequest();
  const { showSuccess, showError } = useToast();

  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 [dateFrom, setDateFrom] = useState('');
  const [dateTo, setDateTo] = useState('');
  const mountedRef = useRef(true);

  useEffect(() => {
    if (!importDone) return;
    const t = setTimeout(() => { setImporting(false); setImportDone(false); }, 5000);
    return () => clearTimeout(t);
  }, [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();
    return () => { mountedRef.current = false; };
  }, [loadData]);

  const _loadImportStatus = useCallback(async () => {
    if (!instanceId) return;
    try {
      const res = await request({ url: `/api/trustee/${instanceId}/accounting/import-status`, method: 'get' });
      if (mountedRef.current) setImportStatus(res.data);
    } catch { /* ignore */ }
  }, [instanceId, request]);

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

  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('Saved', 'Accounting configuration saved successfully.');
      await loadData();
    } catch (err: any) {
      showError('Error', err.response?.data?.detail || err.message || 'Failed to save configuration.');
    } 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('Connection OK', 'Successfully connected to the accounting system.');
      } else {
        showError('Connection Failed', result.errorMessage || 'Could not connect.');
      }
    } catch (err: any) {
      const msg = err.response?.data?.detail || err.message || 'Connection test failed.';
      setTestResult({ success: false, message: msg });
      showError('Error', msg);
    } finally {
      setTesting(false);
    }
  };

  const handleRemove = async () => {
    if (!instanceId) return;
    if (!window.confirm('Remove the accounting integration? This does not delete synced data.')) return;
    setSaving(true);
    try {
      await deleteAccountingConfig(request, instanceId);
      showSuccess('Removed', 'Accounting integration removed.');
      setSelectedType('');
      setDisplayLabel('');
      setConfigValues({});
      setTestResult(null);
      await loadData();
    } catch (err: any) {
      showError('Error', err.message || 'Failed to remove configuration.');
    } finally {
      setSaving(false);
    }
  };

  const selectedConnector = _getSelectedConnector();

  if (loading) {
    return <div className={styles.loading}>Loading accounting settings...</div>;
  }

  return (
    <div className={styles.listView}>
      <div className={styles.expenseImportSection}>
        <h3 className={styles.sectionTitle}>Accounting System Integration</h3>
        <p className={styles.sectionDescription}>
          Connect an accounting system to automatically sync bookings from this Trustee instance.
        </p>

        {existingConfig?.configured && (
          <div className={styles.successMessage} style={{ marginBottom: '0.5rem' }}>
            <strong>Connected:</strong> {existingConfig.displayLabel || existingConfig.connectorType}
            {existingConfig.lastSyncStatus != null && existingConfig.lastSyncStatus !== '' && (
              <> &middot; Last sync: {existingConfig.lastSyncStatus}</>
            )}
          </div>
        )}

        {existingConfig?.configured && (existingConfig.lastSyncAt != null || existingConfig.lastSyncStatus != null) && (
          <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 }}>Sync-Status / Fehlerprotokoll</h4>
              <div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>
                {existingConfig.lastSyncAt != null && (
                  <div style={{ fontSize: '0.9rem' }}>
                    <strong>Letzter Sync:</strong>{' '}
                    {new Date(existingConfig.lastSyncAt * 1000).toLocaleString()}
                    {existingConfig.lastSyncStatus != null && existingConfig.lastSyncStatus !== '' && (
                      <> &middot; Status: {existingConfig.lastSyncStatus}</>
                    )}
                  </div>
                )}
                {existingConfig.lastSyncStatus === 'error' && (existingConfig.lastSyncErrorMessage ?? '').trim() !== '' && (
                  <div className={styles.errorMessage} style={{ marginTop: '0.25rem', padding: '0.75rem' }}>
                    {existingConfig.lastSyncErrorMessage}
                  </div>
                )}
                {existingConfig.lastSyncStatus === 'error' && (!existingConfig.lastSyncErrorMessage || existingConfig.lastSyncErrorMessage.trim() === '') && (
                  <div className={styles.errorMessage} style={{ marginTop: '0.25rem', padding: '0.75rem' }}>
                    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>Accounting System</h4>
            <select
              className={styles.folderSelect}
              value={selectedType}
              onChange={e => handleTypeChange(e.target.value)}
            >
              <option value="">Select a system...</option>
              {connectors.map(c => (
                <option key={c.connectorType} value={c.connectorType}>
                  {c.label?.de || c.label?.en || 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>Credentials</h4>
              <div style={{ display: 'flex', flexDirection: 'column', gap: '0.75rem' }}>
                <div>
                  <label style={{ display: 'block', marginBottom: '0.25rem', fontSize: '0.85rem' }}>
                    Display Label
                  </label>
                  <input
                    type="text"
                    className={styles.folderSelect}
                    value={displayLabel}
                    onChange={e => setDisplayLabel(e.target.value)}
                    placeholder="e.g. Run My Accounts - Muster AG"
                  />
                </div>
                {selectedConnector.configFields.map(field => (
                  <div key={field.key}>
                    <label style={{ display: 'block', marginBottom: '0.25rem', fontSize: '0.85rem' }}>
                      {field.label?.de || field.label?.en || 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'}
                    />
                  </div>
                ))}
              </div>
            </div>
          </div>
        )}

        {/* Step 3: Save & Test */}
        {selectedConnector && (
          <div className={styles.setupStep}>
            <div className={styles.stepNumber}>3</div>
            <div className={styles.stepContent}>
              <h4>Save & Test</h4>
              {testResult && (
                <div className={testResult.success ? styles.successMessage : styles.errorMessage} style={{ marginBottom: '0.75rem' }}>
                  {testResult.success ? 'Connection successful!' : `Connection failed: ${testResult.message || 'Unknown error'}`}
                </div>
              )}
              <div style={{ display: 'flex', gap: '0.5rem', flexWrap: 'wrap' }}>
                <button
                  className={styles.primaryButton}
                  onClick={handleSave}
                  disabled={saving}
                >
                  {saving ? 'Saving...' : 'Save Configuration'}
                </button>
                {existingConfig?.configured && (
                  <button
                    className={styles.secondaryButton}
                    onClick={handleTestConnection}
                    disabled={testing}
                  >
                    {testing ? 'Testing...' : 'Test Connection'}
                  </button>
                )}
                {existingConfig?.configured && (
                  <button
                    className={styles.secondaryButton}
                    onClick={handleRemove}
                    disabled={saving}
                    style={{ color: 'var(--error-color, #dc2626)' }}
                  >
                    Remove Integration
                  </button>
                )}
              </div>
            </div>
          </div>
        )}

        {/* Step 4: Import Accounting Data */}
        {existingConfig?.configured && (
          <div className={styles.setupStep}>
            <div className={styles.stepNumber}>4</div>
            <div className={styles.stepContent}>
              <h4>Buchhaltungsdaten importieren</h4>
              <p style={{ fontSize: '0.85rem', color: 'var(--text-secondary)', marginBottom: '0.75rem' }}>
                Kontenplan, Buchungen, Kontakte und Salden aus dem Buchhaltungssystem einlesen.
                Diese Daten stehen anschliessend im AI Workspace fuer Analysen zur Verfuegung.
              </p>

              <div style={{ display: 'flex', gap: '0.75rem', marginBottom: '0.5rem', flexWrap: 'wrap', alignItems: 'flex-end' }}>
                <div>
                  <label style={{ display: 'block', fontSize: '0.8rem', marginBottom: '0.2rem' }}>Von (optional)</label>
                  <input type="date" className={styles.folderSelect} value={dateFrom} onChange={e => setDateFrom(e.target.value)} style={{ width: '160px' }} />
                </div>
                <div>
                  <label style={{ display: 'block', fontSize: '0.8rem', marginBottom: '0.2rem' }}>Bis (optional)</label>
                  <input type="date" className={styles.folderSelect} value={dateTo} onChange={e => setDateTo(e.target.value)} style={{ width: '160px' }} />
                </div>
              </div>
              <div style={{ display: 'flex', gap: '0.4rem', marginBottom: '0.75rem', flexWrap: 'wrap' }}>
                {[
                  { label: 'YTD', from: `${new Date().getFullYear()}-01-01`, to: new Date().toISOString().slice(0, 10) },
                  {
                    label: 'Letztes Jahr',
                    from: `${new Date().getFullYear() - 1}-01-01`,
                    to: `${new Date().getFullYear() - 1}-12-31`,
                  },
                  {
                    label: 'Letzter Monat',
                    from: (() => { const d = new Date(); d.setDate(1); d.setMonth(d.getMonth() - 1); return d.toISOString().slice(0, 10); })(),
                    to: (() => { const d = new Date(); d.setDate(0); return d.toISOString().slice(0, 10); })(),
                  },
                ].map(s => (
                  <button
                    key={s.label}
                    type="button"
                    className={styles.secondaryButton}
                    style={{ fontSize: '0.75rem', padding: '0.25rem 0.6rem', minWidth: 0 }}
                    onClick={() => { setDateFrom(s.from); setDateTo(s.to); }}
                  >
                    {s.label}
                  </button>
                ))}
              </div>

              <button
                className={styles.primaryButton}
                disabled={importing}
                onClick={async () => {
                  if (!instanceId) return;
                  setImporting(true);
                  setImportResult(null);
                  try {
                    const body: Record<string, string> = {};
                    if (dateFrom) body.dateFrom = dateFrom;
                    if (dateTo) body.dateTo = dateTo;
                    const res = await request({ url: `/api/trustee/${instanceId}/accounting/import-data`, method: 'post', data: body });
                    if (mountedRef.current) {
                      setImportResult(res.data);
                      if (res.data.errors?.length) {
                        showError('Import teilweise fehlgeschlagen', res.data.errors.join('; '));
                      } else {
                        showSuccess('Import abgeschlossen',
                          `${res.data.accounts || 0} Konten, ${res.data.journalEntries || 0} Buchungen, ` +
                          `${res.data.contacts || 0} Kontakte, ${res.data.accountBalances || 0} Salden importiert.`);
                      }
                      _loadImportStatus();
                    }
                  } catch (err: any) {
                    showError('Import fehlgeschlagen', err.response?.data?.detail || err.message || 'Unbekannter Fehler');
                  } finally {
                    setImportDone(true);
                  }
                }}
              >
                {importing ? 'Importiere...' : 'Daten jetzt einlesen'}
              </button>

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

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

export default TrusteeAccountingSettingsView;
