import React, { useCallback, useEffect, useMemo, useState } from 'react';
import {
  createColumnHelper,
  flexRender,
  getCoreRowModel,
  getFilteredRowModel,
  getSortedRowModel,
  getPaginationRowModel,
  useReactTable
} from '@tanstack/react-table';

const formatDateTime = (value) => {
  if (!value) {
    return '';
  }
  try {
    return new Date(value).toLocaleString();
  } catch {
    return String(value);
  }
};

const DirectionBadge = ({ value }) => {
  const base = 'px-2 py-1 text-xs rounded-full font-semibold';
  if (value === 'outgoing') {
    return <span className={`${base} bg-purple-100 text-purple-700`}>Outgoing</span>;
  }
  return <span className={`${base} bg-blue-100 text-blue-700`}>Incoming</span>;
};

const StatusBadge = ({ status }) => {
  const code = Number(status);
  let color = 'bg-gray-100 text-gray-700';
  if (code >= 500) {
    color = 'bg-red-100 text-red-700';
  } else if (code >= 400) {
    color = 'bg-amber-100 text-amber-800';
  } else if (code > 0) {
    color = 'bg-green-100 text-green-700';
  }
  return <span className={`px-2 py-1 text-xs rounded-full font-semibold ${color}`}>{status ?? '—'}</span>;
};

const buildRequestLink = (path, target) => {
  if (!path) {
    return null;
  }
  const trimmed = String(path).trim();
  if (/^https?:\/\//i.test(trimmed)) {
    return trimmed;
  }
  let base = '';
  if (target) {
    const normalizedTarget = String(target).trim().replace(/\/+$/, '');
    base = /^https?:\/\//i.test(normalizedTarget)
      ? normalizedTarget
      : `https://${normalizedTarget}`;
  } else if (typeof window !== 'undefined' && window.location?.origin) {
    base = window.location.origin;
  }
  if (!base) {
    return null;
  }
  const normalizedPath = trimmed.startsWith('/') ? trimmed : `/${trimmed}`;
  return `${base}${normalizedPath}`;
};

