import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useQuery } from '@tanstack/react-query';
import { POLLING } from '../../../lib/constants.js';
import { fetchDelegateRuns, fetchDelegateRunTimeline, type TraceEventLite } from '../../../api';
import { buildDelegateRunTree, currentRunningTool, delegateStatusBadge, formatElapsed, formatTokens, summarizeDescendants, type DelegateRunNode, type DelegateRun, type SubtaskDelegateGroup } from '../../../lib/delegateRuns';
import { useNow } from '../../../hooks/useNow';
import { summarizeTraceEvent } from '../../../lib/traceEvent';

function EventLine({ event }: { event: TraceEventLite }) {
  const summary = summarizeTraceEvent(event);
  return (
    <div className="flex items-baseline gap-1.5 py-0.5 font-mono text-[10px] text-slate-500">
      <span className="shrink-0 text-slate-400">{new Date(event.ts).toLocaleTimeString()}</span>
      <span className="shrink-0 font-semibold text-slate-600">{event.kind}</span>
      {summary && <span className="truncate text-slate-400">{summary}</span>}
    </div>
  );
}

function RunCard({ taskId, node, indent = 0, jobId }: { taskId: number; node: DelegateRunNode; indent?: number; jobId?: string }) {
  const { t } = useTranslation('detail');
  const [open, setOpen] = useState(false);
  const [eventsOpen, setEventsOpen] = useState(false);
  const badge = delegateStatusBadge(node.status);
  const running = node.status === 'running';
  // 実行中カードのみ 1 秒刻みで経過を更新（ネットワーク不要のローカルタイマー）。
  const now = useNow(running);

  const { data: events } = useQuery({
    queryKey: ['delegate-run-timeline', taskId, node.delegateRunId, jobId],
    queryFn: () => fetchDelegateRunTimeline(taskId, node.delegateRunId, jobId),
    enabled: open,
    // 開いていて実行中の間だけ自動更新。完了したら停止（done な run のイベントは不変）。
    refetchInterval: open && running ? POLLING.FAST : false,
  });

  const runningTool = running ? currentRunningTool(events ?? []) : null;
  const descendantSummary = summarizeDescendants(node);

  let childBadgeContent = null;
  let childBadgeClass = '';
  if (descendantSummary.total > 0) {
    if (descendantSummary.failed > 0) {
      childBadgeContent = t('delegateRuns.childCountFailed', { total: descendantSummary.total, failed: descendantSummary.failed });
      childBadgeClass = 'bg-red-100 text-red-800';
    } else if (descendantSummary.running > 0) {
      childBadgeContent = t('delegateRuns.childCount', { total: descendantSummary.total });
      childBadgeClass = 'bg-blue-100 text-blue-800';
    } else {
      childBadgeContent = t('delegateRuns.childCount', { total: descendantSummary.total });
      childBadgeClass = 'bg-slate-100 text-slate-600';
    }
  }

  return (
    <div
      className="border border-slate-200 rounded-md mb-1.5 overflow-hidden"
      style={indent > 0 ? { marginLeft: `${indent * 16}px` } : undefined}
    >
      <button
        className="w-full flex items-center gap-2 px-3 py-2 text-left hover:bg-slate-50 transition-colors"
        onClick={() => setOpen((v) => !v)}
        aria-expanded={open}
      >
        <span className={`shrink-0 text-[10px] font-bold px-1.5 py-0.5 rounded-full ${badge.cls}`}>
          {t(badge.labelKey)}
        </span>
        {childBadgeContent && (
          <span className={`shrink-0 text-[10px] font-bold px-1.5 py-0.5 rounded-full ${childBadgeClass}`}>
            {childBadgeContent}
          </span>
        )}
        <span className="text-[13px] text-slate-800 font-medium truncate flex-1">
          {node.description || t('delegateRuns.noDescription')}
        </span>
        <span className="shrink-0 text-xs text-slate-400">
          {t('delegateRuns.toolCount', { count: node.toolCalls })} · {formatElapsed(node.startTs, node.endTs, now)}{node.totalTokens && node.totalTokens > 0 ? ` · ${formatTokens(node.totalTokens)}` : ''}
        </span>
        <span className="shrink-0 text-slate-400 text-xs ml-1" aria-hidden="true">{open ? '▲' : '▼'}</span>
      </button>

      {open && (
        <div className="border-t border-slate-100 px-3 pb-2">
          {runningTool && (
            <div className="mt-2 px-2 py-1 text-[12px] text-blue-700 bg-blue-50 rounded">
              {t('subtasks.delegateRunningTool', { tool: runningTool })}
            </div>
          )}
          {(node.status === 'success' || node.status === 'needs_user_input' || node.status === 'aborted') && node.resultPreview && (
            <div className={`mt-2 p-2 rounded text-[12px] ${
              node.status === 'aborted'
                ? 'bg-red-50 text-red-700'
                : 'bg-slate-50 text-slate-700'
            }`}>
              <div className="font-semibold mb-1">
                {t(node.status === 'aborted' ? 'delegateRuns.abortReason' : 'delegateRuns.result')}
              </div>
              <div className="whitespace-pre-wrap break-words max-h-48 overflow-y-auto">
                {node.resultPreview}
              </div>
            </div>
          )}
          {node.toolSummary && node.toolSummary.length > 0 && (
            <div className="mt-2">
              <div className="text-[10px] text-slate-500 mb-1">{t('delegateRuns.toolSummary')}</div>
              <div className="flex flex-wrap gap-1">
                {node.toolSummary.map((item) => (
                  <div key={item.tool} className="bg-slate-100 text-slate-600 rounded px-1.5 py-0.5 text-[11px] font-mono">
                    {item.tool} ×{item.count}
                  </div>
                ))}
              </div>
            </div>
          )}
          {node.filesChanged && node.filesChanged.length > 0 && (
            <div className="mt-2">
              <div className="text-[10px] text-slate-500 mb-1">{t('delegateRuns.filesChanged')}</div>
              <div>
                {node.filesChanged.map((path, idx) => (
                  <div key={idx} className="font-mono text-[11px] text-slate-600 truncate" title={path}>
                    {path}
                  </div>
                ))}
              </div>
            </div>
          )}
          <button
            className="mt-2 text-[11px] text-slate-500 hover:text-slate-700 transition-colors"
            onClick={() => setEventsOpen((v) => !v)}
            aria-expanded={eventsOpen}
          >
            <span aria-hidden="true">{eventsOpen ? '▾' : '▸'}</span> {t('delegateRuns.eventsToggle', { count: node.eventCount })}
          </button>
          {eventsOpen && (
            <>
              {events && events.length > 0 ? (
                <div className="mt-1">
                  {events.length > 20 && (
                    <div className="text-[11px] text-slate-400 mb-1">
                      {t('delegateRuns.moreEvents', { count: events.length - 20 })}
                    </div>
                  )}
                  {events.slice(-20).map((e) => <EventLine key={e.eventId} event={e} />)}
                </div>
              ) : (
                <div className="mt-1 text-[11px] text-slate-400">
                  {events ? t('delegateRuns.eventsEmpty') : t('common:loading')}
                </div>
              )}
            </>
          )}
          {node.children.map((c) => (
            <RunCard key={c.delegateRunId} taskId={taskId} node={c} indent={indent + 1} jobId={jobId} />
          ))}
        </div>
      )}
    </div>
  );
}

