'use client';

import React from 'react';
import { CheckCircle2, Loader2, Sparkles } from 'lucide-react';

import type { ProcessArtifact, ProcessEvent, ProcessRun } from '@/types';
import { Badge } from '@/components/ui/badge';
import { appArtifactPreview, appFeedRoleLabel, appStatusLabel } from '@/lib/i18n/common';
import type { AppLocale } from '@/lib/i18n/core';
import { pickAppText } from '@/lib/i18n/core';
import { useAppI18n } from '@/lib/i18n/provider';
import { cn } from '@/lib/utils';

type RunCardPhase = 'live' | 'exiting' | 'collapsed';

type AgentFeedItem = {
  key: string;
  created_at: string;
  role: 'user' | 'assistant' | 'system' | 'tool';
  text: string;
  tone?: ProcessRun['status'];
};

const TERMINAL_STATUSES = new Set<ProcessRun['status']>(['done', 'error', 'cancelled']);

const AGENT_ACCENTS = [
  {
    frame: 'border-[#BCC4CE] bg-[#E4E7EB]/45',
    title: 'text-[#697281]',
    dot: 'bg-[#8C96A3]',
    result: 'border-[#BCC4CE] bg-[#E4E7EB]/55',
  },
  {
    frame: 'border-[#B7C2B5] bg-[#E3E8E2]/45',
    title: 'text-[#657162]',
    dot: 'bg-[#869683]',
    result: 'border-[#B7C2B5] bg-[#E3E8E2]/55',
  },
  {
    frame: 'border-[#B8AEA8] bg-[#E7E2DE]/55',
    title: 'text-[#5F5550]',
    dot: 'bg-[#8B7E77]',
    result: 'border-[#B8AEA8] bg-[#E7E2DE]/65',
  },
  {
    frame: 'border-[#D8D2CE] bg-[#ECE8E5]/70',
    title: 'text-[#4F4642]',
    dot: 'bg-[#6A5E58]',
    result: 'border-[#D8D2CE] bg-[#ECE8E5]/80',
  },
] as const;

function accentFor(index: number) {
  return AGENT_ACCENTS[index % AGENT_ACCENTS.length];
}

function statusTone(status: ProcessRun['status']) {
  if (status === 'done') return 'border-[#B7C2B5] bg-[#E3E8E2] text-[#657162]';
  if (status === 'error') return 'border-[#B8AEA8] bg-[#E7E2DE] text-[#342E2B]';
  if (status === 'cancelled') return 'border-[#D8D2CE] bg-[#ECE8E5] text-[#6A5E58]';
  if (status === 'waiting') return 'border-[#B8AEA8] bg-[#E7E2DE] text-[#5F5550]';
  if (status === 'queued') return 'border-[#D8D2CE] bg-[#ECE8E5] text-[#4F4642]';
  return 'border-[#BCC4CE] bg-[#E4E7EB] text-[#697281]';
}

function feedTone(role: AgentFeedItem['role']) {
  if (role === 'user') {
    return 'ml-6 border-border/70 bg-muted/60 text-foreground';
  }
  if (role === 'system') {
    return 'mx-4 border-border/60 bg-accent/60 text-foreground/85';
  }
  if (role === 'tool') {
    return 'mr-6 border-border/70 bg-background/80 text-foreground';
  }
  return 'mr-6 border-border/70 bg-background/80 text-foreground';
}

function delegatedTask(run: ProcessRun): string | null {
  const value = run.metadata?.delegated_task;
  return typeof value === 'string' && value.trim() ? value.trim() : null;
}

