import React, { useState, useEffect, useCallback, useRef } from 'react';
import { getAuditLogs, getAuditStats, exportAuditLogs } from '../../services/auditLogs';
import './AuditLogs.css';

// ── helpers ────────────────────────────────────────────────────────────────────

const ACTION_LABELS = {
  CREATE: 'Erstellen', UPDATE: 'Bearbeiten', DELETE: 'Löschen',
  RESTORE: 'Wiederherstellen', LOGIN: 'Login', LOGOUT: 'Logout',
  LOGIN_FAILED: 'Login fehlgeschlagen', IMPORT: 'Import', EXPORT: 'Export',
  BULK_UPDATE: 'Massen-Update', BULK_DELETE: 'Massen-Löschung',
  PASSWORD_RESET: 'Passwort-Reset', PASSWORD_CHANGE: 'Passwort-Änderung'
};

const ACTION_ICONS = {
  CREATE: '➕', UPDATE: '✏️', DELETE: '🗑️', RESTORE: '↩️',
  LOGIN: '🔓', LOGOUT: '🔒', LOGIN_FAILED: '🚫',
  IMPORT: '📥', EXPORT: '📤', BULK_UPDATE: '✏️', BULK_DELETE: '🗑️',
  PASSWORD_RESET: '🔑', PASSWORD_CHANGE: '🔑'
};

const ACTION_BADGE = {
  CREATE: 'badge-create', UPDATE: 'badge-update', DELETE: 'badge-delete',
  RESTORE: 'badge-restore', LOGIN: 'badge-login', LOGOUT: 'badge-logout',
  LOGIN_FAILED: 'badge-login-failed', IMPORT: 'badge-import', EXPORT: 'badge-export',
  BULK_UPDATE: 'badge-bulk-update', BULK_DELETE: 'badge-bulk-delete',
  PASSWORD_RESET: 'badge-password', PASSWORD_CHANGE: 'badge-password'
};

const formatDate = (ds) =>
  new Date(ds).toLocaleString('de-DE', {
    year: 'numeric', month: '2-digit', day: '2-digit',
    hour: '2-digit', minute: '2-digit', second: '2-digit'
  });

const parseUA = (ua) => {
  if (!ua) return '—';
  if (/iPhone|iPad/.test(ua)) return '📱 iOS';
  if (/Android/.test(ua)) return '📱 Android';
  if (/Firefox\/(\d+)/.test(ua)) return `🦊 Firefox ${ua.match(/Firefox\/(\d+)/)[1]}`;
  if (/Edg\/(\d+)/.test(ua))     return `🔷 Edge ${ua.match(/Edg\/(\d+)/)[1]}`;
  if (/Chrome\/(\d+)/.test(ua))  return `🌐 Chrome ${ua.match(/Chrome\/(\d+)/)[1]}`;
  if (/Safari\/(\d+)/.test(ua))  return `🧭 Safari`;
  return ua.slice(0, 60);
};

const statusBadgeClass = (code) => {
  if (!code) return '';
  if (code < 300) return 'status-ok';
  if (code < 400) return 'status-redirect';
  if (code < 500) return 'status-error';
  return 'status-server-error';
};

// ── component ──────────────────────────────────────────────────────────────────

