/**
 * Web client root — ticket #13, lot F2. Mounted (instead of the desktop `App`)
 * only when the HTTP transport is selected (`VITE_TRANSPORT="http"`).
 *
 * Routes on the {@link WebSession} paired flag: not paired ⇒ {@link PairingScreen};
 * paired ⇒ the read-only {@link WebWorkspace}. It subscribes to the session's
 * `onUnauthorized` signal so a `401` from any `/api/invoke` (expired/missing
 * cookie) drops back to pairing automatically. "Se déconnecter" (F6) revokes the
 * server session (`POST /api/logout`), tears down the live WS singleton, and
 * returns to pairing.
 */

import { useEffect, useState } from "react";

import { Button } from "@/shared";
import { disconnectWebLive, getWebSession, type WebSession } from "@/adapters/http";
import { PairingScreen } from "./PairingScreen";
import { WebWorkspace } from "./WebWorkspace";

interface WebAppProps {
  /** Injectable session (tests); defaults to the shared singleton. */
  session?: WebSession;
}

export function WebApp({ session }: WebAppProps = {}) {
  const webSession = session ?? getWebSession();
  const [paired, setPaired] = useState(() => webSession.isPaired());
  const [signingOut, setSigningOut] = useState(false);

  useEffect(() => {
    // A 401 anywhere clears the flag and fires this: return to pairing. The live
    // WS is torn down by the composition-root 401 handler (F6).
    return webSession.onUnauthorized(() => setPaired(false));
  }, [webSession]);

  async function signOut(): Promise<void> {
    if (signingOut) return;
    setSigningOut(true);
    try {
      // Revoke the server session (best-effort), then drop the live socket so it
      // stops reconnecting, and return to pairing regardless of the outcome.
      await webSession.logout();
    } finally {
      disconnectWebLive();
      setSigningOut(false);
      setPaired(false);
    }
  }

  return (
    <div className="flex h-full flex-col bg-canvas text-content">
      <header
        data-testid="web-header"
        className="flex shrink-0 items-center justify-between border-b border-border px-4 py-3 pt-[max(0.75rem,env(safe-area-inset-top))] pl-[max(1rem,env(safe-area-inset-left))] pr-[max(1rem,env(safe-area-inset-right))] sm:px-6"
      >
        <div className="flex items-baseline gap-2">
          <h1 className="text-base font-semibold tracking-tight sm:text-lg">IdeA</h1>
          <span className="rounded-md bg-raised px-1.5 py-0.5 text-[0.65rem] font-medium uppercase text-muted">
            web
          </span>
        </div>
        {paired && (
          <Button variant="ghost" size="sm" loading={signingOut} onClick={() => void signOut()}>
            Se déconnecter
          </Button>
        )}
      </header>

      <div className="flex flex-1 flex-col overflow-hidden">
        {paired ? (
          <WebWorkspace />
        ) : (
          <PairingScreen session={webSession} onPaired={() => setPaired(true)} />
        )}
      </div>
    </div>
  );
}
