import { useState, useMemo } from 'react';
import type { ExecutionSummary } from '../../api/schema-types';
import { StatusPill } from '../../components/shared/StatusPill';
import { DurationBar } from '../../components/shared/DurationBar';
import { AppBadge } from '../../components/shared/AppBadge';
import { ProcessorTree } from './ProcessorTree';
import { ExchangeDetail } from './ExchangeDetail';
import styles from './ResultsTable.module.css';

interface ResultsTableProps {
  results: ExecutionSummary[];
  loading: boolean;
}

type SortColumn = 'startTime' | 'status' | 'agentId' | 'routeId' | 'correlationId' | 'durationMs';
type SortDir = 'asc' | 'desc';

function formatTime(iso: string) {
  return new Date(iso).toLocaleTimeString('en-GB', {
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
    fractionalSecondDigits: 3,
  });
}

function compareFn(a: ExecutionSummary, b: ExecutionSummary, col: SortColumn, dir: SortDir): number {
  let cmp = 0;
  switch (col) {
    case 'startTime':
      cmp = a.startTime.localeCompare(b.startTime);
      break;
    case 'status':
      cmp = a.status.localeCompare(b.status);
      break;
    case 'agentId':
      cmp = a.agentId.localeCompare(b.agentId);
      break;
    case 'routeId':
      cmp = a.routeId.localeCompare(b.routeId);
      break;
    case 'correlationId':
      cmp = (a.correlationId ?? '').localeCompare(b.correlationId ?? '');
      break;
    case 'durationMs':
      cmp = a.durationMs - b.durationMs;
      break;
  }
  return dir === 'asc' ? cmp : -cmp;
}

interface SortableThProps {
  label: string;
  column: SortColumn;
  activeColumn: SortColumn | null;
  direction: SortDir;
  onSort: (col: SortColumn) => void;
  style?: React.CSSProperties;
}

function SortableTh({ label, column, activeColumn, direction, onSort, style }: SortableThProps) {
  const isActive = activeColumn === column;
  return (
    <th
      className={`${styles.th} ${styles.thSortable} ${isActive ? styles.thActive : ''}`}
      style={style}
      onClick={() => onSort(column)}
    >
      {label}
      <span className={styles.sortArrow}>
        {isActive ? (direction === 'asc' ? '\u25B2' : '\u25BC') : '\u25B4'}
      </span>
    </th>
  );
}

export function ResultsTable({ results, loading }: ResultsTableProps) {
  const [expandedId, setExpandedId] = useState<string | null>(null);
  const [sortColumn, setSortColumn] = useState<SortColumn | null>(null);
  const [sortDir, setSortDir] = useState<SortDir>('desc');

  const sortedResults = useMemo(() => {
    if (!sortColumn) return results;
    return [...results].sort((a, b) => compareFn(a, b, sortColumn, sortDir));
  }, [results, sortColumn, sortDir]);

  function handleSort(col: SortColumn) {
    if (sortColumn === col) {
      setSortDir((d) => (d === 'asc' ? 'desc' : 'asc'));
    } else {
      setSortColumn(col);
      setSortDir('desc');
    }
  }

  if (loading && results.length === 0) {
    return (
      <div className={styles.tableWrap}>
        <div className={styles.loadingOverlay}>Loading executions...</div>
      </div>
    );
  }

  if (results.length === 0) {
    return (
      <div className={styles.tableWrap}>
        <div className={styles.emptyState}>No executions found matching your filters.</div>
      </div>
    );
  }

  return (
    <div className={styles.tableWrap}>
      <table className={styles.table}>
        <thead className={styles.thead}>
          <tr>
            <th className={styles.th} style={{ width: 32 }} />
            <SortableTh label="Timestamp" column="startTime" activeColumn={sortColumn} direction={sortDir} onSort={handleSort} />
            <SortableTh label="Status" column="status" activeColumn={sortColumn} direction={sortDir} onSort={handleSort} />
            <SortableTh label="Application" column="agentId" activeColumn={sortColumn} direction={sortDir} onSort={handleSort} />
            <SortableTh label="Route" column="routeId" activeColumn={sortColumn} direction={sortDir} onSort={handleSort} />
            <SortableTh label="Correlation ID" column="correlationId" activeColumn={sortColumn} direction={sortDir} onSort={handleSort} />
            <SortableTh label="Duration" column="durationMs" activeColumn={sortColumn} direction={sortDir} onSort={handleSort} />
          </tr>
        </thead>
        <tbody>
          {sortedResults.map((exec) => {
            const isExpanded = expandedId === exec.executionId;
            return (
              <ResultRow
                key={exec.executionId}
                exec={exec}
                isExpanded={isExpanded}
                onToggle={() => setExpandedId(isExpanded ? null : exec.executionId)}
              />
            );
          })}
        </tbody>
      </table>
    </div>
  );
}

function ResultRow({
  exec,
  isExpanded,
  onToggle,
}: {
  exec: ExecutionSummary;
  isExpanded: boolean;
  onToggle: () => void;
}) {
  return (
    <>
      <tr
        className={`${styles.row} ${isExpanded ? styles.expanded : ''}`}
        onClick={onToggle}
      >
        <td className={`${styles.td} ${styles.tdExpand}`}>&rsaquo;</td>
        <td className={`${styles.td} mono`}>{formatTime(exec.startTime)}</td>
        <td className={styles.td}>
          <StatusPill status={exec.status} />
        </td>
        <td className={styles.td}>
          <AppBadge name={exec.agentId} />
        </td>
        <td className={`${styles.td} mono text-secondary`}>{exec.routeId}</td>
        <td className={`${styles.td} mono text-muted ${styles.correlationId}`} title={exec.correlationId ?? ''}>
          {exec.correlationId ?? '-'}
        </td>
        <td className={styles.td}>
          <DurationBar duration={exec.durationMs} />
        </td>
      </tr>
      {isExpanded && (
        <tr className={styles.detailRowVisible}>
          <td className={styles.detailCell} colSpan={7}>
            <div className={styles.detailContent}>
              <ProcessorTree executionId={exec.executionId} />
              <ExchangeDetail execution={exec} />
            </div>
          </td>
        </tr>
      )}
    </>
  );
}
