'use client';

import { useState, useEffect, useCallback } from 'react';
import {
  Download,
  RefreshCw,
  Filter,
  Activity,
  AlertTriangle,
  Info,
  Bug,
  Server,
} from 'lucide-react';

const LOG_EXPORTER_URL =
  process.env.NEXT_PUBLIC_LOG_EXPORTER_URL || 'http://localhost:3200';

// ─── Types ────────────────────────────────────────────────────────────────────

interface LogEntry {
  timestamp: string;
  service: string;
  level: string;
  context: string;
  message: string;
  reqId: string;
  req_method: string;
  req_url: string;
  res_status: string;
  response_time_ms: string;
  error: string;
}

interface LogsResponse {
  total: number;
  query: string;
  range: { from: string; to: string };
  logs: LogEntry[];
}

interface Filters {
  service: string;
  level: string;
  search: string;
  startDate: string;
  endDate: string;
  limit: string;
}

// ─── Helpers ──────────────────────────────────────────────────────────────────

const LEVEL_STYLES: Record<string, string> = {
  error: 'bg-red-100 text-red-700 border border-red-200',
  fatal: 'bg-red-200 text-red-900 border border-red-300',
  warn: 'bg-yellow-100 text-yellow-700 border border-yellow-200',
  info: 'bg-blue-100 text-blue-700 border border-blue-200',
  debug: 'bg-gray-100 text-gray-600 border border-gray-200',
  trace: 'bg-purple-100 text-purple-700 border border-purple-200',
};

const LEVEL_ROW_BG: Record<string, string> = {
  error: 'bg-red-50',
  fatal: 'bg-red-100',
  warn: 'bg-yellow-50',
  info: '',
  debug: '',
  trace: '',
};

function LevelBadge({ level }: { level: string }) {
  const style = LEVEL_STYLES[level] || 'bg-gray-100 text-gray-600';
  return (
    <span className={`inline-block px-2 py-0.5 rounded text-xs font-mono font-semibold uppercase ${style}`}>
      {level}
    </span>
  );
}

function StatCard({
  label,
  value,
  icon: Icon,
  color,
}: {
  label: string;
  value: number | string;
  icon: any;
  color: string;
}) {
  return (
    <div className="bg-white rounded-lg border p-4 flex items-center gap-4">
      <div className={`p-2 rounded-lg ${color}`}>
        <Icon className="h-5 w-5" />
      </div>
      <div>
        <p className="text-2xl font-bold text-gray-900">{value}</p>
        <p className="text-sm text-gray-500">{label}</p>
      </div>
    </div>
  );
}

// ─── Page ─────────────────────────────────────────────────────────────────────

