import { useTranslation } from 'react-i18next';
import { LocalTask } from '../../api';
import { matchText } from '../../lib/utils';
import { COLUMN_LIST, SortMode, StatusColumn } from '../../lib/urlState';
import { filterTasksByScope, type TaskScope } from '../../lib/taskScope';
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;
  /**
   * Owner scope (mine/others). Only meaningful when scopeEnabled — auth must be
   * on and the viewer known; otherwise everything is owner 'local' and the
   * control is hidden.
   */
  scope?: TaskScope;
  onScopeChange?: (scope: TaskScope) => void;
  currentUserId?: string | null;
  scopeEnabled?: boolean;
  /** 'rail' 時は RailPanel を render する。default 'list'。 */
  mode?: 'list' | 'rail';
  /** rail mode 時の「リストに戻る」ボタンで呼ばれる。 */
  onExitFocused?: () => void;
}

function ScopeToggle({
  scope,
  mineCount,
  othersCount,
  onScopeChange,
}: {
  scope: TaskScope;
  mineCount: number;
  othersCount: number;
  onScopeChange: (scope: TaskScope) => void;
}) {
  const { t } = useTranslation('list');
  const seg = (value: TaskScope, label: string, count: number) => (
    <button
      type="button"
      onClick={() => onScopeChange(value)}
      aria-pressed={scope === value}
      className={`flex-1 px-2 py-1 rounded text-[11px] font-medium transition-colors tabular-nums ${
        scope === value
          ? 'bg-surface text-slate-900 shadow-sm'
          : 'text-slate-500 hover:text-slate-700'
      }`}
    >
      {label} <span className={scope === value ? 'text-slate-500' : 'text-slate-400'}>{count}</span>
    </button>
  );
  return (
    <div className="flex gap-0.5 p-0.5 mb-2 rounded-md bg-canvas border border-hairline" role="group" aria-label={t('scope.aria')}>
      {seg('mine', t('scope.mine'), mineCount)}
      {seg('others', t('scope.others'), othersCount)}
    </div>
  );
}

export function TaskListPanel({
  localTasks: allTasks,
  selectedStatus,
  sortMode,
  searchQuery,
  activeTaskId,
  onStatusChange,
  onSortChange,
  onSearchChange,
  onSelectTask,
  onOpenCreate,
  scope = 'mine',
  onScopeChange,
  currentUserId = null,
  scopeEnabled = false,
  mode = 'list',
  onExitFocused,
}: TaskListPanelProps) {
  const { t } = useTranslation('list');
  // Owner scope is the outermost filter: status counts / search / sort all
  // operate on the scoped list so "自分" mode never counts others' tasks.
  // When the toggle is disabled (no-auth: every task is owner 'local'), the
  // scope partition is meaningless — show the full list unfiltered.
  const localTasks = scopeEnabled
    ? filterTasksByScope(allTasks, scope, currentUserId)
    : allTasks;
  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>
        {t('newRequest')}
      </button>
      {scopeEnabled && onScopeChange && (
        <ScopeToggle
          scope={scope}
          mineCount={filterTasksByScope(allTasks, 'mine', currentUserId).length}
          othersCount={filterTasksByScope(allTasks, 'others', currentUserId).length}
          onScopeChange={onScopeChange}
        />
      )}
      <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> {t('counts.items')}</span>
        <span aria-hidden="true" className="text-slate-300">·</span>
        <span><span className="font-semibold text-emerald-600">{runningCount}</span> {t('counts.running')}</span>
        <span><span className="font-semibold text-amber-600">{waitingCount}</span> {t('counts.waiting')}</span>
        {failedCount > 0 && (
          <span><span className="font-semibold text-red-600">{failedCount}</span> {t('counts.failed')}</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">{t('empty')}</div>
        )}
      </div>
    </div>
  );
}