function buildFeed(
  run: ProcessRun,
  events: ProcessEvent[],
  artifacts: ProcessArtifact[],
  locale: AppLocale,
): AgentFeedItem[] {
  const items: AgentFeedItem[] = [];
  let hasLeadBubble = false;

  for (const event of events) {
    if (!event.text?.trim()) {
      continue;
    }
    if (event.kind === 'run_message') {
      const role = event.message_role || 'assistant';
      if (role === 'user') {
        hasLeadBubble = true;
      }
      items.push({
        key: event.event_id,
        created_at: event.created_at,
        role,
        text: event.text.trim(),
      });
      continue;
    }
    if (event.kind === 'run_progress') {
      items.push({
        key: event.event_id,
        created_at: event.created_at,
        role: 'assistant',
        text: event.text.trim(),
      });
      continue;
    }
    if (event.kind === 'run_status' && event.status && event.status !== 'running') {
      items.push({
        key: event.event_id,
        created_at: event.created_at,
        role: 'system',
        text: event.text.trim(),
        tone: event.status,
      });
    }
  }

  for (const artifact of artifacts) {
    items.push({
      key: artifact.artifact_id,
      created_at: artifact.created_at,
      role: artifact.actor_type === 'mcp' ? 'tool' : 'assistant',
      text: appArtifactPreview(artifact, locale),
    });
  }

  if (!hasLeadBubble) {
    const task = delegatedTask(run);
    if (task) {
      items.push({
        key: `${run.run_id}:delegated-task`,
        created_at: run.started_at,
        role: 'user',
        text: task,
      });
    }
  }

  return items
    .sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime())
    .slice(-8);
}

function runSummary(run: ProcessRun, feed: AgentFeedItem[], locale: AppLocale): string {
  if (run.summary?.trim()) {
    return run.summary.trim();
  }
  const latestAssistant = [...feed].reverse().find((item) => item.role === 'assistant' || item.role === 'tool');
  return latestAssistant?.text || pickAppText(locale, '已完成子任务处理', 'Subtask processing completed');
}

function SkillChips({ metadata }: { metadata?: Record<string, unknown> }) {
  const rawSelected = metadata?.selected_skill_names;
  const rawEphemeral = metadata?.ephemeral_skill_names;
  const selected = Array.isArray(rawSelected) ? rawSelected.map(String).filter(Boolean) : [];
  const ephemeral = Array.isArray(rawEphemeral) ? rawEphemeral.map(String).filter(Boolean) : [];
  const guidanceId = typeof metadata?.ephemeral_guidance_id === 'string' ? metadata.ephemeral_guidance_id : '';
  if (selected.length === 0 && ephemeral.length === 0 && !guidanceId) {
    return null;
  }
  return (
    <div className="mt-1.5 flex flex-wrap gap-1.5">
      {selected.map((name) => (
        <Badge key={`skill:${name}`} variant="secondary" className="max-w-[128px] truncate text-[10px]">
          skill:{name}
        </Badge>
      ))}
      {ephemeral.map((name) => (
        <Badge key={`ephemeral:${name}`} variant="outline" className="max-w-[128px] truncate text-[10px]">
          ephemeral:{name}
        </Badge>
      ))}
      {guidanceId && (
        <Badge variant="outline" className="text-[10px]">
          guidance:{guidanceId.slice(0, 8)}
        </Badge>
      )}
    </div>
  );
}

function useRunCardPhases(runs: ProcessRun[]) {
  const [phases, setPhases] = React.useState<Record<string, RunCardPhase>>(() =>
    Object.fromEntries(
      runs.map((run) => [run.run_id, TERMINAL_STATUSES.has(run.status) ? 'collapsed' : 'live'])
    )
  );
  const timersRef = React.useRef<Record<string, ReturnType<typeof setTimeout>>>({});

  React.useEffect(() => {
    setPhases((prev) => {
      const next = { ...prev };
      const seen = new Set<string>();

      for (const run of runs) {
        seen.add(run.run_id);
        const isTerminal = TERMINAL_STATUSES.has(run.status);
        const current = next[run.run_id];
        if (!current) {
          next[run.run_id] = isTerminal ? 'collapsed' : 'live';
          continue;
        }
        if (!isTerminal) {
          next[run.run_id] = 'live';
          if (timersRef.current[run.run_id]) {
            clearTimeout(timersRef.current[run.run_id]);
            delete timersRef.current[run.run_id];
          }
          continue;
        }
        if (current === 'live') {
          next[run.run_id] = 'exiting';
          timersRef.current[run.run_id] = setTimeout(() => {
            setPhases((snapshot) => {
              if (snapshot[run.run_id] !== 'exiting') {
                return snapshot;
              }
              return { ...snapshot, [run.run_id]: 'collapsed' };
            });
            delete timersRef.current[run.run_id];
          }, 420);
        }
      }

      for (const runId of Object.keys(next)) {
        if (!seen.has(runId)) {
          if (timersRef.current[runId]) {
            clearTimeout(timersRef.current[runId]);
            delete timersRef.current[runId];
          }
          delete next[runId];
        }
      }

      return next;
    });

    return () => {
      for (const timer of Object.values(timersRef.current)) {
        clearTimeout(timer);
      }
      timersRef.current = {};
    };
  }, [runs]);

  return phases;
}

