<script lang="ts">
  import { onMount } from 'svelte';
  import ChatInput from "./ChatInput.svelte";
  import type { AgentMessage, AgentStatus } from "./agent-store.svelte.ts";
  import { t } from "./i18n.svelte.ts";

  interface Props {
    messages: AgentMessage[];
    status: AgentStatus;
    costUsd: number;
    tokens: number;
    model?: string;
    provider?: string;
    profile?: string;
    contextPct?: number;
    burnRate?: number;
    onSend?: (text: string) => void;
    onStop?: () => void;
  }

  let {
    messages,
    status,
    costUsd,
    tokens,
    model = "claude-opus-4-5",
    provider = "claude",
    contextPct = 0,
    onSend,
    onStop,
  }: Props = $props();

  let scrollEl: HTMLDivElement;
  // These need $state because Svelte 5 template bindings require reactive
  // declarations. Rule 58 exception: component-scoped UI state that drives
  // template output but has no cross-component readers.
  let promptText = $state("");
  let expandedTools = $state<Set<string>>(new Set());

  let agentPaneEl: HTMLDivElement;
  let isDragging = $state(false);

  // Auto-scroll on message change — done via onMount observer, NOT $effect
  // ($effect + messages.length + DOM mutation = infinite loop in Svelte 5)
  onMount(() => {
    const observer = new MutationObserver(() => {
      if (scrollEl) scrollEl.scrollTop = scrollEl.scrollHeight;
    });
    if (scrollEl) observer.observe(scrollEl, { childList: true, subtree: true });
    return () => observer.disconnect();
  });

  function handleSend() {
    const text = promptText.trim();
    if (!text) return;
    promptText = "";
    onSend?.(text);
  }

  function toggleTool(id: string) {
    const next = new Set(expandedTools);
    next.has(id) ? next.delete(id) : next.add(id);
    expandedTools = next;
  }

  function fmtTokens(n: number) {
    return n >= 1000 ? `${(n / 1000).toFixed(1)}k` : String(n);
  }
  function fmtCost(n: number) {
    return `$${n.toFixed(3)}`;
  }

  function dotClass(s: AgentStatus) {
    if (s === "running") return "dot-progress";
    if (s === "error") return "dot-error";
    if (s === "done") return "dot-success";
    return "dot-idle";
  }

  function statusLabel(s: AgentStatus) {
    if (s === "running") return t("agent.status.running");
    if (s === "error") return t("agent.status.error");
    if (s === "done") return t("agent.status.done");
    return t("agent.status.idle");
  }

  function onResizeMouseDown(e: MouseEvent) {
    e.preventDefault();
    isDragging = true;
    const startY = e.clientY;
    const startH = agentPaneEl?.getBoundingClientRect().height ?? 300;
    function onMove(ev: MouseEvent) {
      if (!agentPaneEl) return;
      const newH = Math.max(120, startH + (ev.clientY - startY));
      agentPaneEl.style.flexBasis = `${newH}px`;
      agentPaneEl.style.flexGrow = "0";
      agentPaneEl.style.flexShrink = "0";
    }
    function onUp() {
      isDragging = false;
      window.removeEventListener("mousemove", onMove);
      window.removeEventListener("mouseup", onUp);
    }
    window.addEventListener("mousemove", onMove);
    window.addEventListener("mouseup", onUp);
  }
</script>

