import React, { useState, useMemo } from "react";
import type { ParsedMessage } from "../lib/types";
import {
  parseAgentEvents,
  summarizeToolCall,
  stripLineNumbers,
  type AgentEvent,
  type ParsedAgentProgress,
} from "../lib/agent-progress-parser";
import { renderMarkdown } from "../lib/markdown";

interface Props {
  events: ParsedMessage[];
}

// ── Helpers ────────────────────────────────────────────────

function formatTime(ts?: string): string {
  if (!ts) return "";
  const d = new Date(ts);
  if (isNaN(d.getTime())) return "";
  return d.toLocaleTimeString(undefined, {
    hour: "2-digit",
    minute: "2-digit",
    second: "2-digit",
  });
}

function formatTimeRange(first?: string, last?: string): string {
  if (!first) return "";
  const f = formatTime(first);
  const l = formatTime(last);
  if (!l || f === l) return f;
  return `${f}\u2013${l}`;
}

function shortToolName(name: string): string {
  if (name.startsWith("mcp__morph-mcp__")) {
    const short = name.slice("mcp__morph-mcp__".length);
    if (short === "warpgrep_codebase_search") return "WarpGrep";
    if (short === "edit_file") return "FastEdit";
    return short;
  }
  if (name.startsWith("mcp__")) {
    const parts = name.split("__");
    return parts[parts.length - 1] || name;
  }
  return name;
}

// ── SVG Icons (16x16) ─────────────────────────────────────

function IconFile() {
  return (
    <svg className="w-3.5 h-3.5" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <path d="M9 1.5H4a1 1 0 00-1 1v11a1 1 0 001 1h8a1 1 0 001-1V5.5L9 1.5z" />
      <path d="M9 1.5V5.5h4" />
    </svg>
  );
}

function IconSearch() {
  return (
    <svg className="w-3.5 h-3.5" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <circle cx="7" cy="7" r="4.5" />
      <path d="M10.5 10.5L14 14" />
    </svg>
  );
}

function IconFolder() {
  return (
    <svg className="w-3.5 h-3.5" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <path d="M2 4.5V12a1 1 0 001 1h10a1 1 0 001-1V6a1 1 0 00-1-1H8L6.5 3.5H3a1 1 0 00-1 1z" />
    </svg>
  );
}

function IconTerminal() {
  return (
    <svg className="w-3.5 h-3.5" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <path d="M2 3.5h12a1 1 0 011 1v7a1 1 0 01-1 1H2a1 1 0 01-1-1v-7a1 1 0 011-1z" />
      <path d="M4 7l2 1.5L4 10" />
      <path d="M8 10h3" />
    </svg>
  );
}

function IconPencil() {
  return (
    <svg className="w-3.5 h-3.5" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <path d="M11.5 1.5l3 3L5 14H2v-3L11.5 1.5z" />
    </svg>
  );
}

function IconAgent() {
  return (
    <svg className="w-3.5 h-3.5" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <rect x="3" y="2" width="10" height="8" rx="1" />
      <circle cx="6" cy="6" r="1" fill="currentColor" stroke="none" />
      <circle cx="10" cy="6" r="1" fill="currentColor" stroke="none" />
      <path d="M5 13v-3h6v3" />
    </svg>
  );
}

function IconGlobe() {
  return (
    <svg className="w-3.5 h-3.5" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <circle cx="8" cy="8" r="6.5" />
      <path d="M1.5 8h13M8 1.5c-2 2.5-2 9.5 0 13M8 1.5c2 2.5 2 9.5 0 13" />
    </svg>
  );
}

function IconWrench() {
  return (
    <svg className="w-3.5 h-3.5" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <path d="M10 2a4 4 0 00-3.87 5.03L2 11.17V14h2.83l4.14-4.13A4 4 0 0010 2z" />
    </svg>
  );
}

function IconCheck() {
  return (
    <svg className="w-3.5 h-3.5" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <path d="M3 8.5l3.5 3.5L13 4" />
    </svg>
  );
}

function IconChat() {
  return (
    <svg className="w-3.5 h-3.5" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <path d="M2 2.5h12a1 1 0 011 1v7a1 1 0 01-1 1H5l-3 3V3.5a1 1 0 011-1z" />
    </svg>
  );
}

function IconNote() {
  return (
    <svg className="w-3.5 h-3.5" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <path d="M4 2.5h8a1 1 0 011 1v9a1 1 0 01-1 1H4a1 1 0 01-1-1v-9a1 1 0 011-1z" />
      <path d="M5.5 5.5h5M5.5 8h5M5.5 10.5h3" />
    </svg>
  );
}

// ── Icon selection ────────────────────────────────────────

function ToolIcon({ name }: { name: string }) {
  const short = shortToolName(name);
  switch (short) {
    case "Read": return <IconFile />;
    case "Grep": case "WarpGrep": return <IconSearch />;
    case "Glob": return <IconFolder />;
    case "Bash": return <IconTerminal />;
    case "Write": case "Edit": case "FastEdit": return <IconPencil />;
    case "Task": return <IconAgent />;
    case "WebFetch": case "WebSearch": return <IconGlobe />;
    default: return <IconWrench />;
  }
}

function EventIcon({ event }: { event: AgentEvent }) {
  switch (event.kind) {
    case "tool_call": return <ToolIcon name={event.toolName} />;
    case "tool_result": return <IconCheck />;
    case "text_response": return <IconChat />;
    case "user_text": return <IconNote />;
    case "raw_content": return <IconWrench />;
  }
}

// ── Summary row label ─────────────────────────────────────