function AgentBubble({
  item,
  locale,
}: {
  item: AgentFeedItem;
  locale: AppLocale;
}) {
  return (
    <div
      className={cn(
        'rounded-2xl border px-3 py-2 text-[13px] leading-5 transition-colors',
        feedTone(item.role),
        item.role === 'system' && item.tone ? statusTone(item.tone) : ''
      )}
    >
      <div className="mb-1 text-[10px] font-medium uppercase tracking-[0.14em] text-muted-foreground">
        <span>{appFeedRoleLabel(item.role, locale)}</span>
      </div>
      <div className="whitespace-pre-wrap break-words">{item.text}</div>
    </div>
  );
}

function LiveAgentCard({
  run,
  feed,
  artifactCount,
  selected,
  phase,
  accentIndex,
  onSelect,
  locale,
}: {
  run: ProcessRun;
  feed: AgentFeedItem[];
  artifactCount: number;
  selected: boolean;
  phase: RunCardPhase;
  accentIndex: number;
  onSelect: () => void;
  locale: AppLocale;
}) {
  const showSpinner = !TERMINAL_STATUSES.has(run.status);
  const accent = accentFor(accentIndex);

  return (
    <button
      type="button"
      onClick={onSelect}
      className={cn(
        'min-w-[308px] max-w-[308px] rounded-[22px] border bg-card/70 p-3.5 text-left backdrop-blur-sm transition-all duration-300',
        accent.frame,
        selected ? 'ring-1 ring-primary/40 shadow-[0_18px_36px_-30px_rgba(15,23,42,0.75)]' : 'hover:border-primary/30',
        phase === 'exiting' && 'pointer-events-none scale-[0.94] -translate-y-2 opacity-0'
      )}
    >
      <div className="flex items-start justify-between gap-3">
        <div className="min-w-0">
          <div className="flex items-center gap-2 text-[11px] font-medium uppercase tracking-[0.18em] text-muted-foreground">
            <span className={cn('h-2 w-2 rounded-full', accent.dot)} />
            <span>{pickAppText(locale, '子任务', 'Subtask')}</span>
          </div>
          <div className={cn('mt-1 truncate text-sm font-semibold', accent.title)}>{run.actor_name}</div>
          <div className="mt-1 line-clamp-2 text-xs text-muted-foreground">{run.title}</div>
          <SkillChips metadata={run.metadata} />
        </div>
        <Badge variant="outline" className={cn('border', statusTone(run.status))}>
          {appStatusLabel(run.status, locale)}
        </Badge>
      </div>

      <div className="mt-3 rounded-[18px] border border-border/60 bg-background/55 p-2.5">
        <div className="max-h-[280px] space-y-2.5 overflow-y-auto pr-1">
          {feed.length === 0 && (
            <div className="rounded-2xl border border-dashed border-border/60 bg-background/60 px-4 py-5 text-center text-sm text-muted-foreground">
              {pickAppText(locale, '等待子任务输出...', 'Waiting for subtask output...')}
            </div>
          )}
          {feed.map((item) => (
            <AgentBubble key={item.key} item={item} locale={locale} />
          ))}
        </div>
      </div>

      <div className="mt-3 flex items-center gap-2 text-[11px] text-muted-foreground">
        {showSpinner && (
          <span className="inline-flex items-center gap-1.5 rounded-full border border-border/60 bg-muted/40 px-2.5 py-1 text-foreground/80">
            <Loader2 className="h-3 w-3 animate-spin" />
            {pickAppText(locale, '运行中', 'Running')}
          </span>
        )}
        {artifactCount > 0 && <span>{pickAppText(locale, `${artifactCount} 个输出`, `${artifactCount} outputs`)}</span>}
        {typeof run.source === 'string' && run.source.trim() && <span>{run.source}</span>}
      </div>
    </button>
  );
}