export default function AdminLogsPage() {
  const [logs, setLogs] = useState<LogEntry[]>([]);
  const [services, setServices] = useState<string[]>([]);
  const [loading, setLoading] = useState(false);
  const [exportLoading, setExportLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [total, setTotal] = useState(0);
  const [expandedRow, setExpandedRow] = useState<number | null>(null);

  const now = new Date();
  const oneHourAgo = new Date(now.getTime() - 60 * 60 * 1000);

  const [filters, setFilters] = useState<Filters>({
    service: 'all',
    level: 'all',
    search: '',
    startDate: oneHourAgo.toISOString().slice(0, 16),
    endDate: now.toISOString().slice(0, 16),
    limit: '500',
  });

  // Load available services
  useEffect(() => {
    fetch(`${LOG_EXPORTER_URL}/api/logs/services`)
      .then(r => r.json())
      .then(d => setServices(d.services || []))
      .catch(() => {});
  }, []);

  const buildQueryString = useCallback(
    (fmt?: string) => {
      const params = new URLSearchParams();
      if (filters.service !== 'all') params.set('service', filters.service);
      if (filters.level !== 'all') params.set('level', filters.level);
      if (filters.search) params.set('search', filters.search);
      if (filters.startDate) params.set('start', new Date(filters.startDate).toISOString());
      if (filters.endDate) params.set('end', new Date(filters.endDate).toISOString());
      params.set('limit', filters.limit);
      if (fmt) params.set('format', fmt);
      return params.toString();
    },
    [filters],
  );

  const fetchLogs = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const res = await fetch(
        `${LOG_EXPORTER_URL}/api/logs/export?${buildQueryString('json')}`,
      );
      if (!res.ok) {
        const body = await res.json().catch(() => ({}));
        throw new Error(body.error || `HTTP ${res.status}`);
      }
      const data: LogsResponse = await res.json();
      setLogs(data.logs || []);
      setTotal(data.total || 0);
    } catch (err: any) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  }, [buildQueryString]);

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

  const handleExport = async (format: 'json' | 'csv') => {
    setExportLoading(true);
    try {
      const res = await fetch(
        `${LOG_EXPORTER_URL}/api/logs/export?${buildQueryString(format)}`,
      );
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      const blob = await res.blob();
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `xpeditis-logs-${new Date().toISOString().slice(0, 10)}.${format}`;
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      URL.revokeObjectURL(url);
    } catch (err: any) {
      setError(err.message);
    } finally {
      setExportLoading(false);
    }
  };

  // Stats
  const countByLevel = (level: string) =>
    logs.filter(l => l.level === level).length;

  const setFilter = (key: keyof Filters, value: string) =>
    setFilters(prev => ({ ...prev, [key]: value }));

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold text-gray-900">Logs système</h1>
          <p className="mt-1 text-sm text-gray-500">
            Visualisation et export des logs applicatifs en temps réel
          </p>
        </div>
        <div className="flex items-center gap-2">
          <button
            onClick={fetchLogs}
            disabled={loading}
            className="flex items-center gap-2 px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors disabled:opacity-50"
          >
            <RefreshCw className={`h-4 w-4 ${loading ? 'animate-spin' : ''}`} />
            Actualiser
          </button>
          <div className="relative group">
            <button
              disabled={exportLoading || loading}
              className="flex items-center gap-2 px-4 py-2 text-sm font-medium text-white bg-[#10183A] rounded-lg hover:bg-[#1a2550] transition-colors disabled:opacity-50"
            >
              <Download className="h-4 w-4" />
              {exportLoading ? 'Export...' : 'Exporter'}
            </button>
            <div className="absolute right-0 mt-1 w-36 bg-white rounded-lg shadow-lg border border-gray-200 z-10 hidden group-hover:block">
              <button
                onClick={() => handleExport('csv')}
                className="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-50"
              >
                Télécharger CSV
              </button>
              <button
                onClick={() => handleExport('json')}
                className="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-50"
              >
                Télécharger JSON
              </button>
            </div>
          </div>
        </div>
      </div>

      {/* Stats */}
      <div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
        <StatCard
          label="Total logs"
          value={total}
          icon={Activity}
          color="bg-blue-100 text-blue-600"
        />
        <StatCard
          label="Erreurs"
          value={countByLevel('error') + countByLevel('fatal')}
          icon={AlertTriangle}
          color="bg-red-100 text-red-600"
        />
        <StatCard
          label="Warnings"
          value={countByLevel('warn')}
          icon={AlertTriangle}
          color="bg-yellow-100 text-yellow-600"
        />
        <StatCard
          label="Info"
          value={countByLevel('info')}
          icon={Info}
          color="bg-green-100 text-green-600"
        />
      </div>

      {/* Filters */}
      <div className="bg-white rounded-lg border p-4">
        <div className="flex items-center gap-2 mb-4">
          <Filter className="h-4 w-4 text-gray-500" />
          <h2 className="text-sm font-semibold text-gray-700">Filtres</h2>
        </div>
        <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6 gap-3">
          {/* Service */}
          <div>
            <label className="block text-xs font-medium text-gray-500 mb-1">Service</label>
            <select
              value={filters.service}
              onChange={e => setFilter('service', e.target.value)}
              className="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-[#34CCCD] focus:border-[#34CCCD] focus:outline-none"
            >
              <option value="all">Tous</option>
              {services.map(s => (
                <option key={s} value={s}>
                  {s}
                </option>
              ))}
            </select>
          </div>

          {/* Level */}
          <div>
            <label className="block text-xs font-medium text-gray-500 mb-1">Niveau</label>
            <select
              value={filters.level}
              onChange={e => setFilter('level', e.target.value)}
              className="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-[#34CCCD] focus:border-[#34CCCD] focus:outline-none"
            >
              <option value="all">Tous</option>
              <option value="error">Error</option>
              <option value="fatal">Fatal</option>
              <option value="warn">Warn</option>
              <option value="info">Info</option>
              <option value="debug">Debug</option>
            </select>
          </div>

          {/* Search */}
          <div>
            <label className="block text-xs font-medium text-gray-500 mb-1">Recherche</label>
            <input
              type="text"
              placeholder="Texte libre..."
              value={filters.search}
              onChange={e => setFilter('search', e.target.value)}
              onKeyDown={e => e.key === 'Enter' && fetchLogs()}
              className="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-[#34CCCD] focus:border-[#34CCCD] focus:outline-none"
            />
          </div>

          {/* Start */}
          <div>
            <label className="block text-xs font-medium text-gray-500 mb-1">Début</label>
            <input
              type="datetime-local"
              value={filters.startDate}
              onChange={e => setFilter('startDate', e.target.value)}
              className="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-[#34CCCD] focus:border-[#34CCCD] focus:outline-none"
            />
          </div>

          {/* End */}
          <div>
            <label className="block text-xs font-medium text-gray-500 mb-1">Fin</label>
            <input
              type="datetime-local"
              value={filters.endDate}
              onChange={e => setFilter('endDate', e.target.value)}
              className="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-[#34CCCD] focus:border-[#34CCCD] focus:outline-none"
            />
          </div>

          {/* Limit + Apply */}
          <div className="flex flex-col justify-end gap-2">
            <label className="block text-xs font-medium text-gray-500">Limite</label>
            <div className="flex gap-2">
              <select
                value={filters.limit}
                onChange={e => setFilter('limit', e.target.value)}
                className="flex-1 px-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-[#34CCCD] focus:outline-none"
              >
                <option value="100">100</option>
                <option value="500">500</option>
                <option value="1000">1000</option>
                <option value="5000">5000</option>
              </select>
              <button
                onClick={fetchLogs}
                disabled={loading}
                className="px-3 py-2 text-sm font-medium text-white bg-[#34CCCD] rounded-lg hover:bg-[#2bb8b9] transition-colors disabled:opacity-50 whitespace-nowrap"
              >
                Filtrer
              </button>
            </div>
          </div>
        </div>
      </div>

      {/* Error */}
      {error && (
        <div className="bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded-lg flex items-center gap-2">
          <AlertTriangle className="h-4 w-4 flex-shrink-0" />
          <span className="text-sm">
            Impossible de contacter le log-exporter : <strong>{error}</strong>
            <br />
            <span className="text-xs text-red-500">
              Vérifiez que le container log-exporter est démarré sur{' '}
              <code className="font-mono">{LOG_EXPORTER_URL}</code>
            </span>
          </span>
        </div>
      )}

      {/* Table */}
      <div className="bg-white rounded-lg border overflow-hidden">
        <div className="px-4 py-3 border-b bg-gray-50 flex items-center justify-between">
          <div className="flex items-center gap-2">
            <Server className="h-4 w-4 text-gray-500" />
            <span className="text-sm font-medium text-gray-700">
              {loading ? 'Chargement...' : `${total} entrée${total !== 1 ? 's' : ''}`}
            </span>
          </div>
          {!loading && logs.length > 0 && (
            <span className="text-xs text-gray-400">
              Cliquer sur une ligne pour les détails
            </span>
          )}
        </div>

        {loading ? (
          <div className="flex items-center justify-center h-40">
            <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-[#34CCCD]" />
          </div>
        ) : logs.length === 0 && !error ? (
          <div className="flex flex-col items-center justify-center h-40 text-gray-400 gap-2">
            <Bug className="h-8 w-8" />
            <p className="text-sm">Aucun log trouvé pour ces filtres</p>
          </div>
        ) : (
          <div className="overflow-x-auto">
            <table className="min-w-full text-sm">
              <thead className="bg-gray-50 border-b">
                <tr>
                  <th className="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase whitespace-nowrap">
                    Timestamp
                  </th>
                  <th className="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">
                    Service
                  </th>
                  <th className="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">
                    Niveau
                  </th>
                  <th className="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">
                    Contexte
                  </th>
                  <th className="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">
                    Message
                  </th>
                  <th className="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase whitespace-nowrap">
                    Req / Status
                  </th>
                </tr>
              </thead>
              <tbody className="divide-y divide-gray-100">
                {logs.map((log, i) => (
                  <>
                    <tr
                      key={i}
                      onClick={() => setExpandedRow(expandedRow === i ? null : i)}
                      className={`cursor-pointer hover:bg-gray-50 transition-colors ${LEVEL_ROW_BG[log.level] || ''}`}
                    >
                      <td className="px-4 py-2 font-mono text-xs text-gray-500 whitespace-nowrap">
                        {new Date(log.timestamp).toLocaleString('fr-FR', {
                          day: '2-digit',
                          month: '2-digit',
                          hour: '2-digit',
                          minute: '2-digit',
                          second: '2-digit',
                        })}
                      </td>
                      <td className="px-4 py-2 whitespace-nowrap">
                        <span className="px-2 py-0.5 bg-[#10183A] text-white text-xs rounded font-mono">
                          {log.service}
                        </span>
                      </td>
                      <td className="px-4 py-2 whitespace-nowrap">
                        <LevelBadge level={log.level} />
                      </td>
                      <td className="px-4 py-2 text-xs text-gray-500 whitespace-nowrap">
                        {log.context || '—'}
                      </td>
                      <td className="px-4 py-2 max-w-xs">
                        <span className="line-clamp-1 text-gray-800">
                          {log.error ? (
                            <span className="text-red-600">{log.error}</span>
                          ) : (
                            log.message
                          )}
                        </span>
                      </td>
                      <td className="px-4 py-2 font-mono text-xs text-gray-500 whitespace-nowrap">
                        {log.req_method && (
                          <span>
                            <span className="font-semibold">{log.req_method}</span>{' '}
                            {log.req_url}{' '}
                            {log.res_status && (
                              <span
                                className={
                                  String(log.res_status).startsWith('5')
                                    ? 'text-red-500 font-bold'
                                    : String(log.res_status).startsWith('4')
                                      ? 'text-yellow-600 font-bold'
                                      : 'text-green-600'
                                }
                              >
                                {log.res_status}
                              </span>
                            )}
                          </span>
                        )}
                      </td>
                    </tr>

                    {/* Expanded detail row */}
                    {expandedRow === i && (
                      <tr key={`detail-${i}`} className="bg-gray-50">
                        <td colSpan={6} className="px-4 py-3">
                          <div className="grid grid-cols-2 md:grid-cols-4 gap-3 text-xs">
                            <div>
                              <span className="font-semibold text-gray-600">Timestamp</span>
                              <p className="font-mono text-gray-800 mt-0.5">{log.timestamp}</p>
                            </div>
                            {log.reqId && (
                              <div>
                                <span className="font-semibold text-gray-600">Request ID</span>
                                <p className="font-mono text-gray-800 mt-0.5 truncate">{log.reqId}</p>
                              </div>
                            )}
                            {log.response_time_ms && (
                              <div>
                                <span className="font-semibold text-gray-600">Durée</span>
                                <p className="font-mono text-gray-800 mt-0.5">
                                  {log.response_time_ms} ms
                                </p>
                              </div>
                            )}
                            <div className="col-span-2 md:col-span-4">
                              <span className="font-semibold text-gray-600">Message complet</span>
                              <pre className="mt-0.5 p-2 bg-white rounded border font-mono text-gray-800 overflow-x-auto whitespace-pre-wrap break-all">
                                {log.error
                                  ? `[ERROR] ${log.error}\n\n${log.message}`
                                  : log.message}
                              </pre>
                            </div>
                          </div>
                        </td>
                      </tr>
                    )}
                  </>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </div>
    </div>
  );
}
