/**
 * `WebProjectsPanel` — the "Projects" panel, web variant (ticket #90).
 *
 * The desktop `ProjectsView` project manager depends on `SystemGateway.pickFolder`
 * (a native folder-browse dialog), which is desktop-only (see
 * `adapters/http/unsupported.ts`). The web client cannot reuse it as-is: project
 * creation here takes the root as a manually typed absolute path, resolved
 * server-side (the machine running the IdeA server, not the browsing device).
 */

import { useState } from "react";

import type { GatewayError, Project } from "@/domain";
import { Button, Input, Panel, Spinner } from "@/shared";

function describe(e: unknown): string {
  if (e && typeof e === "object" && "message" in e) {
    return String((e as GatewayError).message);
  }
  return String(e);
}

export interface WebProjectsPanelProps {
  projects: Project[] | null;
  openId: string | null;
  onOpen: (projectId: string) => void;
  onCreate: (name: string, root: string) => Promise<Project>;
  onRefresh: () => void;
}

export function WebProjectsPanel({
  projects,
  openId,
  onOpen,
  onCreate,
  onRefresh,
}: WebProjectsPanelProps) {
  const [name, setName] = useState("");
  const [root, setRoot] = useState("");
  const [busy, setBusy] = useState(false);
  const [createError, setCreateError] = useState<string | null>(null);

  const canCreate = name.trim().length > 0 && root.trim().length > 0 && !busy;

  async function submit(e: React.FormEvent) {
    e.preventDefault();
    if (!canCreate) return;
    setBusy(true);
    setCreateError(null);
    try {
      const created = await onCreate(name.trim(), root.trim());
      setName("");
      setRoot("");
      onOpen(created.id);
    } catch (e) {
      setCreateError(describe(e));
    } finally {
      setBusy(false);
    }
  }

  return (
    <div className="flex flex-col gap-4">
      <div className="flex items-center justify-between">
        <h2 className="text-base font-semibold tracking-tight">Projets</h2>
        <Button variant="ghost" size="sm" onClick={onRefresh}>
          Rafraîchir
        </Button>
      </div>

      <Panel title="Nouveau projet">
        <form onSubmit={(e) => void submit(e)} className="flex flex-col gap-2">
          <Input
            aria-label="Nom du projet"
            placeholder="Nom du projet"
            value={name}
            onChange={(e) => setName(e.target.value)}
          />
          <Input
            aria-label="Chemin du projet"
            placeholder="/chemin/absolu/du/projet"
            value={root}
            onChange={(e) => setRoot(e.target.value)}
          />
          <p className="text-xs text-muted">
            Saisir un chemin absolu accessible depuis le serveur IdeA.
          </p>
          {createError && (
            <p role="alert" className="text-xs text-danger">
              {createError}
            </p>
          )}
          <Button type="submit" variant="primary" disabled={!canCreate} loading={busy}>
            Créer le projet
          </Button>
        </form>
      </Panel>

      {projects === null ? (
        <span className="inline-flex items-center gap-1.5 text-sm text-muted">
          <Spinner size={12} /> Chargement des projets…
        </span>
      ) : projects.length === 0 ? (
        <p className="text-sm text-muted">Aucun projet.</p>
      ) : (
        <ul className="flex flex-col gap-2" data-testid="web-project-list">
          {projects.map((p) => (
            <li key={p.id}>
              <button
                type="button"
                onClick={() => onOpen(p.id)}
                aria-pressed={openId === p.id}
                className="flex w-full flex-col items-start rounded-md border border-border bg-raised px-3 py-2 text-left transition-colors hover:border-primary aria-pressed:border-primary"
              >
                <span className="text-sm font-medium text-content">{p.name}</span>
                <span className="text-xs text-faint">{p.root}</span>
              </button>
            </li>
          ))}
        </ul>
      )}
    </div>
  );
}