function ResultCard({
  run,
  summary,
  artifactCount,
  selected,
  accentIndex,
  onSelect,
  locale,
}: {
  run: ProcessRun;
  summary: string;
  artifactCount: number;
  selected: boolean;
  accentIndex: number;
  onSelect: () => void;
  locale: AppLocale;
}) {
  const accent = accentFor(accentIndex);

  return (
    <button
      type="button"
      onClick={onSelect}
      className={cn(
        'min-w-[188px] max-w-[228px] rounded-2xl border bg-card/70 px-3.5 py-3 text-left backdrop-blur-sm transition-colors',
        accent.result,
        selected ? 'ring-1 ring-primary/35' : 'hover:border-primary/25'
      )}
    >
      <div className="flex items-center justify-between gap-3">
        <div className="min-w-0">
          <div className="text-[10px] font-medium uppercase tracking-[0.18em] text-muted-foreground">{pickAppText(locale, '结果', 'Result')}</div>
          <div className={cn('mt-1 truncate text-sm font-semibold', accent.title)}>{run.actor_name}</div>
        </div>
        <CheckCircle2 className="h-4 w-4 text-[#657162]" />
      </div>
      <div className="mt-2 line-clamp-3 text-sm text-foreground/80">{summary}</div>
      <div className="mt-3 flex items-center gap-2 text-[11px] text-muted-foreground">
        <Badge variant="outline" className={cn('border', statusTone(run.status))}>
          {appStatusLabel(run.status, locale)}
        </Badge>
        {artifactCount > 0 && <span>{pickAppText(locale, `${artifactCount} 个输出`, `${artifactCount} outputs`)}</span>}
      </div>
    </button>
  );
}

