"use client";

import { useCallback, useEffect, useRef, useState } from "react";
import { AlertCircle, Bot, ChevronDown, Cpu, User, Wrench } from "lucide-react";
import { useAuth } from "@/auth/clerk";
import { getLocalAuthToken, isLocalAuthMode } from "@/auth/localAuth";
import { getApiBaseUrl } from "@/lib/api-base";
import { formatRelativeTimestamp } from "@/lib/formatters";

interface RuntimeMessage {
  event_id: string;
  session_key: string;
  session_label: string | null;
  role: string;
  model: string | null;
  content_preview: string;
  content_truncated: boolean;
  has_tool_use: boolean;
  tool_names: string[];
  timestamp: string | null;
  agent_id: string | null;
  board_id: string | null;
}

interface Gateway {
  id: string;
  name: string;
}

interface RuntimeActivityFeedProps {
  gateways: Gateway[];
}

// ---------------------------------------------------------------------------
// Role colours + icons
// ---------------------------------------------------------------------------
const ROLE_STYLE: Record<string, { label: string; badge: string; icon: React.ElementType }> = {
  user:      { label: "User",      badge: "bg-[color:var(--accent-soft)] text-[color:var(--accent)]",         icon: User  },
  assistant: { label: "Assistant", badge: "bg-[color:rgba(52,211,153,0.15)] text-[color:var(--success)]",    icon: Bot   },
  tool:      { label: "Tool",      badge: "bg-[color:rgba(251,191,36,0.15)] text-[color:var(--warning)]",    icon: Wrench},
};
const DEFAULT_ROLE = { label: "System", badge: "bg-[color:var(--surface-strong)] text-muted", icon: Cpu };

function roleMeta(role: string) {
  return ROLE_STYLE[role.toLowerCase()] ?? DEFAULT_ROLE;
}

// ---------------------------------------------------------------------------
// SSE connection helper
// ---------------------------------------------------------------------------
async function getAuthHeaders(): Promise<Record<string, string>> {
  const headers: Record<string, string> = { Accept: "text/event-stream" };
  if (isLocalAuthMode()) {
    const token = getLocalAuthToken();
    if (token) headers.Authorization = `Bearer ${token}`;
  } else {
    try {
      const clerk = (window as unknown as { Clerk?: { session?: { getToken: () => Promise<string> } } }).Clerk;
      if (clerk?.session) {
        const token = await clerk.session.getToken();
        if (token) headers.Authorization = `Bearer ${token}`;
      }
    } catch {
      // Clerk not ready
    }
  }
  return headers;
}

