/**
 * Web agent cell — ticket #13, lot F4. Thin wiring (no new terminal logic) that
 * reuses the existing, transport-neutral {@link TerminalView} to render a CLI
 * agent over the WebSocket in web mode.
 *
 * The agent's CLI runs server-side (B6); the browser is display-only. This
 * component just supplies `TerminalView` with the DI **agent gateway** as the
 * opener/reattacher:
 *  - `open`  → `agent.launchAgent(projectId, agentId, …)` (frame `agent.launch`,
 *    unified `terminal.attached` ack; the minted conversation id is carried on the
 *    returned handle),
 *  - `reattach` → `agent.reattach(sessionId, …)` (frame `terminal.attach`, no
 *    relaunch, bounded scrollback repainted) — so a browser reload/reconnect
 *    resumes the surviving server-side PTY.
 *
 * The session id is persisted in component state so a re-mount re-attaches rather
 * than relaunching, matching the desktop cell's lifecycle. A structured agent is
 * refused server-side (`UNSUPPORTED`) and surfaced by `TerminalView`'s own error
 * banner — no crash. It touches only gateways via DI (no `@tauri-apps/api`).
 */

import { useCallback, useState } from "react";

import type {
  OpenTerminalOptions,
  ReattachResult,
  TerminalHandle,
} from "@/ports";
import { useGateways } from "@/app/di";
import { TerminalView, type TerminalInputApi } from "@/features/terminals";
import { TerminalKeyBar } from "./TerminalKeyBar";

interface WebAgentCellProps {
  /** Owning project id (resolved server-side by `agent.launch`). */
  projectId: string;
  /** Agent to launch/attach. */
  agentId: string;
  /** Working directory for the cell (typically the project root). */
  cwd: string;
  /** Layout leaf id, when the caller tracks one (drives the singleton guard). */
  nodeId?: string;
  /**
   * Bumped by the caller after a web cell opens/closes (ticket #61 web
   * regression) — the web equivalent of desktop `useLayout.layoutVersion`.
   * Forwarded to {@link TerminalView} as-is; never changes this component's
   * `key`, so the terminal/PTY is never recreated by it.
   */
  refitSignal?: number;
}

export function WebAgentCell({ projectId, agentId, cwd, nodeId, refitSignal }: WebAgentCellProps) {
  const { agent } = useGateways();
  const [sessionId, setSessionId] = useState<string | null>(null);
  // Input API of the mounted xterm (#69), used by the mobile key bar. Stays
  // `null` in headless renders where xterm cannot mount — the bar then renders
  // disabled rather than throwing.
  const [inputApi, setInputApi] = useState<TerminalInputApi | null>(null);

  const open = useCallback(
    (options: OpenTerminalOptions, onData: (bytes: Uint8Array) => void): Promise<TerminalHandle> =>
      agent.launchAgent(
        projectId,
        agentId,
        nodeId ? { ...options, nodeId } : options,
        onData,
      ),
    [agent, projectId, agentId, nodeId],
  );

  const reattach = useCallback(
    (sid: string, onData: (bytes: Uint8Array) => void): Promise<ReattachResult> =>
      agent.reattach(sid, onData),
    [agent],
  );

  return (
    // #69 — the cell was a flat `h-64` (256px), which on a phone left the agent
    // a letterbox roughly 20 lines tall. It now takes 60% of the *dynamic*
    // viewport on phones (so the collapsing URL bar can't clip it) and keeps a
    // fixed, desktop-like height from `sm` up. `min-h-0` on the terminal row
    // lets it shrink inside the flex column instead of pushing the key bar off.
    <div
      data-testid="web-agent-cell"
      className="flex h-[60dvh] min-h-64 w-full flex-col overflow-hidden rounded-md border border-border sm:h-80"
    >
      <div className="min-h-0 flex-1">
        <TerminalView
          cwd={cwd}
          agentMode
          open={open}
          reattach={reattach}
          sessionId={sessionId}
          onSessionId={setSessionId}
          onReady={setInputApi}
          refitSignal={refitSignal}
        />
      </div>
      <TerminalKeyBar api={inputApi} />
    </div>
  );
}