export function AgentTeamBlock({
  rootRun,
  memberRuns,
  events,
  artifacts,
  selectedRunId,
  onSelectRun,
}: {
  rootRun: ProcessRun;
  memberRuns: ProcessRun[];
  events: ProcessEvent[];
  artifacts: ProcessArtifact[];
  selectedRunId: string | null;
  onSelectRun: (runId: string) => void;
}) {
  const { locale } = useAppI18n();
  const phases = useRunCardPhases(memberRuns);
  const sortedRuns = React.useMemo(
    () =>
      [...memberRuns].sort((a, b) => {
        const at = new Date(a.started_at).getTime();
        const bt = new Date(b.started_at).getTime();
        return at - bt;
      }),
    [memberRuns]
  );
  const liveRuns = sortedRuns.filter((run) => phases[run.run_id] === 'live');
  const terminalRuns = sortedRuns.filter((run) => TERMINAL_STATUSES.has(run.status));
  const collapsedRuns = sortedRuns.filter((run) => phases[run.run_id] === 'collapsed');
  const liveCount = liveRuns.filter((run) => !TERMINAL_STATUSES.has(run.status)).length;
  if (liveRuns.length === 0 && terminalRuns.length > 0) {
    return (
      <div className="inline-flex max-w-full flex-wrap items-start gap-2 rounded-2xl border border-border/60 bg-card/35 px-3 py-3 backdrop-blur-sm">
        <div className="mr-1 flex min-h-[68px] min-w-[132px] max-w-[180px] flex-col justify-center">
          <div className="inline-flex items-center gap-2 text-[11px] font-medium uppercase tracking-[0.18em] text-muted-foreground">
            <Sparkles className="h-3.5 w-3.5" />
            {pickAppText(locale, '智能体结果', 'Agent results')}
          </div>
          <div className="mt-1 line-clamp-2 text-sm font-medium text-foreground">{rootRun.title}</div>
        </div>
        {terminalRuns.map((run, index) => {
          const runEvents = events.filter((event) => event.run_id === run.run_id);
          const runArtifacts = artifacts.filter((artifact) => artifact.run_id === run.run_id);
          const feed = buildFeed(run, runEvents, runArtifacts, locale);
          return (
            <ResultCard
              key={run.run_id}
              run={run}
              summary={runSummary(run, feed, locale)}
              artifactCount={runArtifacts.length}
              selected={selectedRunId === run.run_id}
              accentIndex={index}
              onSelect={() => onSelectRun(run.run_id)}
              locale={locale}
            />
          );
        })}
      </div>
    );
  }

  return (
    <div className="overflow-hidden rounded-[24px] border border-border/70 bg-card/45 p-3.5 backdrop-blur-sm shadow-[0_18px_42px_-34px_rgba(0,0,0,0.55)]">
      <div className="flex flex-wrap items-start justify-between gap-3">
        <div>
          <div className="inline-flex items-center gap-2 text-xs font-medium uppercase tracking-[0.2em] text-muted-foreground">
            <Sparkles className="h-3.5 w-3.5" />
            {pickAppText(locale, '任务子流程', 'Task subprocess')}
          </div>
          <div className="mt-1.5 text-base font-semibold text-foreground">{rootRun.title}</div>
          <p className="mt-1 text-sm text-muted-foreground">
            {liveCount > 0
              ? pickAppText(locale, `主 Agent 正在协调 ${liveCount} 个运行中的子任务`, `Main Agent is coordinating ${liveCount} running subtasks`)
              : pickAppText(locale, '子任务已完成，结果已折叠为摘要卡片', 'Subtasks are done. Results are folded into summary cards')}
          </p>
        </div>
        <div className="flex items-center gap-2">
          <Badge variant="outline" className="border-border/70 bg-background/55 text-foreground/85">
            {pickAppText(locale, `${memberRuns.length} 个子任务`, `${memberRuns.length} subtasks`)}
          </Badge>
          <Badge variant="outline" className={cn('border', statusTone(rootRun.status))}>
            {appStatusLabel(rootRun.status, locale)}
          </Badge>
        </div>
      </div>

      {liveRuns.length > 0 && (
        <div className="mt-3 -mx-1 overflow-x-auto pb-2">
          <div className="flex min-w-full gap-3 px-1">
            {liveRuns.map((run, index) => {
              const runEvents = events.filter((event) => event.run_id === run.run_id);
              const runArtifacts = artifacts.filter((artifact) => artifact.run_id === run.run_id);
              const feed = buildFeed(run, runEvents, runArtifacts, locale);
              return (
                <LiveAgentCard
                  key={run.run_id}
                  run={run}
                  feed={feed}
                  artifactCount={runArtifacts.length}
                  selected={selectedRunId === run.run_id}
                  phase={phases[run.run_id] || 'live'}
                  accentIndex={index}
                  onSelect={() => onSelectRun(run.run_id)}
                  locale={locale}
                />
              );
            })}
          </div>
        </div>
      )}

      {collapsedRuns.length > 0 && (
        <div className="mt-3 flex flex-wrap gap-2">
          {collapsedRuns.map((run, index) => {
            const runEvents = events.filter((event) => event.run_id === run.run_id);
            const runArtifacts = artifacts.filter((artifact) => artifact.run_id === run.run_id);
            const feed = buildFeed(run, runEvents, runArtifacts, locale);
            return (
              <ResultCard
                key={run.run_id}
                run={run}
                summary={runSummary(run, feed, locale)}
                artifactCount={runArtifacts.length}
                selected={selectedRunId === run.run_id}
                accentIndex={index}
                onSelect={() => onSelectRun(run.run_id)}
                locale={locale}
              />
            );
          })}
        </div>
      )}
    </div>
  );
}