const DebugPage = ({ authorizedFetch }) => {
  const [logs, setLogs] = useState([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');
  const columnHelper = useMemo(() => createColumnHelper(), []);
  const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 100 });
  const [expandedId, setExpandedId] = useState(null);

  const TABLE_STATE_KEY = 'debugRequestsTableState';

  const readTableState = useCallback(() => {
    if (typeof window === 'undefined') {
      return { sorting: [], columnFilters: [] };
    }
    try {
      const raw = window.localStorage.getItem(TABLE_STATE_KEY);
      if (!raw) {
        return { sorting: [], columnFilters: [] };
      }
      const parsed = JSON.parse(raw);
      return {
        sorting: Array.isArray(parsed.sorting) ? parsed.sorting : [],
        columnFilters: Array.isArray(parsed.columnFilters) ? parsed.columnFilters : []
      };
    } catch {
      return { sorting: [], columnFilters: [] };
    }
  }, []);

  const persistTableState = useCallback((state) => {
    if (typeof window === 'undefined') {
      return;
    }
    try {
      window.localStorage.setItem(TABLE_STATE_KEY, JSON.stringify(state));
    } catch {
      /* ignore */
    }
  }, []);

  const fetchLogs = useCallback(async () => {
    setLoading(true);
    setError('');
    try {
      const response = await authorizedFetch('/api/debug/requests');
      if (!response.ok) {
        throw new Error(`HTTP ${response.status}`);
      }
      const data = await response.json();
      setLogs(Array.isArray(data.logs) ? data.logs : []);
    } catch (err) {
      setError(`Logs konnten nicht geladen werden: ${err.message}`);
    } finally {
      setLoading(false);
    }
  }, [authorizedFetch]);

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

  const rows = useMemo(() => logs.map((entry) => ({
    id: entry.id,
    direction: entry.direction || 'incoming',
    method: entry.method || '',
    path: entry.path || '',
    status: entry.status ?? null,
    durationMs: entry.durationMs ?? null,
    timestamp: entry.timestamp,
    profileId: entry.profileId || null,
    profileName: entry.profileName || null,
    sessionId: entry.sessionId || null,
    target: entry.target || null,
    error: entry.error || null,
    responseBody: entry.responseBody || null
  })), [logs]);

  const ColumnTextFilter = ({ column, placeholder }) => {
    if (!column.getCanFilter()) {
      return null;
    }
    return (
      <input
        type="text"
        value={column.getFilterValue() ?? ''}
        onChange={(event) => column.setFilterValue(event.target.value || undefined)}
        placeholder={placeholder}
        className="mt-1 w-full rounded border px-2 py-1 text-xs focus:outline-none focus:ring-1 focus:ring-blue-500"
      />
    );
  };

  const SortableHeader = ({ column, label, placeholder }) => (
    <div className="flex flex-col">
      <button
        type="button"
        className="flex items-center justify-between text-left font-semibold whitespace-nowrap"
        onClick={column.getToggleSortingHandler()}
      >
        <span>{label}</span>
        {column.getIsSorted() ? (
          <span className="text-xs text-gray-500">{column.getIsSorted() === 'asc' ? '▲' : '▼'}</span>
        ) : (
          <span className="text-xs text-gray-400">⇅</span>
        )}
      </button>
      <ColumnTextFilter column={column} placeholder={placeholder} />
    </div>
  );

  const columns = useMemo(
    () => [
      columnHelper.accessor('timestamp', {
        header: ({ column }) => <SortableHeader column={column} label="Zeitpunkt" placeholder="z. B. 2024" />,
        cell: ({ getValue }) => formatDateTime(getValue()),
        sortingFn: 'datetime',
        filterFn: 'includesString'
      }),
      columnHelper.accessor('direction', {
        header: ({ column }) => (
          <SortableHeader column={column} label="Richtung" placeholder="incoming/outgoing" />
        ),
        cell: ({ row }) => (
          <div className="flex items-center gap-2">
            <DirectionBadge value={row.original.direction} />
            {row.original.target && <span className="text-xs text-gray-500">{row.original.target}</span>}
          </div>
        ),
        sortingFn: 'alphanumeric',
        filterFn: 'includesString'
      }),
      columnHelper.accessor('method', {
        header: ({ column }) => <SortableHeader column={column} label="Methode" placeholder="GET, POST…" />,
        cell: ({ getValue }) => <span className="font-mono text-xs uppercase">{getValue()}</span>,
        sortingFn: 'alphanumeric',
        filterFn: 'includesString'
      }),
      columnHelper.accessor('path', {
        header: ({ column }) => <SortableHeader column={column} label="Pfad / Ziel" placeholder="/api/…" />,
        cell: ({ getValue, row }) => {
          const value = getValue();
          const href = buildRequestLink(value, row.original.target);
          if (!href) {
            return (
              <span className="max-w-xs truncate block whitespace-nowrap" title={value}>
                {value || '—'}
              </span>
            );
          }
          return (
            <a
              href={href}
              target="_blank"
              rel="noreferrer"
              onClick={(event) => event.stopPropagation()}
              className="max-w-xs truncate block whitespace-nowrap text-blue-600 hover:underline"
              title={href}
            >
              {value || href}
            </a>
          );
        },
        sortingFn: 'alphanumeric',
        filterFn: 'includesString'
      }),
      columnHelper.accessor('status', {
        header: ({ column }) => <SortableHeader column={column} label="Status" placeholder="200, 500…" />,
        cell: ({ getValue }) => <StatusBadge status={getValue()} />,
        sortingFn: 'alphanumeric',
        filterFn: 'includesString'
      }),
      columnHelper.accessor('durationMs', {
        header: ({ column }) => <SortableHeader column={column} label="Dauer (ms)" placeholder="z. B. >100" />,
        cell: ({ getValue }) => (getValue() != null ? getValue() : '—'),
        sortingFn: 'alphanumeric',
        filterFn: 'includesString'
      }),
      columnHelper.accessor(
        (row) => row.profileName || row.profileId || '',
        {
          id: 'profile',
          header: ({ column }) => <SortableHeader column={column} label="Profil" placeholder="Profil-Name" />,
          cell: ({ row }) => {
            const name = row.original.profileName;
            const value = row.original.profileId;
            return (
              <span className="text-xs text-gray-600" title={value || ''}>
                {name || value || '—'}
              </span>
            );
          },
        sortingFn: 'alphanumeric',
        filterFn: 'includesString'
        }
      ),
      columnHelper.accessor('sessionId', {
        header: ({ column }) => <SortableHeader column={column} label="Session" placeholder="Session-ID" />,
        cell: ({ getValue }) => {
          const value = getValue();
          return (
            <span className="text-xs text-gray-600 max-w-xs truncate block whitespace-nowrap" title={value || ''}>
              {value || '—'}
            </span>
          );
        },
        sortingFn: 'alphanumeric',
        filterFn: 'includesString'
      }),
      columnHelper.accessor('error', {
        header: ({ column }) => <SortableHeader column={column} label="Fehler" placeholder="Fehlermeldung" />,
        cell: ({ getValue }) => {
          const value = getValue();
          return (
            <span className="text-xs text-gray-600 max-w-xs truncate block whitespace-nowrap" title={value || ''}>
              {value || '—'}
            </span>
          );
        },
        sortingFn: 'alphanumeric',
        filterFn: 'includesString'
      })
    ],
    [columnHelper]
  );

  const initialState = useMemo(() => readTableState(), [readTableState]);
  const [tableSorting, setTableSorting] = useState(initialState.sorting.length ? initialState.sorting : [{ id: 'timestamp', desc: true }]);
  const [tableFilters, setTableFilters] = useState(initialState.columnFilters);

  useEffect(() => {
    persistTableState({ sorting: tableSorting, columnFilters: tableFilters });
  }, [tableFilters, tableSorting, persistTableState]);

  const table = useReactTable({
    data: rows,
    columns,
    state: {
      sorting: tableSorting,
      columnFilters: tableFilters,
      pagination
    },
    onSortingChange: setTableSorting,
    onColumnFiltersChange: setTableFilters,
    onPaginationChange: setPagination,
    getCoreRowModel: getCoreRowModel(),
    getSortedRowModel: getSortedRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
    getPaginationRowModel: getPaginationRowModel()
  });

  return (
    <div className="p-4 max-w-7xl w-full mx-auto bg-white shadow-lg rounded-lg mt-4">
      <div className="flex items-center justify-between mb-4">
        <div>
          <h1 className="text-2xl font-bold text-gray-800">Request-Debug</h1>
          <p className="text-gray-500 text-sm">Alle Requests der letzten 4 Wochen</p>
        </div>
        <button
          onClick={fetchLogs}
          className="bg-blue-500 hover:bg-blue-600 text-white py-2 px-4 rounded focus:outline-none focus:ring-2 focus:ring-blue-500 transition-colors"
          disabled={loading}
        >
          {loading ? 'Lade…' : 'Neu laden'}
        </button>
      </div>
      {error && (
        <div className="mb-4 rounded border border-red-200 bg-red-50 text-red-700 px-4 py-2">
          {error}
        </div>
      )}
      <div className="overflow-x-auto">
        <table className="min-w-full text-sm">
          <thead className="bg-gray-50">
            {table.getHeaderGroups().map((headerGroup) => (
              <tr key={headerGroup.id}>
                {headerGroup.headers.map((header) => (
                  <th key={header.id} className="px-4 py-2 text-left text-gray-600 align-top whitespace-nowrap">
                    {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}
                  </th>
                ))}
              </tr>
            ))}
          </thead>
          <tbody>
            {table.getRowModel().rows.length === 0 ? (
              <tr>
                <td colSpan={9} className="px-4 py-4 text-center text-gray-500">
                  Keine Einträge vorhanden.
                </td>
              </tr>
            ) : (
              table.getRowModel().rows.map((row) => {
                const isExpanded = expandedId === row.original.id;
                return (
                  <React.Fragment key={row.id}>
                    <tr
                      className={`border-b hover:bg-gray-50 cursor-pointer ${isExpanded ? 'bg-blue-50/40' : ''}`}
                      onClick={() => setExpandedId((prev) => (prev === row.original.id ? null : row.original.id))}
                    >
                      {row.getVisibleCells().map((cell) => (
                        <td key={cell.id} className="px-4 py-2 align-top whitespace-nowrap">
                          {flexRender(cell.column.columnDef.cell, cell.getContext())}
                        </td>
                      ))}
                    </tr>
                    {isExpanded && (
                      <tr className="border-b bg-gray-50">
                        <td colSpan={table.getVisibleLeafColumns().length} className="px-4 py-3">
                          <div className="text-sm text-gray-800">
                            <div className="flex flex-wrap gap-4 mb-2">
                              <span className="font-semibold">Details</span>
                              <span>Richtung: {row.original.direction}</span>
                              <span>Methode: {row.original.method}</span>
                              <span>Status: {row.original.status ?? '—'}</span>
                              <span>Dauer: {row.original.durationMs != null ? `${row.original.durationMs} ms` : '—'}</span>
                            </div>
                            <div>
                              <p className="font-semibold mb-1">Response-Body</p>
                              <pre className="bg-white border rounded p-3 text-xs whitespace-pre-wrap max-h-80 overflow-auto">
                                {row.original.responseBody || 'Keine Details erfasst.'}
                              </pre>
                            </div>
                          </div>
                        </td>
                      </tr>
                    )}
                  </React.Fragment>
                );
              })
            )}
          </tbody>
        </table>
      </div>
      <div className="flex items-center justify-between mt-4 text-sm text-gray-700 gap-4">
        <div className="flex items-center gap-2">
          <span>Zeilen pro Seite:</span>
          <select
            className="border rounded px-2 py-1 text-sm"
            value={pagination.pageSize}
            onChange={(event) => table.setPageSize(Number(event.target.value))}
          >
            {[25, 50, 100, 200].map((size) => (
              <option key={size} value={size}>
                {size}
              </option>
            ))}
          </select>
        </div>
        <div className="flex items-center gap-2">
          <button
            className="px-3 py-1 border rounded disabled:opacity-50"
            onClick={() => table.setPageIndex(0)}
            disabled={!table.getCanPreviousPage()}
          >
            «
          </button>
          <button
            className="px-3 py-1 border rounded disabled:opacity-50"
            onClick={() => table.previousPage()}
            disabled={!table.getCanPreviousPage()}
          >
            Zurück
          </button>
          <span>
            Seite {table.getState().pagination.pageIndex + 1} von {table.getPageCount() || 1}
          </span>
          <button
            className="px-3 py-1 border rounded disabled:opacity-50"
            onClick={() => table.nextPage()}
            disabled={!table.getCanNextPage()}
          >
            Weiter
          </button>
          <button
            className="px-3 py-1 border rounded disabled:opacity-50"
            onClick={() => table.setPageIndex(table.getPageCount() - 1)}
            disabled={!table.getCanNextPage()}
          >
            »
          </button>
        </div>
      </div>
    </div>
  );
};

export default DebugPage;
