import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import i18n from '../../../i18n';
import { useQuery } from '@tanstack/react-query';
import { POLLING } from '../../../lib/constants.js';
import { SubtaskInfo, SubtaskActivity, SubtaskFiles, fetchSubtaskFiles, subtaskFileRawUrl, fetchSubtaskActivity } from '../../../api';
import { statusTone, formatStatusLabel, parseActivityLog, isPreviewable } from '../../../lib/utils';
import { ActivityTimeline } from '../../activity/ActivityTimeline';
import { LinkifiedText } from '../../../lib/linkified-text';
import { OutputPreviewProvider } from '../../../lib/output-preview-context';
import { stripOutputPrefix } from '../../../lib/output-path-detect';

export type SubtaskFilePreviewHandler = (taskId: number, jobId: string, category: string, filePath: string) => void;

interface SubtasksPanelProps {
  taskId: number;
  subtasks: SubtaskInfo[];
  subtaskCount: number;
  subtaskCompleted: number;
  subtaskActivities?: SubtaskActivity[];
  onFilePreview?: SubtaskFilePreviewHandler;
}

interface SubtaskCardProps {
  taskId: number;
  subtask: SubtaskInfo;
  activity?: SubtaskActivity;
  onFilePreview?: SubtaskFilePreviewHandler;
}

const ACTIVE_STATUSES = new Set(['running', 'waiting_human', 'waiting_subtasks']);

const CATEGORY_LABELS: Record<string, string> = {
  output: 'Output files',
  logs: 'Logs',
  input: 'Input files',
};

const CATEGORY_ORDER = ['output', 'logs', 'input'];

function FileList({ taskId, jobId, category, files, onFilePreview }: { taskId: number; jobId: string; category: string; files: string[]; onFilePreview?: SubtaskFilePreviewHandler }) {
  const label = i18n.t('detail:subtasks.category.' + category, { defaultValue: CATEGORY_LABELS[category] ?? category });
  return (
    <div className="mt-2">
      <div className="text-[10px] font-semibold text-slate-400 uppercase tracking-wide mb-1">{label}</div>
      <ul className="flex flex-col gap-0.5">
        {files.map(filePath => {
          const previewable = isPreviewable(filePath);
          return (
            <li key={filePath} className="flex items-center gap-1.5">
              {previewable && onFilePreview ? (
                <button
                  onClick={() => onFilePreview(taskId, jobId, category, filePath)}
                  className="text-xs text-blue-600 hover:underline break-all text-left"
                >
                  {filePath}
                </button>
              ) : (
                <a
                  href={subtaskFileRawUrl(taskId, jobId, `${category}/${filePath}`)}
                  target="_blank"
                  rel="noopener noreferrer"
                  className="text-xs text-blue-600 hover:underline break-all"
                >
                  {filePath}
                </a>
              )}
            </li>
          );
        })}
      </ul>
    </div>
  );
}