export function DelegateRunsSection({ taskId }: { taskId: number }) {
  const { t } = useTranslation('detail');
  const { data } = useQuery({
    queryKey: ['delegate-runs', taskId],
    queryFn: () => fetchDelegateRuns(taskId),
    // 実行中の run がある間は速く（FAST=5s）、無ければ通常（MEDIUM=10s）。
    // refetchIntervalInBackground は既定 false なのでタブ非表示時は自動停止。
    refetchInterval: (query) => {
      const result = query.state.data;
      const runs = result?.runs;
      return runs?.some((r: DelegateRun) => r.status === 'running') ? POLLING.FAST : POLLING.MEDIUM;
    },
  });

  const tree = buildDelegateRunTree(data?.runs ?? []);
  const subtasks: SubtaskDelegateGroup[] = data?.subtasks ?? [];

  if (tree.length === 0 && subtasks.length === 0) return null;

  return (
    <div className="mb-4">
      <div className="text-sm font-bold text-slate-800 mb-2">{t('subtasks.delegateSection')}</div>
      {tree.map((n) => (
        <RunCard key={n.delegateRunId} taskId={taskId} node={n} />
      ))}
      {subtasks.map((group) => {
        const groupTree = buildDelegateRunTree(group.runs);
        return (
          <div key={group.jobId} className="mt-3">
            <div className="text-xs font-semibold text-slate-500 mb-1 px-1">
              {t('delegateRuns.subtaskGroupTitle', { n: group.issueNumber })}
            </div>
            {groupTree.map((n) => (
              <RunCard key={n.delegateRunId} taskId={taskId} node={n} jobId={group.jobId} />
            ))}
          </div>
        );
      })}
    </div>
  );
}
