'use client';

import React from 'react';
import { Activity, CheckCircle2, ChevronDown, Circle, FileText, LoaderCircle, PanelRightOpen, Sparkles, TerminalSquare, Users, X } from 'lucide-react';

import { Badge } from '@/components/ui/badge';
import { ScrollArea } from '@/components/ui/scroll-area';
import { formatTaskRuntimeDuration, formatTaskRuntimeTime } from '@/components/task-runtime/TaskRuntimeShared';
import { pickAppText } from '@/lib/i18n/core';
import { useAppI18n } from '@/lib/i18n/provider';
import {
  buildTaskUiModel,
  taskUiStatusClass,
  taskUiStatusLabel,
  type TaskUiModel,
  type TaskUiStatus,
} from '@/lib/task-ui-model';
import { containedLongTextClass, containedPreservedLongTextClass } from '@/lib/text-wrapping';
import type { BackendTask, SessionProcessProjection, TaskTimelineCard } from '@/types';

function StatusBadge({ status }: { status: TaskUiStatus }) {
  const { locale } = useAppI18n();
  return (
    <Badge variant="outline" className={`h-7 rounded-full px-2.5 text-[11px] ${taskUiStatusClass(status)}`}>
      {taskUiStatusLabel(status, locale)}
    </Badge>
  );
}

function ProgressCard({
  icon,
  title,
  label,
  status,
  children,
}: {
  icon: React.ReactNode;
  title: string;
  label: string;
  status: TaskUiStatus;
  children: React.ReactNode;
}) {
  const { locale } = useAppI18n();
  const [open, setOpen] = React.useState(true);

  return (
    <section className="min-w-0 rounded-lg border border-[#E6E1DE] bg-white shadow-[0_6px_18px_rgba(31,24,20,0.04)]">
      <button
        type="button"
        onClick={() => setOpen((current) => !current)}
        className="flex min-h-[52px] w-full min-w-0 items-center gap-3 px-4 py-2.5 text-left"
        aria-expanded={open}
      >
        <span className="flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-[#F1EFEE] text-[#615854]">{icon}</span>
        <span className="min-w-0 flex-1">
          <span className="block truncate text-sm font-semibold text-[#1D1715]">{title}</span>
          <span className="mt-0.5 block truncate text-xs text-muted-foreground">{label}</span>
        </span>
        <StatusBadge status={status} />
        <ChevronDown className={`h-4 w-4 shrink-0 text-muted-foreground transition-transform ${open ? 'rotate-180' : ''}`} />
      </button>
      {open ? (
        <div className="border-t border-[#ECE8E5] px-4 py-2.5">
          <div className="min-w-0">{children}</div>
          <button
            type="button"
            className="mt-3 flex h-9 w-full items-center justify-center rounded-md border border-[#E6E1DE] bg-[#FBFAF9] text-xs font-medium text-[#615854] hover:bg-[#F4F1EF]"
          >
            {pickAppText(locale, '详情', 'Details')}
          </button>
        </div>
      ) : null}
    </section>
  );
}

function SummarySection({ model }: { model: TaskUiModel }) {
  return (
    <p className={`line-clamp-2 text-sm leading-5 text-muted-foreground ${containedPreservedLongTextClass}`}>
      {model.summary.summary}
    </p>
  );
}

function SkillSection({ model }: { model: TaskUiModel }) {
  const { locale } = useAppI18n();
  if (model.skills.length === 0) {
    return <p className="text-sm text-muted-foreground">{pickAppText(locale, '暂无 Skill 选择', 'No skill selected yet')}</p>;
  }
  const primary = model.skills[0];
  return (
    <div className="min-w-0">
      <div className={`line-clamp-1 text-sm font-medium text-[#1D1715] ${containedLongTextClass}`}>{primary.name}</div>
      {primary.createdAt ? <div className="mt-1 text-xs text-muted-foreground">{formatTaskRuntimeTime(primary.createdAt, locale)}</div> : null}
      {primary.summary ? (
        <p className={`mt-1 line-clamp-1 text-xs leading-5 text-muted-foreground ${containedLongTextClass}`}>{primary.summary}</p>
      ) : null}
    </div>
  );
}

