import { LocalTask } from '../../api';
import { matchText } from '../../lib/utils';
import { COLUMN_LIST, SortMode, StatusColumn } from '../../lib/urlState';
import { FilterBar } from './FilterBar';
import { LocalTaskListItem } from './TaskListItem';
import { RailPanel } from './RailPanel';

interface TaskListPanelProps {
  localTasks: LocalTask[];
  selectedStatus: 'all' | StatusColumn;
  sortMode: SortMode;
  searchQuery: string;
  activeTaskId: number | null;
  onStatusChange: (status: 'all' | StatusColumn) => void;
  onSortChange: (sort: SortMode) => void;
  onSearchChange: (q: string) => void;
  onSelectTask: (id: number) => void;
  onOpenCreate: () => void;
  /** 'rail' 時は RailPanel を render する。default 'list'。 */
  mode?: 'list' | 'rail';
  /** rail mode 時の「リストに戻る」ボタンで呼ばれる。 */
  onExitFocused?: () => void;
}

export function TaskListPanel({
  localTasks,
  selectedStatus,
  sortMode,
  searchQuery,
  activeTaskId,
  onStatusChange,
  onSortChange,
  onSearchChange,
  onSelectTask,
  onOpenCreate,
  mode = 'list',
  onExitFocused,
}: TaskListPanelProps) {
  if (mode === 'rail') {
    const localColumnsRail: Record<string, LocalTask[]> = COLUMN_LIST.reduce((acc, s) => {
      acc[s] = localTasks.filter(t => (t.latestJob?.status ?? 'queued') === s);
      return acc;
    }, {} as Record<string, LocalTask[]>);
    const allRail = Object.values(localColumnsRail).flat();
    const baseRail = selectedStatus === 'all' ? allRail : localColumnsRail[selectedStatus] ?? [];
    const filteredRail = baseRail.filter(t =>
      matchText(t.title, searchQuery) || matchText(t.body, searchQuery) || matchText(t.pieceName, searchQuery) || matchText(t.ownerName ?? '', searchQuery),
    );
    return (
      <RailPanel
        tasks={filteredRail}
        activeTaskId={activeTaskId}
        onSelectTask={onSelectTask}
        onOpenCreate={onOpenCreate}
        onExitFocused={onExitFocused ?? (() => {})}
      />
    );
  }
  const localColumns: Record<string, LocalTask[]> = COLUMN_LIST.reduce((acc, s) => {
    acc[s] = localTasks.filter(t => (t.latestJob?.status ?? 'queued') === s);
    return acc;
  }, {} as Record<string, LocalTask[]>);

  const allLocalTasks = Object.values(localColumns).flat();

  const baseList: LocalTask[] =
    selectedStatus === 'all' ? allLocalTasks : localColumns[selectedStatus] ?? [];

  const filtered = baseList.filter(t =>
    matchText(t.title, searchQuery) || matchText(t.body, searchQuery) || matchText(t.pieceName, searchQuery) || matchText(t.ownerName ?? '', searchQuery)
  ).sort((a, b) => {
    if (sortMode === 'title') {
      return a.title.localeCompare(b.title);
    }
    if (sortMode === 'status') {
      const aStatus = a.latestJob?.status ?? 'queued';
      const bStatus = b.latestJob?.status ?? 'queued';
      return aStatus.localeCompare(bStatus);
    }
    return new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime();
  });

  const counts: Record<string, number> = {};
  for (const s of COLUMN_LIST) {
    counts[s] = localColumns[s]?.length ?? 0;
  }
  const totalCount = allLocalTasks.length;
  const runningCount = counts.running ?? 0;
  const waitingCount = (counts.waiting_human ?? 0) + (counts.waiting_subtasks ?? 0);
  const failedCount = counts.failed ?? 0;

  return (
    <div className="flex flex-col h-full overflow-hidden">
      <button
        type="button"
        onClick={onOpenCreate}
        className="w-full mb-3 px-3 py-2 bg-accent hover:bg-accent-deep active:scale-[0.98] active:bg-accent-deep text-accent-fg rounded-md text-xs font-semibold inline-flex items-center justify-center gap-1.5 transition-[transform,background-color,color] duration-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent-ring"
      >
        <svg
          width="13"
          height="13"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          strokeWidth={2.25}
          strokeLinecap="round"
          strokeLinejoin="round"
          aria-hidden="true"
        >
          <path d="M12 5v14M5 12h14" />
        </svg>
        新しい依頼
      </button>
      <div className="flex items-center gap-3 text-[10px] text-slate-500 px-0.5 pb-2.5 font-mono tabular-nums">
        <span><span className="font-semibold text-slate-700">{totalCount}</span> 件</span>
        <span aria-hidden="true" className="text-slate-300">·</span>
        <span><span className="font-semibold text-emerald-600">{runningCount}</span> 実行中</span>
        <span><span className="font-semibold text-amber-600">{waitingCount}</span> 待機中</span>
        {failedCount > 0 && (
          <span><span className="font-semibold text-red-600">{failedCount}</span> 失敗</span>
        )}
      </div>
      <FilterBar
        selectedStatus={selectedStatus}
        sortMode={sortMode}
        searchQuery={searchQuery}
        counts={counts}
        totalCount={totalCount}
        onStatusChange={onStatusChange}
        onSortChange={onSortChange}
        onSearchChange={onSearchChange}
      />
      <div className="flex flex-col gap-1.5 mt-2 overflow-y-auto flex-1 min-h-0 pr-0.5">
        {filtered.map(task => (
          <LocalTaskListItem
            key={task.id}
            task={task}
            active={activeTaskId === task.id}
            onClick={() => onSelectTask(task.id)}
          />
        ))}
        {filtered.length === 0 && (
          <div className="text-[13px] text-slate-500 px-2 py-3">スレッドがありません</div>
        )}
      </div>
    </div>
  );
}