// ---------------------------------------------------------------------------
// Main component
// ---------------------------------------------------------------------------
export function RuntimeActivityFeed({ gateways }: RuntimeActivityFeedProps) {
  const { isSignedIn } = useAuth();
  const [gatewayId, setGatewayId] = useState<string>(() => gateways[0]?.id ?? "");
  const [messages, setMessages] = useState<RuntimeMessage[]>([]);
  const [connected, setConnected] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const cancelledRef = useRef(false);
  const seenIdsRef = useRef(new Set<string>());

  const connect = useCallback(async () => {
    if (!gatewayId || !isSignedIn) return;
    cancelledRef.current = false;
    setError(null);

    const baseUrl = getApiBaseUrl();
    const url = `${baseUrl}/api/v1/gateways/${gatewayId}/runtime-activity/stream`;
    const headers = await getAuthHeaders();

    try {
      const response = await fetch(url, { headers });
      if (!response.ok) {
        setError(`Gateway returned ${response.status}`);
        return;
      }
      if (!response.body) {
        setError("Stream unavailable");
        return;
      }
      setConnected(true);

      const reader = response.body.getReader();
      const decoder = new TextDecoder();
      let buffer = "";

      while (!cancelledRef.current) {
        const { value, done } = await reader.read();
        if (done) break;
        buffer += decoder.decode(value, { stream: true });
        buffer = buffer.replace(/\r\n/g, "\n");
        let boundary = buffer.indexOf("\n\n");
        while (boundary !== -1) {
          const raw = buffer.slice(0, boundary);
          buffer = buffer.slice(boundary + 2);
          let eventType = "";
          let data = "";
          for (const line of raw.split("\n")) {
            if (line.startsWith("event:")) eventType = line.slice(6).trim();
            else if (line.startsWith("data:")) data += line.slice(5).trim();
          }
          if (eventType === "runtime_message" && data) {
            try {
              const msg = JSON.parse(data) as RuntimeMessage;
              if (!seenIdsRef.current.has(msg.event_id)) {
                seenIdsRef.current.add(msg.event_id);
                setMessages((prev) => [msg, ...prev].slice(0, 300));
              }
            } catch {
              // skip malformed event
            }
          }
          boundary = buffer.indexOf("\n\n");
        }
      }
    } catch (err) {
      if (!cancelledRef.current) {
        setError(err instanceof Error ? err.message : "Connection lost");
        setConnected(false);
      }
    }
  }, [gatewayId, isSignedIn]);

  useEffect(() => {
    setMessages([]);
    seenIdsRef.current = new Set();
    setConnected(false);
    connect();
    return () => {
      cancelledRef.current = true;
    };
  }, [connect]);

  if (!gateways.length) {
    return (
      <div className="flex flex-col items-center gap-3 rounded-xl border border-dashed border-border bg-muted/50 p-12 text-center">
        <Cpu className="h-10 w-10 text-muted-foreground" />
        <p className="font-medium text-foreground">No gateways configured</p>
        <p className="text-sm text-muted-foreground">
          Configure a gateway on a board to see its live activity here.
        </p>
      </div>
    );
  }

  return (
    <div className="flex flex-col gap-4">
      {/* Gateway picker + status */}
      <div className="flex flex-wrap items-center justify-between gap-3">
        <div className="flex items-center gap-2">
          <div
            className={`h-2 w-2 rounded-full ${
              connected
                ? "bg-[color:var(--success)]"
                : "bg-[color:var(--border-strong)]"
            }`}
          />
          <span className="text-sm text-muted-foreground">
            {connected ? "Live" : "Connecting…"}
          </span>
        </div>

        {gateways.length > 1 && (
          <div className="relative">
            <select
              value={gatewayId}
              onChange={(e) => setGatewayId(e.target.value)}
              className="appearance-none rounded-lg border border-border bg-card px-3 py-1.5 pr-8 text-sm text-foreground focus:outline-none focus:ring-2 focus:ring-ring"
            >
              {gateways.map((gw) => (
                <option key={gw.id} value={gw.id}>
                  {gw.name}
                </option>
              ))}
            </select>
            <ChevronDown className="pointer-events-none absolute right-2 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
          </div>
        )}
      </div>

      {error && (
        <div className="flex items-start gap-2 rounded-lg border border-destructive/40 bg-destructive/10 px-3 py-2 text-sm text-destructive">
          <AlertCircle className="mt-0.5 h-4 w-4 shrink-0" />
          <span>{error}</span>
        </div>
      )}

      {/* Feed */}
      <div className="space-y-2">
        {messages.length === 0 && connected && (
          <p className="py-8 text-center text-sm text-muted-foreground">
            Waiting for session activity…
          </p>
        )}
        {messages.map((msg) => {
          const meta = roleMeta(msg.role);
          const Icon = meta.icon;
          const shortModel = msg.model?.includes("/")
            ? msg.model.split("/")[1]
            : msg.model;
          return (
            <div
              key={msg.event_id}
              className="rounded-lg border border-border bg-card px-4 py-3 shadow-sm"
            >
              <div className="flex flex-wrap items-start gap-2">
                <span
                  className={`inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-xs font-medium ${meta.badge}`}
                >
                  <Icon className="h-3 w-3" />
                  {meta.label}
                </span>
                {msg.session_label && (
                  <span className="text-xs text-muted-foreground">
                    {msg.session_label}
                  </span>
                )}
                {shortModel && (
                  <span className="rounded-full bg-muted px-2 py-0.5 text-xs text-muted-foreground">
                    {shortModel}
                  </span>
                )}
                {msg.has_tool_use && msg.tool_names.length > 0 && (
                  <span className="rounded-full bg-[color:rgba(251,191,36,0.10)] px-2 py-0.5 text-xs text-[color:var(--warning)]">
                    {msg.tool_names.join(", ")}
                  </span>
                )}
                <span className="ml-auto text-xs text-muted-foreground">
                  {msg.timestamp
                    ? formatRelativeTimestamp(msg.timestamp)
                    : null}
                </span>
              </div>
              {msg.content_preview && (
                <p className="mt-2 line-clamp-3 text-sm text-foreground/80">
                  {msg.content_preview}
                  {msg.content_truncated && (
                    <span className="ml-1 text-xs text-muted-foreground">
                      [truncated]
                    </span>
                  )}
                </p>
              )}
              {msg.board_id && (
                <p className="mt-1 text-xs text-muted-foreground">
                  board {msg.board_id.slice(0, 8)}…
                </p>
              )}
            </div>
          );
        })}
      </div>
    </div>
  );
}