function ToolsSection({ model }: { model: TaskUiModel }) {
  const { locale } = useAppI18n();
  const attempts = model.attempts.filter((attempt) => attempt.tools.length > 0);
  if (attempts.length === 0) {
    return <p className="text-sm text-muted-foreground">{pickAppText(locale, '暂无工具调用', 'No tool calls yet')}</p>;
  }
  return (
    <div className="space-y-3">
      {attempts.map((attempt) => (
        <div key={attempt.id} className="min-w-0">
          <div className="mb-1.5 flex items-center justify-between gap-2 text-xs text-muted-foreground">
            <span>{attempt.title}</span>
            <span>{attempt.tools.length} calls</span>
          </div>
          <div className="space-y-2">
            {attempt.tools.map((tool) => (
              <div key={tool.id} className="grid min-w-0 grid-cols-[minmax(0,1fr)_76px_46px] items-center gap-2">
                <span className={`text-sm text-[#1D1715] ${containedLongTextClass}`}>
                  {tool.toolName}
                </span>
                <span className={`flex items-center gap-1 text-xs ${tool.status === 'done' ? 'text-[#22733A]' : tool.status === 'running' ? 'text-[#B26A00]' : tool.status === 'error' ? 'text-[#9D3D2F]' : 'text-muted-foreground'}`}>
                  {tool.status === 'done' ? <CheckCircle2 className="h-3.5 w-3.5" /> : tool.status === 'running' ? <LoaderCircle className="h-3.5 w-3.5" /> : <Circle className="h-3.5 w-3.5" />}
                  {taskUiStatusLabel(tool.status, locale)}
                </span>
                <span className="text-right text-xs text-muted-foreground">{formatSidebarToolDuration(tool, locale)}</span>
              </div>
            ))}
          </div>
        </div>
      ))}
    </div>
  );
}

function formatSidebarToolDuration(tool: TaskUiModel['tools'][number], locale: string): string {
  if (typeof tool.durationMs === 'number') {
    return formatTaskRuntimeDuration(tool.durationMs, locale);
  }
  if (tool.status === 'running' && tool.createdAt) {
    const startMs = new Date(tool.createdAt).getTime();
    if (!Number.isNaN(startMs)) {
      return formatTaskRuntimeDuration(Date.now() - startMs, locale);
    }
  }
  return '-';
}

function flattenAgents(model: TaskUiModel) {
  const output: Array<{ id: string; name: string; status: TaskUiStatus; depth: number }> = [];
  const visit = (node: TaskUiModel['agentTree'][number], depth: number) => {
    output.push({ id: node.runId, name: node.title || node.name, status: node.status, depth });
    node.children.forEach((child) => visit(child, depth + 1));
  };
  model.agentTree.forEach((node) => visit(node, 0));
  return output;
}

function AgentSection({ model }: { model: TaskUiModel }) {
  const { locale } = useAppI18n();
  const rows = flattenAgents(model).slice(0, 6);
  if (!model.team.hasTeam) {
    return (
      <div className="rounded-md border border-[#E6E1DE] bg-[#FBFAF9] px-3 py-2 text-sm text-muted-foreground">
        {pickAppText(locale, '本轮为 Main Agent 单线程执行，未启动 Agent Team。', 'This run uses the Main Agent only; no Agent Team was started.')}
      </div>
    );
  }
  if (rows.length === 0) {
    return <p className="text-sm text-muted-foreground">{pickAppText(locale, 'Agent Team 已启动，等待节点数据', 'Agent Team started; waiting for node data')}</p>;
  }
  return (
    <div className="min-w-0">
      <div className="flex items-center gap-2 text-xs text-[#615854]">
        <Users className="h-3.5 w-3.5" />
        <span>{rows[0]?.name}</span>
      </div>
      <div className="ml-4 mt-2 space-y-2 border-l border-[#D8D2CE] pl-4">
        {rows.map((node) => (
          <div key={node.id} className="grid min-w-0 grid-cols-[14px_minmax(0,1fr)_74px] items-center gap-2" style={{ paddingLeft: `${Math.min(node.depth, 3) * 8}px` }}>
            <span className="h-px w-3 bg-[#D8D2CE]" />
            <span className={`text-xs text-[#1D1715] ${containedLongTextClass}`}>{node.name}</span>
            <span className={`flex items-center gap-1 text-xs ${node.status === 'done' ? 'text-[#22733A]' : node.status === 'running' ? 'text-[#B26A00]' : 'text-muted-foreground'}`}>
              {node.status === 'done' ? <CheckCircle2 className="h-3.5 w-3.5" /> : node.status === 'running' ? <LoaderCircle className="h-3.5 w-3.5" /> : <Circle className="h-3.5 w-3.5" />}
              {taskUiStatusLabel(node.status, locale)}
            </span>
          </div>
        ))}
      </div>
    </div>
  );
}