function summaryLabel(event: AgentEvent): string {
  switch (event.kind) {
    case "tool_call":
      return summarizeToolCall(event.toolName, event.input);
    case "tool_result":
      return `Result (${event.content.length.toLocaleString()} chars)`;
    case "text_response":
      return `Text response (${event.lineCount} lines)`;
    case "user_text":
      return event.text.length > 80
        ? event.text.slice(0, 79) + "\u2026"
        : event.text;
    case "raw_content":
      return event.content.length > 60
        ? event.content.slice(0, 59) + "\u2026"
        : event.content;
  }
}

function summaryToolName(event: AgentEvent): string {
  if (event.kind === "tool_call") return shortToolName(event.toolName);
  if (event.kind === "tool_result") return "Result";
  if (event.kind === "text_response") return "Response";
  if (event.kind === "user_text") return "Prompt";
  return "Raw";
}

// ── Drill-down content ────────────────────────────────────
// All content originates from local JSONL session files owned by the user.
// Same trust model as MessageBubble's markdown rendering.
// This is a local-only developer tool, not exposed to untrusted input.

function RenderedMarkdown({ content, label }: { content: string; label?: string }) {
  const html = useMemo(() => renderMarkdown(content), [content]);
  return (
    <div>
      {label && (
        <div className="text-[10px] uppercase tracking-wider text-foreground-muted mb-1">
          {label}
        </div>
      )}
      <div
        className="prose-message-progress max-h-96 overflow-y-auto"
        dangerouslySetInnerHTML={{ __html: html }}
      />
    </div>
  );
}

function DrillDown({ event }: { event: AgentEvent }) {
  if (event.kind === "tool_call") {
    const jsonBlock = "```json\n" + JSON.stringify(event.input, null, 2) + "\n```";
    return <RenderedMarkdown content={jsonBlock} label="Input" />;
  }

  if (event.kind === "tool_result") {
    // Strip cat-n line number prefixes so hljs can detect syntax,
    // then wrap in a language-tagged code fence for highlighting.
    const stripped = stripLineNumbers(event.content);
    const lang = event.language || "";
    const wrapped = "```" + lang + "\n" + stripped + "\n```";
    return <RenderedMarkdown content={wrapped} label="Result" />;
  }

  if (event.kind === "text_response") {
    return <RenderedMarkdown content={event.text} />;
  }

  if (event.kind === "user_text") {
    return <RenderedMarkdown content={event.text} />;
  }

  // raw_content
  return <RenderedMarkdown content={(event as { content: string }).content} />;
}

// ── Main component ────────────────────────────────────────

export function AgentProgressView({ events }: Props) {
  const [expandedIndex, setExpandedIndex] = useState<number | null>(null);

  const parsed: ParsedAgentProgress = useMemo(
    () => parseAgentEvents(events),
    [events]
  );

  const promptPreview = parsed.prompt
    ? parsed.prompt.length > 100
      ? parsed.prompt.slice(0, 99) + "\u2026"
      : parsed.prompt
    : null;

  return (
    <div data-testid="agent-progress-view" className="flex flex-col">
      {/* Header */}
      <div className="px-2.5 py-2 border-b border-border-muted">
        {promptPreview && (
          <div
            data-testid="agent-prompt"
            className="text-xs text-foreground font-medium leading-snug mb-0.5"
          >
            &ldquo;{promptPreview}&rdquo;
          </div>
        )}
        <div className="text-[10px] text-foreground-muted font-mono leading-tight">
          Agent {parsed.agentId || "unknown"}
          {" \u00B7 "}
          {parsed.turnCount} turn{parsed.turnCount !== 1 ? "s" : ""}
          {parsed.firstTimestamp && (
            <>
              {" \u00B7 "}
              <span className="tabular-nums">
                {formatTimeRange(parsed.firstTimestamp, parsed.lastTimestamp)}
              </span>
            </>
          )}
        </div>
      </div>

      {/* Activity feed */}
      <div className="flex flex-col">
        {parsed.events.map((event, i) => {
          const isExpanded = expandedIndex === i;
          return (
            <div key={i}>
              <button
                data-testid="agent-event-row"
                onClick={() => setExpandedIndex(isExpanded ? null : i)}
                className={`w-full flex items-center gap-2 px-2.5 py-1.5 text-left font-mono text-[11px] hover:bg-surface-overlay/50 transition-colors ${
                  isExpanded ? "bg-surface-overlay/30" : ""
                }`}
              >
                <span className="w-14 flex-shrink-0 whitespace-nowrap tabular-nums text-foreground-muted">
                  {formatTime(event.timestamp)}
                </span>
                <span className="flex-shrink-0 w-4 text-foreground-muted">
                  <EventIcon event={event} />
                </span>
                <span className="w-14 flex-shrink-0 whitespace-nowrap font-semibold text-foreground-secondary">
                  {summaryToolName(event)}
                </span>
                <span className="flex-1 min-w-0 truncate text-foreground-secondary">
                  {summaryLabel(event)}
                </span>
                <svg
                  className={`w-3 h-3 flex-shrink-0 text-foreground-muted transition-transform duration-150 ${
                    isExpanded ? "rotate-90" : ""
                  }`}
                  fill="none"
                  viewBox="0 0 24 24"
                  stroke="currentColor"
                  strokeWidth={2.5}
                >
                  <path
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    d="M8.25 4.5l7.5 7.5-7.5 7.5"
                  />
                </svg>
              </button>

              {isExpanded && (
                <div
                  data-testid="agent-drilldown"
                  className="px-2.5 py-2 bg-surface-inset/50"
                >
                  <DrillDown event={event} />
                </div>
              )}
            </div>
          );
        })}
      </div>
    </div>
  );
}