function AuditLogs() {
  const [logs, setLogs]             = useState([]);
  const [stats, setStats]           = useState(null);
  const [loading, setLoading]       = useState(true);
  const [statsLoading, setStatsLoading] = useState(true);
  const [error, setError]           = useState(null);
  const [expanded, setExpanded]     = useState({});
  const [showStats, setShowStats]   = useState(true);
  const [autoRefresh, setAutoRefresh] = useState(false);
  const [exporting, setExporting]   = useState(false);
  const [pagination, setPagination] = useState({});
  const [statsDays, setStatsDays]   = useState(30);

  const [filters, setFilters] = useState({
    action: '', resource: '', adminUsername: '',
    success: '', startDate: '', endDate: '',
    page: 1, limit: 25
  });

  const autoRefreshRef = useRef(null);

  const loadLogs = useCallback(async () => {
    setLoading(true);
    setError(null);
    const params = {};
    Object.entries(filters).forEach(([k, v]) => { if (v !== '') params[k] = v; });
    const result = await getAuditLogs(params);
    if (result.success) {
      setLogs(result.data);
      setPagination(result.pagination);
    } else {
      setError(result.message);
    }
    setLoading(false);
  }, [filters]);

  const loadStats = useCallback(async () => {
    setStatsLoading(true);
    const result = await getAuditStats(statsDays);
    if (result.success) setStats(result.data);
    setStatsLoading(false);
  }, [statsDays]);

  useEffect(() => { loadLogs(); }, [loadLogs]);
  useEffect(() => { loadStats(); }, [loadStats]);

  // Auto-refresh
  useEffect(() => {
    if (autoRefresh) {
      autoRefreshRef.current = setInterval(() => loadLogs(), 30000);
    } else {
      clearInterval(autoRefreshRef.current);
    }
    return () => clearInterval(autoRefreshRef.current);
  }, [autoRefresh, loadLogs]);

  const setFilter = (key, value) =>
    setFilters(f => ({ ...f, [key]: value, page: 1 }));

  const toggleExpand = (id) =>
    setExpanded(e => ({ ...e, [id]: !e[id] }));

  const handleExport = async () => {
    setExporting(true);
    const params = {};
    Object.entries(filters).forEach(([k, v]) => {
      if (v !== '' && k !== 'page' && k !== 'limit') params[k] = v;
    });
    await exportAuditLogs(params);
    setExporting(false);
  };

  const resetFilters = () =>
    setFilters({ action: '', resource: '', adminUsername: '', success: '', startDate: '', endDate: '', page: 1, limit: 25 });

  // ── stats cards ──────────────────────────────────────────────────────────────

  const renderStats = () => {
    if (statsLoading) return <div className="stats-loading">Lade Statistiken…</div>;
    if (!stats) return null;
    const maxBar = Math.max(...(stats.dailyActivity?.map(d => d.count) || [1]), 1);
    return (
      <div className="audit-stats">
        <div className="stats-row">
          <div className="stat-card stat-total">
            <div className="stat-number">{stats.total}</div>
            <div className="stat-label">Aktionen gesamt</div>
          </div>
          <div className="stat-card stat-failed">
            <div className="stat-number">{stats.failed}</div>
            <div className="stat-label">Fehlgeschlagen</div>
          </div>
          <div className="stat-card stat-success">
            <div className="stat-number">{stats.total - stats.failed}</div>
            <div className="stat-label">Erfolgreich</div>
          </div>
          <div className="stat-card stat-period">
            <div className="stat-number">{stats.days} Tage</div>
            <div className="stat-label">Zeitraum</div>
          </div>
        </div>

        <div className="stats-details">
          <div className="stats-col">
            <h4>Nach Aktion</h4>
            {stats.byAction.map(a => (
              <div key={a.action} className="stat-bar-row">
                <span className={`audit-badge ${ACTION_BADGE[a.action] || 'badge-default'}`}>
                  {ACTION_ICONS[a.action]} {ACTION_LABELS[a.action] || a.action}
                </span>
                <span className="stat-bar-count">{a.count}</span>
              </div>
            ))}
          </div>
          <div className="stats-col">
            <h4>Nach Admin</h4>
            {stats.byAdmin.map(a => (
              <div key={a.admin} className="stat-bar-row">
                <span className="stat-bar-label">👤 {a.admin}</span>
                <span className="stat-bar-count">{a.count}</span>
              </div>
            ))}
          </div>
          <div className="stats-col stats-chart-col">
            <h4>Aktivität (letzte {stats.days} Tage)</h4>
            <div className="mini-chart">
              {stats.dailyActivity.map(d => (
                <div key={d.date} className="chart-bar-wrap" title={`${d.date}: ${d.count} (${d.failed} Fehler)`}>
                  <div className="chart-bar" style={{ height: `${Math.max(4, (d.count / maxBar) * 100)}%` }}>
                    {d.failed > 0 && (
                      <div className="chart-bar-failed" style={{ height: `${(d.failed / d.count) * 100}%` }} />
                    )}
                  </div>
                </div>
              ))}
            </div>
          </div>
        </div>
      </div>
    );
  };

  // ── diff renderer ────────────────────────────────────────────────────────────

  const renderDiff = (changes) => {
    if (!changes || Object.keys(changes).length === 0) return null;
    return (
      <table className="diff-table">
        <thead>
          <tr><th>Feld</th><th>Vorher</th><th>Nachher</th></tr>
        </thead>
        <tbody>
          {Object.entries(changes).map(([field, { before, after }]) => (
            <tr key={field}>
              <td className="diff-field">{field}</td>
              <td className="diff-before">{JSON.stringify(before) ?? '—'}</td>
              <td className="diff-after">{JSON.stringify(after) ?? '—'}</td>
            </tr>
          ))}
        </tbody>
      </table>
    );
  };

  // ── log item ─────────────────────────────────────────────────────────────────

  const renderLogItem = (log) => {
    const isExpanded = expanded[log._id];
    const hasDiff    = log.changes && Object.keys(log.changes).length > 0;
    const hasMeta    = log.metadata && Object.keys(log.metadata).length > 0;
    const hasDetail  = hasDiff || hasMeta || log.errorMessage || log.userAgent || log.requestPath;

    return (
      <div key={log._id} className={`audit-item ${!log.success ? 'audit-item-failed' : ''}`}>
        <div className="audit-item-header" onClick={() => hasDetail && toggleExpand(log._id)}
             style={{ cursor: hasDetail ? 'pointer' : 'default' }}>
          <span className={`audit-badge ${ACTION_BADGE[log.action] || 'badge-default'}`}>
            {ACTION_ICONS[log.action]} {ACTION_LABELS[log.action] || log.action}
          </span>
          <span className="audit-resource">{log.resource}</span>
          {log.statusCode && (
            <span className={`status-code ${statusBadgeClass(log.statusCode)}`}>{log.statusCode}</span>
          )}
          {log.duration != null && (
            <span className="duration-badge">{log.duration} ms</span>
          )}
          <span className="audit-time">{formatDate(log.createdAt)}</span>
          {hasDetail && (
            <span className="expand-toggle">{isExpanded ? '▲' : '▼'}</span>
          )}
        </div>

        <div className="audit-item-body">
          <span className="audit-admin">👤 <strong>{log.adminUsername || '—'}</strong></span>
          {log.resourceName && <span className="audit-resource-name">📌 {log.resourceName}</span>}
          {log.ipAddress    && <span className="audit-ip">🌐 {log.ipAddress}</span>}
          {!log.success     && <span className="audit-failed-badge">✗ Fehlgeschlagen</span>}
        </div>

        {isExpanded && (
          <div className="audit-item-detail">
            {log.requestMethod && log.requestPath && (
              <div className="detail-row">
                <span className="detail-label">Anfrage</span>
                <code>{log.requestMethod} {log.requestPath}</code>
              </div>
            )}
            {log.userAgent && (
              <div className="detail-row">
                <span className="detail-label">Browser</span>
                <span>{parseUA(log.userAgent)}</span>
                <span className="detail-ua-full" title={log.userAgent}>ⓘ</span>
              </div>
            )}
            {log.errorMessage && (
              <div className="detail-row detail-error">
                <span className="detail-label">Fehler</span>
                <span>{log.errorMessage}</span>
              </div>
            )}
            {hasMeta && (
              <div className="detail-row">
                <span className="detail-label">Details</span>
                <span>
                  {Object.entries(log.metadata).map(([k, v]) => (
                    <span key={k} className="meta-tag">{k}: <strong>{String(v)}</strong></span>
                  ))}
                </span>
              </div>
            )}
            {hasDiff && (
              <div className="detail-diff">
                <div className="detail-label">Änderungen</div>
                {renderDiff(log.changes)}
              </div>
            )}
          </div>
        )}
      </div>
    );
  };

  // ── main render ───────────────────────────────────────────────────────────────

  return (
    <div className="audit-logs-container">
      <div className="audit-header">
        <div className="audit-header-row">
          <div>
            <h2>📋 Audit-Logs</h2>
            <p className="audit-description">Vollständiges Protokoll aller Admin-Aktionen</p>
          </div>
          <div className="audit-header-actions">
            <label className="auto-refresh-toggle">
              <input type="checkbox" checked={autoRefresh}
                     onChange={e => setAutoRefresh(e.target.checked)} />
              Auto-Refresh (30 s)
            </label>
            <button className="btn-export" onClick={handleExport} disabled={exporting}>
              {exporting ? 'Exportiere…' : '⬇️ CSV exportieren'}
            </button>
          </div>
        </div>

        <div className="stats-toggle-bar">
          <button className="btn-stats-toggle" onClick={() => setShowStats(s => !s)}>
            {showStats ? '▲ Statistiken ausblenden' : '▼ Statistiken anzeigen'}
          </button>
          {showStats && (
            <select value={statsDays} onChange={e => setStatsDays(Number(e.target.value))}
                    className="filter-select stats-days-select">
              <option value={7}>7 Tage</option>
              <option value={30}>30 Tage</option>
              <option value={90}>90 Tage</option>
              <option value={365}>365 Tage</option>
            </select>
          )}
        </div>
        {showStats && renderStats()}
      </div>

      <div className="audit-filters">
        <select value={filters.action} onChange={e => setFilter('action', e.target.value)} className="filter-select">
          <option value="">Alle Aktionen</option>
          {Object.entries(ACTION_LABELS).map(([k, v]) => (
            <option key={k} value={k}>{ACTION_ICONS[k]} {v}</option>
          ))}
        </select>

        <select value={filters.resource} onChange={e => setFilter('resource', e.target.value)} className="filter-select">
          <option value="">Alle Ressourcen</option>
          <option value="User">Benutzer</option>
          <option value="Admin">Admin</option>
          <option value="Config">Konfiguration</option>
          <option value="Handler">Handler</option>
        </select>

        <select value={filters.success} onChange={e => setFilter('success', e.target.value)} className="filter-select">
          <option value="">Alle Status</option>
          <option value="true">✓ Erfolgreich</option>
          <option value="false">✗ Fehlgeschlagen</option>
        </select>

        <input type="text" placeholder="Admin-Name…" value={filters.adminUsername}
               onChange={e => setFilter('adminUsername', e.target.value)} className="filter-input" />

        <input type="date" value={filters.startDate}
               onChange={e => setFilter('startDate', e.target.value)} className="filter-input filter-date"
               title="Von Datum" />
        <input type="date" value={filters.endDate}
               onChange={e => setFilter('endDate', e.target.value)} className="filter-input filter-date"
               title="Bis Datum" />

        <button onClick={loadLogs} className="btn-refresh" disabled={loading}>
          🔄 {loading ? 'Lädt…' : 'Aktualisieren'}
        </button>
        <button onClick={resetFilters} className="btn-reset">✕ Zurücksetzen</button>
      </div>

      {error && <div className="audit-error"><p>{error}</p></div>}

      <div className="audit-results-bar">
        {pagination.total != null && (
          <span>{pagination.total} Einträge gefunden</span>
        )}
        <select value={filters.limit} onChange={e => setFilter('limit', Number(e.target.value))}
                className="filter-select limit-select">
          <option value={10}>10 pro Seite</option>
          <option value={25}>25 pro Seite</option>
          <option value={50}>50 pro Seite</option>
          <option value={100}>100 pro Seite</option>
        </select>
      </div>

      <div className="audit-list">
        {loading && logs.length === 0
          ? <div className="audit-empty">Lade Logs…</div>
          : logs.length === 0
            ? <div className="audit-empty">Keine Logs gefunden</div>
            : logs.map(renderLogItem)
        }
      </div>

      {pagination.pages > 1 && (
        <div className="audit-pagination">
          <button onClick={() => setFilters(f => ({ ...f, page: 1 }))}
                  disabled={filters.page === 1} className="btn-page">«</button>
          <button onClick={() => setFilters(f => ({ ...f, page: f.page - 1 }))}
                  disabled={filters.page === 1} className="btn-page">‹ Zurück</button>
          <span className="page-info">
            Seite {filters.page} / {pagination.pages}
          </span>
          <button onClick={() => setFilters(f => ({ ...f, page: f.page + 1 }))}
                  disabled={filters.page >= pagination.pages} className="btn-page">Weiter ›</button>
          <button onClick={() => setFilters(f => ({ ...f, page: pagination.pages }))}
                  disabled={filters.page >= pagination.pages} className="btn-page">»</button>
        </div>
      )}
    </div>
  );
}

export default AuditLogs;