function statusForSummary(task: BackendTask): TaskUiStatus {
  if (task.status === 'awaiting_acceptance' || task.status === 'closed') return 'done';
  if (task.status === 'running') return 'running';
  return 'waiting';
}

function primarySkillName(model: TaskUiModel) {
  return model.skills[0]?.name || '';
}

function hasExecutionStructure(model: TaskUiModel): boolean {
  return model.team.hasTeam || model.agentTree.length > 0;
}

function toolStatus(model: TaskUiModel): TaskUiStatus {
  if (model.tools.some((tool) => tool.status === 'running')) return 'running';
  if (model.tools.some((tool) => tool.status === 'error')) return 'error';
  return model.tools.length ? 'done' : 'waiting';
}

function agentStatus(model: TaskUiModel): TaskUiStatus {
  if (model.agentTree.some((node) => node.status === 'running' || node.children.some((child) => child.status === 'running'))) return 'running';
  if (!model.team.hasTeam) return 'waiting';
  if (model.agentTree.some((node) => node.status === 'error' || node.children.some((child) => child.status === 'error'))) return 'error';
  return model.agentTree.length ? 'done' : model.team.status;
}

function ProgressPanel({
  task,
  process,
  cards,
  isLive,
  onClose,
}: {
  task: BackendTask | null;
  process: SessionProcessProjection | null;
  cards: TaskTimelineCard[];
  isLive: boolean;
  onClose?: () => void;
}) {
  const { locale } = useAppI18n();
  const model = task
    ? buildTaskUiModel({
        task,
        process: process ?? { runs: [], events: [], artifacts: [] },
        cards,
        locale,
      })
    : null;

  return (
    <div className="flex h-full min-w-0 flex-col overflow-hidden bg-[#FBFAF9]">
      <div className="flex h-16 min-w-0 shrink-0 items-center justify-between gap-3 border-b border-[#E6E1DE] px-5">
        <div className="min-w-0">
          <h2 className="truncate text-base font-semibold text-foreground">
            {pickAppText(locale, '当前会话的运行进度', 'Current Session Progress')}
          </h2>
          <p className="flex min-w-0 items-center gap-1.5 text-xs text-muted-foreground">
            {isLive ? <Activity className="h-3.5 w-3.5" /> : null}
            <span className="truncate">
              {isLive
                ? pickAppText(locale, '任务时间线实时更新', 'Task timeline updates live')
                : pickAppText(locale, '与任务详情时间线一致', 'Matches the Task detail timeline')}
            </span>
          </p>
        </div>
        {onClose ? (
          <button
            type="button"
            onClick={onClose}
            className="rounded-full p-2 text-muted-foreground transition-colors hover:bg-[#ECE8E5] hover:text-foreground"
            aria-label={pickAppText(locale, '关闭进度面板', 'Close progress panel')}
          >
            <X className="h-4 w-4" />
          </button>
        ) : null}
      </div>

      <ScrollArea className="min-h-0 min-w-0 flex-1 overflow-hidden px-4 py-2.5">
        <div className="min-w-0 max-w-full pb-6">
          {model ? (
            <div className="space-y-2.5">
              <ProgressCard
                icon={<FileText className="h-4 w-4" />}
                title={pickAppText(locale, '任务摘要', 'Task summary')}
                label={model.summary.title}
                status={task ? statusForSummary(task) : 'waiting'}
              >
                <SummarySection model={model} />
              </ProgressCard>
              {model.skills.length > 0 ? (
                <ProgressCard
                  icon={<Sparkles className="h-4 w-4" />}
                  title={pickAppText(locale, 'Skill 选择', 'Skill selection')}
                  label={primarySkillName(model)}
                  status={model.skills[0]?.status || 'waiting'}
                >
                  <SkillSection model={model} />
                </ProgressCard>
              ) : null}
              {model.tools.length > 0 ? (
                <ProgressCard
                  icon={<TerminalSquare className="h-4 w-4" />}
                  title={pickAppText(locale, '工具调用', 'Tool calls')}
                  label={pickAppText(locale, `${model.tools.length} 个工具调用`, `${model.tools.length} tool calls`)}
                  status={toolStatus(model)}
                >
                  <ToolsSection model={model} />
                </ProgressCard>
              ) : null}
              {hasExecutionStructure(model) ? (
                <ProgressCard
                  icon={<Users className="h-4 w-4" />}
                  title={pickAppText(locale, '执行结构', 'Execution structure')}
                  label={
                    model.team.hasTeam
                      ? pickAppText(locale, `Agent Team · ${model.team.outcome}`, `Agent Team · ${model.team.outcome}`)
                      : pickAppText(locale, 'Agent run', 'Agent run')
                  }
                  status={agentStatus(model)}
                >
                  <AgentSection model={model} />
                </ProgressCard>
              ) : null}
            </div>
          ) : (
            <div className="rounded-lg border border-dashed border-[#DED8D4] bg-white px-4 py-10 text-center text-sm text-muted-foreground">
              {pickAppText(locale, '当前会话暂无运行任务', 'No running task in this session')}
            </div>
          )}
        </div>
      </ScrollArea>
    </div>
  );
}