<!-- Status strip (top) -->
<div class="status-strip">
  <span class="strip-dot {dotClass(status)}"></span>
  <span class="strip-label">{statusLabel(status)}</span>
  <span class="strip-model">{model}</span>
  <span class="strip-spacer"></span>
  <span class="strip-tokens">{fmtTokens(tokens)} tok</span>
  <span class="strip-sep" aria-hidden="true"></span>
  <span class="strip-cost">{fmtCost(costUsd)}</span>
  {#if status === "running" && onStop}
    <button
      class="strip-stop-btn"
      onclick={onStop}
      title={t("agent.prompt.stop")}
      aria-label={t("agent.prompt.stop")}
    >
      <svg viewBox="0 0 16 16" fill="currentColor" aria-hidden="true">
        <rect x="3" y="3" width="10" height="10" rx="1" />
      </svg>
    </button>
  {/if}
</div>

<!-- Main pane with floating input -->
<div class="agent-pane" bind:this={agentPaneEl}>
  <!-- Scroll area -->
  <div class="messages-scroll" bind:this={scrollEl}>
    {#each messages as msg, idx (msg.id)}
      {@const isFirst = idx === 0}
      {@const isLast = idx === messages.length - 1}
      <!-- timeline rows have no gap; user bubbles get margin -->
      <div class="msg-row msg-animated">
        {#if msg.role === "user"}
          <div class="user-bubble">{msg.content}</div>
        {:else if msg.role === "assistant"}
          <div class="timeline-row">
            {#if !isFirst}<div class="timeline-line-up"></div>{/if}
            <div class="timeline-diamond dot-success"></div>
            {#if !isLast}<div class="timeline-line-down"></div>{/if}
            <div class="timeline-content">{msg.content}</div>
          </div>
        {:else if msg.role === "thinking"}
          <div class="timeline-row">
            {#if !isFirst}<div class="timeline-line-up"></div>{/if}
            <div class="timeline-diamond dot-thinking"></div>
            {#if !isLast}<div class="timeline-line-down"></div>{/if}
            <div class="thinking-content">{msg.content}</div>
          </div>
        {:else if msg.role === "system"}
          <div class="timeline-row">
            {#if !isFirst}<div class="timeline-line-up"></div>{/if}
            <div class="timeline-diamond dot-system"></div>
            {#if !isLast}<div class="timeline-line-down"></div>{/if}
            <div class="system-content">{msg.content}</div>
          </div>
        {:else if msg.role === "tool-call"}
          <div class="timeline-row">
            {#if !isFirst}<div class="timeline-line-up"></div>{/if}
            <div class="timeline-diamond dot-progress"></div>
            {#if !isLast}<div class="timeline-line-down"></div>{/if}
            <div class="tool-box">
              <div class="tool-header">
                <span class="tool-name">{msg.toolName ?? "Tool"}</span>
                {#if msg.toolPath}
                  <span class="tool-path">{msg.toolPath}</span>
                {/if}
              </div>
              <div class="tool-body" class:expanded={expandedTools.has(msg.id)}>
                <div class="tool-grid">
                  <span class="tool-col-label">input</span>
                  <span class="tool-col-content">{msg.content}</span>
                </div>
                {#if !expandedTools.has(msg.id)}
                  <div class="tool-fade-overlay">
                    <button
                      class="show-more-btn"
                      onclick={() => toggleTool(msg.id)}>Show more</button
                    >
                  </div>
                {/if}
              </div>
              {#if expandedTools.has(msg.id)}
                <button class="collapse-btn" onclick={() => toggleTool(msg.id)}
                  >Show less</button
                >
              {/if}
            </div>
          </div>
        {:else if msg.role === "tool-result"}
          <div class="timeline-row">
            {#if !isFirst}<div class="timeline-line-up"></div>{/if}
            <div class="timeline-diamond dot-success"></div>
            {#if !isLast}<div class="timeline-line-down"></div>{/if}
            <div class="tool-box tool-result-box">
              <div class="tool-grid">
                <span class="tool-col-label">result</span>
                <span class="tool-col-content tool-result-content"
                  >{msg.content}</span
                >
              </div>
            </div>
          </div>
        {/if}
      </div>
    {/each}
  </div>

  <!-- Gradient fade -->
  <div class="scroll-fade" aria-hidden="true"></div>

  <!-- Floating input -->
  <div class="floating-input">
    <ChatInput
      value={promptText}
      {model}
      {provider}
      {contextPct}
      placeholder={t("agent.prompt.placeholder")}
      onSend={handleSend}
      onInput={(v) => (promptText = v)}
    />
  </div>
</div>

<!-- Drag-resize handle -->
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
<div
  class="resize-handle"
  class:dragging={isDragging}
  role="separator"
  aria-label="Drag to resize"
  onmousedown={onResizeMouseDown}
></div>

<style>
  /* ── Status strip (top) ──────────────────────────────────── */
  .status-strip {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.25rem 0.75rem;
    background: var(--ctp-mantle);
    border-bottom: 0.5px solid var(--ctp-surface1);
    font-size: 0.6875rem;
    color: var(--ctp-subtext0);
    flex-shrink: 0;
  }

  .strip-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    flex-shrink: 0;
  }

  .dot-success {
    background: var(--ctp-green);
  }
  .dot-progress {
    background: var(--ctp-peach);
  }
  .dot-error {
    background: var(--ctp-red);
  }
  .dot-idle {
    background: var(--ctp-overlay1);
  }
  .dot-thinking {
    background: var(--ctp-mauve);
  }
  .dot-system {
    background: var(--ctp-overlay0);
  }

  .strip-label {
    color: var(--ctp-subtext1);
    font-weight: 500;
  }
  .strip-model {
    color: var(--ctp-overlay1);
    margin-left: 0.25rem;
  }
  .strip-spacer {
    flex: 1;
  }
  .strip-tokens {
    color: var(--ctp-overlay1);
  }
  .strip-sep {
    width: 1px;
    height: 0.75rem;
    background: var(--ctp-surface1);
    margin: 0 0.125rem;
  }
  .strip-cost {
    color: var(--ctp-text);
    font-weight: 500;
  }

  .strip-stop-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 1.25rem;
    height: 1.25rem;
    padding: 0;
    margin-left: 0.25rem;
    background: transparent;
    border: 1px solid var(--ctp-red);
    border-radius: 0.2rem;
    color: var(--ctp-red);
    cursor: pointer;
    transition:
      background 0.12s,
      color 0.12s;
    flex-shrink: 0;
  }

  .strip-stop-btn:hover {
    background: color-mix(in srgb, var(--ctp-red) 20%, transparent);
  }

  .strip-stop-btn svg {
    width: 10px;
    height: 10px;
  }

  /* ── Main pane ────────────────────────────────────────────── */
  .agent-pane {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    overflow: hidden;
    position: relative;
    background: var(--ctp-base);
  }

  /* ── Messages scroll area ─────────────────────────────────── */
  .messages-scroll {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: 1.25rem 1.25rem 2.5rem;
    display: flex;
    flex-direction: column;
    gap: 0; /* No gap — timeline lines must connect between rows */
  }

  .messages-scroll::-webkit-scrollbar {
    width: 0.25rem;
  }
  .messages-scroll::-webkit-scrollbar-track {
    background: transparent;
  }
  .messages-scroll::-webkit-scrollbar-thumb {
    background: var(--ctp-surface1);
    border-radius: 0.25rem;
  }

  /* ── Gradient fade ────────────────────────────────────────── */
  .scroll-fade {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    height: 150px;
    background: linear-gradient(to bottom, transparent, var(--ctp-base));
    pointer-events: none;
    z-index: 10;
  }

  /* ── Floating input ───────────────────────────────────────── */
  .floating-input {
    position: absolute;
    bottom: 16px;
    left: 16px;
    right: 16px;
    z-index: 20;
  }

  /* ── Message row ──────────────────────────────────────────── */
  .msg-row {
    display: flex;
    flex-direction: column;
  }

  @keyframes fadeIn {
    from {
      opacity: 0;
      transform: translateY(8px);
    }
    to {
      opacity: 1;
      transform: translateY(0);
    }
  }

  .msg-animated {
    animation: fadeIn 0.3s ease-in-out;
  }

  /* ── User bubble (left-aligned inline block) ─────────────── */
  .user-bubble {
    display: inline-block;
    align-self: flex-start;
    background: var(--ctp-surface0);
    border: 1px solid var(--ctp-surface1);
    border-radius: 6px;
    padding: 0.25rem 0.375rem;
    margin: 0.5rem 0; /* spacing since parent gap is 0 */
    font-size: 0.8125rem;
    line-height: 1.5;
    color: var(--ctp-text);
    white-space: pre-wrap;
    word-break: break-word;
    max-width: 85%;
  }

  /* ── Timeline pattern ────────────────────────────────────── */
  .timeline-row {
    position: relative;
    padding-left: 1.875rem; /* 30px */
  }

  /* Line segments: up (above diamond) and down (below diamond) — no gaps */
  .timeline-line-up {
    position: absolute;
    left: 12px;
    top: 0;
    height: 14px; /* stops at diamond top */
    width: 1px;
    background: var(--ctp-surface0);
  }

  .timeline-line-down {
    position: absolute;
    left: 12px;
    top: 22px; /* starts at diamond bottom (15px + 7px) */
    bottom: 0;
    width: 1px;
    background: var(--ctp-surface0);
  }

  /* Diamond marker (rotated square) */
  .timeline-diamond {
    position: absolute;
    left: 9px;
    top: 14px;
    width: 7px;
    height: 7px;
    transform: rotate(45deg);
    flex-shrink: 0;
  }

  .timeline-content {
    font-size: 0.8125rem;
    line-height: 1.6;
    color: var(--ctp-text);
    padding: 0.5rem 0;
    white-space: pre-wrap;
    word-break: break-word;
  }

  /* ── Tool box ────────────────────────────────────────────── */
  .tool-box {
    border: 0.5px solid var(--ctp-surface1);
    background: var(--ctp-mantle);
    border-radius: 5px;
    overflow: hidden;
    margin: 0.25rem 0;
    font-size: 0.8125rem;
  }

  .tool-result-box {
    border-color: color-mix(in srgb, var(--ctp-teal) 30%, var(--ctp-surface1));
  }

  .tool-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.3rem 0.5rem;
    border-bottom: 0.5px solid var(--ctp-surface1);
  }

  .tool-name {
    font-weight: 700;
    font-size: 0.8125rem;
    color: var(--ctp-text);
  }

  .tool-path {
    font-family: var(--term-font-family);
    font-size: 0.8125rem;
    color: var(--ctp-blue);
  }

  .tool-body {
    position: relative;
    max-height: 60px;
    overflow: hidden;
  }

  .tool-body.expanded {
    max-height: none;
  }

  .tool-grid {
    display: grid;
    grid-template-columns: 4rem 1fr;
    gap: 0.25rem;
    padding: 0.375rem 0.5rem;
  }

  .tool-col-label {
    font-family: var(--term-font-family);
    font-size: 0.85em;
    color: var(--ctp-subtext0);
    opacity: 0.5;
    padding-top: 0.05em;
    white-space: nowrap;
  }

  .tool-col-content {
    font-family: var(--term-font-family);
    font-size: 0.8125rem;
    color: var(--ctp-subtext1);
    white-space: pre-wrap;
    word-break: break-all;
    line-height: 1.4;
  }

  .tool-result-content {
    color: var(--ctp-teal);
  }

  /* ── Thinking content ──────────────────────────────────────── */
  .thinking-content {
    font-size: 0.8125rem;
    line-height: 1.6;
    color: var(--ctp-overlay1);
    font-style: italic;
    padding: 0.5rem 0;
    white-space: pre-wrap;
    word-break: break-word;
  }

  /* ── System content ────────────────────────────────────────── */
  .system-content {
    font-size: 0.75rem;
    line-height: 1.5;
    color: var(--ctp-overlay0);
    padding: 0.25rem 0;
    white-space: pre-wrap;
    word-break: break-word;
  }

  .tool-fade-overlay {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    height: 2.5rem;
    background: linear-gradient(to bottom, transparent, var(--ctp-mantle));
    display: flex;
    align-items: flex-end;
    justify-content: center;
    padding-bottom: 0.25rem;
  }

  .show-more-btn,
  .collapse-btn {
    background: transparent;
    border: none;
    color: var(--ctp-blue);
    font-size: 0.75rem;
    cursor: pointer;
    padding: 0.125rem 0.375rem;
    border-radius: 0.2rem;
    font-family: var(--ui-font-family);
    transition: color 0.12s;
  }

  .show-more-btn:hover,
  .collapse-btn:hover {
    color: var(--ctp-lavender);
  }

  .collapse-btn {
    display: block;
    margin: 0 auto 0.25rem;
  }

  /* ── Drag-resize handle ──────────────────────────────────── */
  .resize-handle {
    height: 4px;
    background: transparent;
    cursor: row-resize;
    flex-shrink: 0;
    transition: background 0.12s;
  }

  .resize-handle:hover,
  .resize-handle.dragging {
    background: var(--ctp-surface1);
  }
</style>