function SubtaskCard({ taskId, subtask, activity, onFilePreview }: SubtaskCardProps) {
  const [expanded, setExpanded] = useState(false);
  const tone = statusTone(subtask.status);
  const title = subtask.instruction.split('\n')[0]?.slice(0, 100) ?? '';
  const isActive = ACTIVE_STATUSES.has(subtask.status);

  const { data: activityLog } = useQuery({
    queryKey: ['subtaskActivity', taskId, subtask.id],
    queryFn: () => fetchSubtaskActivity(taskId, subtask.id),
    refetchInterval: POLLING.FAST,
    enabled: expanded && isActive,
  });

  const displayLog = expanded && !isActive ? (activity?.activityLog ?? '') : (activityLog ?? '');
  const activityEvents = expanded ? parseActivityLog(displayLog) : [];

  const { data: subtaskFiles, isLoading: filesLoading } = useQuery({
    queryKey: ['subtask-files', taskId, subtask.id],
    queryFn: () => fetchSubtaskFiles(taskId, subtask.id),
    enabled: expanded,
    refetchInterval: isActive ? POLLING.MEDIUM : false,
  });

  const currentMovement = activity?.currentMovement;
  const categories = subtaskFiles?.categories ?? {};
  const hasFiles = Object.values(categories).some(f => f.length > 0);

  return (
    <div className="border border-slate-200 rounded-lg bg-canvas overflow-hidden">
      <button
        className="w-full text-left px-3 py-2.5 flex items-start gap-2 hover:bg-slate-50 transition-colors"
        onClick={() => setExpanded(prev => !prev)}
      >
        <span
          className="flex-shrink-0 mt-0.5 px-1.5 py-0.5 rounded-full text-[10px] font-bold"
          style={{ background: tone.bg, color: tone.fg }}
        >
          {formatStatusLabel(subtask.status)}
        </span>
        <span className="text-[13px] text-slate-800 font-medium leading-snug min-w-0 truncate flex-1">
          #{subtask.issueNumber} {title}
        </span>
        {subtask.children && subtask.children.length > 0 && (
          <span className="flex-shrink-0 text-[10px] text-indigo-500 font-medium">
            ({subtask.childCompleted ?? 0}/{subtask.childCount ?? subtask.children.length})
          </span>
        )}
        {currentMovement && isActive && (
          <span className="flex-shrink-0 text-2xs text-slate-400 font-mono">
            {currentMovement}
          </span>
        )}
        <span className="flex-shrink-0 ml-auto text-slate-400 text-xs">
          {expanded ? '▲' : '▼'}
        </span>
      </button>

      {expanded && (
        // Subtask-scoped preview context: any `output/...` link inside
        // this card opens the SUBTASK's workspace file (not the main
        // task's). Wrapping just the expanded body keeps the outer
        // (main task) provider in charge of everything else.
        <OutputPreviewProvider
          openOutputPath={(matchedPath) => {
            if (!onFilePreview) return;
            const relative = stripOutputPrefix(matchedPath);
            onFilePreview(taskId, subtask.id, 'output', relative);
          }}
        >
        <div className="px-3 pb-3 border-t border-slate-100">
          <LinkifiedText
            as="pre"
            className="mt-2 text-xs text-slate-600 whitespace-pre-wrap leading-relaxed font-sans"
            text={subtask.instruction}
          />

          {activityEvents.length > 0 && (
            <div className="mt-3">
              <div className="text-2xs font-semibold text-slate-500 mb-1">Activity</div>
              <ActivityTimeline
                events={activityEvents}
                emptyLabel=""
                limit={isActive ? 5 : undefined}
              />
            </div>
          )}

          {filesLoading && <div className="mt-3 text-xs text-slate-400">{t('subtasks.filesLoading')}</div>}
          {hasFiles && (
            <div className="mt-3">
              <div className="text-2xs font-semibold text-slate-500 mb-1">{t('subtasks.files')}</div>
              {CATEGORY_ORDER.map(cat =>
                categories[cat] && categories[cat].length > 0 ? (
                  <FileList key={cat} taskId={taskId} jobId={subtask.id} category={cat} files={categories[cat]} onFilePreview={onFilePreview} />
                ) : null
              )}
            </div>
          )}

          {subtask.children && subtask.children.length > 0 && (
            <div className="mt-3">
              <div className="text-2xs font-semibold text-slate-500 mb-1">
                {t('subtasks.childTasks', { done: subtask.childCompleted ?? 0, total: subtask.childCount ?? subtask.children.length })}
              </div>
              <div className="flex flex-col gap-1.5 ml-2 border-l-2 border-indigo-100 pl-2">
                {subtask.children.map(child => (
                  <SubtaskCard key={child.id} taskId={taskId} subtask={child} onFilePreview={onFilePreview} />
                ))}
              </div>
            </div>
          )}
        </div>
        </OutputPreviewProvider>
      )}
    </div>
  );
}

export function SubtasksPanel({ taskId, subtasks, subtaskCount, subtaskCompleted, subtaskActivities, onFilePreview }: SubtasksPanelProps) {
  const { t } = useTranslation('detail');
  const progressPct = subtaskCount > 0 ? Math.round((subtaskCompleted / subtaskCount) * 100) : 0;

  return (
    <div className="bg-canvas border border-slate-200 rounded-xl p-4 shadow-sm">
      <div className="flex items-center justify-between mb-3">
        <div className="text-sm font-bold text-slate-800">{t('subtasks.title')}</div>
        <div className="text-xs text-slate-500">{subtaskCompleted}/{subtaskCount} {t('subtasks.done')}</div>
      </div>
      <div className="w-full bg-slate-100 rounded-full h-1.5 mb-4">
        <div className="bg-accent h-1.5 rounded-full transition-all" style={{ width: `${progressPct}%` }} />
      </div>
      <div className="flex flex-col gap-2">
        {subtasks.map(subtask => (
          <SubtaskCard key={subtask.id} taskId={taskId} subtask={subtask} activity={subtaskActivities?.find(a => a.jobId === subtask.id)} onFilePreview={onFilePreview} />
        ))}
      </div>
    </div>
  );
}