export function CurrentSessionProgressSidebar({
  task,
  process,
  cards,
  isLive,
}: {
  task: BackendTask | null;
  process: SessionProcessProjection | null;
  cards: TaskTimelineCard[];
  isLive: boolean;
}) {
  const { locale } = useAppI18n();
  const [mobileOpen, setMobileOpen] = React.useState(false);

  return (
    <>
      <aside className="hidden h-full w-[380px] min-w-0 shrink-0 overflow-hidden border-l border-[#E6E1DE] xl:flex">
        <ProgressPanel task={task} process={process} cards={cards} isLive={isLive} />
      </aside>

      <button
        type="button"
        onClick={() => setMobileOpen(true)}
        className="fixed right-3 top-24 z-40 flex h-11 w-11 items-center justify-center rounded-full border border-[#E6E1DE] bg-white text-[#342E2B] shadow-[0_8px_22px_rgba(0,0,0,0.16)] transition-colors hover:bg-[#F7F6F5] xl:hidden"
        aria-label={pickAppText(locale, '查看当前会话运行进度', 'View current session progress')}
      >
        <PanelRightOpen className="h-5 w-5" />
      </button>

      {mobileOpen ? (
        <div className="fixed inset-0 z-50 xl:hidden">
          <button
            type="button"
            className="absolute inset-0 bg-black/30"
            onClick={() => setMobileOpen(false)}
            aria-label={pickAppText(locale, '关闭进度面板', 'Close progress panel')}
          />
          <div className="absolute inset-y-0 right-0 w-[min(92vw,390px)] min-w-0 overflow-hidden border-l border-[#E6E1DE] shadow-2xl">
            <ProgressPanel task={task} process={process} cards={cards} isLive={isLive} onClose={() => setMobileOpen(false)} />
          </div>
        </div>
      ) : null}
    </>
  );
}
