import { useEffect, useState } from "react";
import { invoke } from "@tauri-apps/api/core";

type DesktopStatus = "loading" | "ready" | "error";
type CheckStatus = "pass" | "warn" | "fail";

type DesktopCheck = {
  id: string;
  label: string;
  status: CheckStatus;
  detail: string;
};

type GitCommitBinding = {
  github_login: string;
  commit_name: string;
  commit_email: string;
};

type DesktopProfile = {
  identity: string;
  handle: string;
  display_name: string;
  rho_home: string;
  source: string;
  has_local_private_keys: boolean;
  signing_key_path?: string;
  encryption_key_path?: string;
  proof_verified: boolean;
  proof_url?: string;
  git_commit_binding?: GitCommitBinding;
};

type ProfileSelection = {
  identity?: string;
  rho_home?: string;
};

type CommandResult = {
  ok: boolean;
  code?: number;
  stdout: string;
  stderr: string;
};

type GitHubAccount = {
  login: string;
  host: string;
  active: boolean;
  state: string;
  git_protocol: string;
  token_source: string;
  matching_identity: string;
  has_rho_profile: boolean;
  has_local_private_keys: boolean;
  signing_key_path?: string;
  encryption_key_path?: string;
  proof_verified: boolean;
  proof_url?: string;
  git_commit_binding?: GitCommitBinding;
};

type OnboardingState = {
  rho_home: string;
  gh_accounts: GitHubAccount[];
  local_profiles: DesktopProfile[];
};

type DesktopProject = {
  id: string;
  name: string;
  path: string;
  exists: boolean;
  is_git: boolean;
  is_rho: boolean;
  rho_project_id?: string;
  owner?: string;
  role: string;
  current_branch?: string;
  remote_url?: string;
  dirty: boolean;
  upstream?: string;
  ahead: number;
  behind: number;
  status_summary: string;
  warning?: string;
};

type FileEntry = {
  path: string;
  kind: string;
  status?: string;
};

type MemberInfo = {
  identity: string;
  handle: string;
  role: string;
};

type ParticipantInfo = {
  handle: string;
  identity?: string;
  display_name?: string;
  signing_fingerprint?: string;
  encryption_fingerprint?: string;
  proof_url?: string;
};

type RepoFileSummary = {
  path: string;
  title: string;
  summary: string;
};

type ToolInfo = {
  id: string;
  action_type?: string;
  owner?: string;
  approval_required: boolean;
  path: string;
};

type MessageInfo = {
  path: string;
  inbox: string;
  thread: string;
  kind: string;
  encrypted: boolean;
  signed: boolean;
  summary: string;
};

type PendingAction = {
  id: string;
  kind: string;
  actor?: string;
  summary: string;
  path: string;
};

type GitStatusEntry = {
  path: string;
  status: string;
};

type RepoDetail = {
  project: DesktopProject;
  files: FileEntry[];
  members: MemberInfo[];
  participants: ParticipantInfo[];
  policy_files: RepoFileSummary[];
  tools: ToolInfo[];
  messages: MessageInfo[];
  pending_actions: PendingAction[];
  status_entries: GitStatusEntry[];
};

export default function App() {
  const [status, setStatus] = useState<DesktopStatus>("loading");
  const [version, setVersion] = useState<string>("");
  const [error, setError] = useState<string>("");
  const [profiles, setProfiles] = useState<DesktopProfile[]>([]);
  const [selectedIdentity, setSelectedIdentity] = useState<string>("");
  const [checks, setChecks] = useState<DesktopCheck[]>([]);
  const [isChecking, setIsChecking] = useState<boolean>(false);
  const [actionResult, setActionResult] = useState<string>("");
  const [isSwitchingGh, setIsSwitchingGh] = useState<boolean>(false);
  const [isCheckingEnv, setIsCheckingEnv] = useState<boolean>(false);
  const [projects, setProjects] = useState<DesktopProject[]>([]);
  const [projectsError, setProjectsError] = useState<string>("");
  const [isLoadingProjects, setIsLoadingProjects] = useState<boolean>(false);
  const [isAddingProject, setIsAddingProject] = useState<boolean>(false);
  const [isCloningProject, setIsCloningProject] = useState<boolean>(false);
  const [isSettingUpRhoRepo, setIsSettingUpRhoRepo] = useState<boolean>(false);
  const [localProjectPath, setLocalProjectPath] = useState<string>("");
  const [cloneUrl, setCloneUrl] = useState<string>("");
  const [cloneDestination, setCloneDestination] = useState<string>("");
  const [setupRepoPath, setSetupRepoPath] = useState<string>("");
  const [setupRepoId, setSetupRepoId] = useState<string>("");
  const [setupRemoteUrl, setSetupRemoteUrl] = useState<string>("");
  const [setupProtectOwnerInbox, setSetupProtectOwnerInbox] = useState<boolean>(true);
  const [selectedProjectPath, setSelectedProjectPath] = useState<string>("");
  const [repoDetail, setRepoDetail] = useState<RepoDetail | null>(null);
  const [repoDetailError, setRepoDetailError] = useState<string>("");
  const [isLoadingRepoDetail, setIsLoadingRepoDetail] = useState<boolean>(false);
  const [onboarding, setOnboarding] = useState<OnboardingState | null>(null);
  const [onboardingError, setOnboardingError] = useState<string>("");
  const [isLoadingOnboarding, setIsLoadingOnboarding] = useState<boolean>(false);
  const [isCreatingProfile, setIsCreatingProfile] = useState<string>("");
  const [isVerifyingProfile, setIsVerifyingProfile] = useState<string>("");
  const [isBindingCommitAuthor, setIsBindingCommitAuthor] = useState<string>("");
  const [manualHandle, setManualHandle] = useState<string>("");
  const [repoActionTargetHandle, setRepoActionTargetHandle] = useState<string>("");
  const [repoActionRequestId, setRepoActionRequestId] = useState<string>("");
  const [isRunningRepoAction, setIsRunningRepoAction] = useState<string>("");
  const [commitMessage, setCommitMessage] = useState<string>("");
  const [isCommittingRepo, setIsCommittingRepo] = useState<boolean>(false);
  const [messageRecipient, setMessageRecipient] = useState<string>("");
  const [messageThread, setMessageThread] = useState<string>("");
  const [messageText, setMessageText] = useState<string>("");
  const [isSendingMessage, setIsSendingMessage] = useState<boolean>(false);
  const [branchName, setBranchName] = useState<string>("");
  const [isRunningGitAction, setIsRunningGitAction] = useState<string>("");

  useEffect(() => {
    const queryIdentity = new URLSearchParams(window.location.search).get("identity") ?? "";

    void Promise.all([
      invoke<string>("app_version"),
      invoke<DesktopProfile[]>("desktop_profiles"),
      invoke<OnboardingState>("desktop_onboarding")
    ])
      .then(([value, discoveredProfiles, onboardingState]) => {
        setVersion(value);
        setProfiles(discoveredProfiles);
        setOnboarding(onboardingState);
        setSelectedIdentity(queryIdentity || discoveredProfiles[0]?.identity || "");
        setStatus("ready");
      })
      .catch((cause: unknown) => {
        setError(cause instanceof Error ? cause.message : String(cause));
        setStatus("error");
      });
  }, []);

  useEffect(() => {
    if (status !== "ready") {
      return;
    }
    void runChecks(selectedIdentity);
    void loadProjects(selectedIdentity);
    setSelectedProjectPath("");
    setRepoDetail(null);
  }, [selectedIdentity, status]);

  const selectedProfile = profiles.find((profile) => profile.identity === selectedIdentity);

  function selection(identity = selectedIdentity): ProfileSelection | undefined {
    const profile = profiles.find((candidate) => candidate.identity === identity);
    if (!profile && !identity) {
      return undefined;
    }
    return {
      identity: identity || profile?.identity,
      rho_home: profile?.rho_home
    };
  }

  async function runChecks(identity = selectedIdentity) {
    setIsChecking(true);
    try {
      const result = await invoke<DesktopCheck[]>("desktop_checks", {
        profile: selection(identity)
      });
      setChecks(result);
    } catch (cause) {
      setError(cause instanceof Error ? cause.message : String(cause));
      setStatus("error");
    } finally {
      setIsChecking(false);
    }
  }

  async function refreshProfilesAndOnboarding(preferredHandle?: string) {
    setIsLoadingOnboarding(true);
    setOnboardingError("");
    try {
      const [discoveredProfiles, onboardingState] = await Promise.all([
        invoke<DesktopProfile[]>("desktop_profiles"),
        invoke<OnboardingState>("desktop_onboarding")
      ]);
      setProfiles(discoveredProfiles);
      setOnboarding(onboardingState);
      if (preferredHandle) {
        const profile = discoveredProfiles.find((candidate) => candidate.handle === preferredHandle);
        if (profile) {
          setSelectedIdentity(profile.identity);
        }
      } else if (!selectedIdentity && discoveredProfiles[0]) {
        setSelectedIdentity(discoveredProfiles[0].identity);
      }
    } catch (cause) {
      setOnboardingError(cause instanceof Error ? cause.message : String(cause));
    } finally {
      setIsLoadingOnboarding(false);
    }
  }

  async function openProfileWindow() {
    await invoke("open_profile_window", {
      profile: selection()
    });
  }

  async function openProfileWindowForHandle(handle: string) {
    const profile = profiles.find((candidate) => candidate.handle === handle);
    const profileSelection: ProfileSelection = {
      identity: profile?.identity || `rho://id/github/${handle}`,
      rho_home: profile?.rho_home || onboarding?.rho_home
    };
    await invoke("open_profile_window", {
      profile: profileSelection
    });
  }

  async function switchGhProfile() {
    setIsSwitchingGh(true);
    try {
      const result = await invoke<CommandResult>("switch_github_profile", {
        profile: selection()
      });
      setActionResult(formatCommandResult("rho gh switch", result));
      await runChecks();
    } catch (cause) {
      setActionResult(cause instanceof Error ? cause.message : String(cause));
    } finally {
      setIsSwitchingGh(false);
    }
  }

  async function switchGhHandle(handle: string) {
    setIsSwitchingGh(true);
    try {
      const result = await invoke<CommandResult>("switch_github_profile", {
        profile: {
          identity: `rho://id/github/${handle}`,
          rho_home: onboarding?.rho_home || selectedProfile?.rho_home
        }
      });
      setActionResult(formatCommandResult(`rho gh switch ${handle}`, result));
      await runChecks();
      await refreshProfilesAndOnboarding(handle);
    } catch (cause) {
      setActionResult(cause instanceof Error ? cause.message : String(cause));
    } finally {
      setIsSwitchingGh(false);
    }
  }

  async function createProfileForHandle(handle: string) {
    const cleanHandle = handle.trim();
    if (!cleanHandle) {
      setOnboardingError("Enter a GitHub handle first.");
      return;
    }
    setIsCreatingProfile(cleanHandle);
    setOnboardingError("");
    try {
      const result = await invoke<CommandResult>("create_github_profile", {
        input: {
          handle: cleanHandle,
          displayName: cleanHandle,
          rhoHome: onboarding?.rho_home
        }
      });
      setActionResult(formatCommandResult(`rho id init ${cleanHandle}`, result));
      setManualHandle("");
      await refreshProfilesAndOnboarding(cleanHandle);
    } catch (cause) {
      setOnboardingError(cause instanceof Error ? cause.message : String(cause));
    } finally {
      setIsCreatingProfile("");
    }
  }

  async function createMissingDetectedProfiles() {
    const missing = onboarding?.gh_accounts.filter((account) => !account.has_rho_profile) ?? [];
    if (missing.length === 0) {
      setOnboardingError("");
      setActionResult("All detected GitHub accounts already have Rho profiles.");
      return;
    }
    setOnboardingError("");
    const results: string[] = [];
    for (const account of missing) {
      setIsCreatingProfile(account.login);
      try {
        const result = await invoke<CommandResult>("create_github_profile", {
          input: {
            handle: account.login,
            displayName: account.login,
            rhoHome: onboarding?.rho_home
          }
        });
        results.push(formatCommandResult(`rho id init ${account.login}`, result));
      } catch (cause) {
        results.push(`${account.login}: ${cause instanceof Error ? cause.message : String(cause)}`);
      }
    }
    setIsCreatingProfile("");
    setActionResult(results.join("\n\n"));
    await refreshProfilesAndOnboarding();
  }

  async function verifyProfileForHandle(handle: string) {
    setIsVerifyingProfile(handle);
    setOnboardingError("");
    try {
      const result = await invoke<CommandResult>("verify_github_profile", {
        handle,
        rhoHome: onboarding?.rho_home
      });
      setActionResult(formatCommandResult(`rho id verify-github ${handle}`, result));
      await refreshProfilesAndOnboarding(handle);
    } catch (cause) {
      setOnboardingError(cause instanceof Error ? cause.message : String(cause));
    } finally {
      setIsVerifyingProfile("");
    }
  }

  async function bindCommitAuthorForHandle(handle: string) {
    setIsBindingCommitAuthor(handle);
    setOnboardingError("");
    try {
      const result = await invoke<CommandResult>("bind_github_commit_profile", {
        handle,
        rhoHome: onboarding?.rho_home
      });
      setActionResult(formatCommandResult(`bind commit author ${handle}`, result));
      await runChecks();
      await refreshProfilesAndOnboarding(handle);
    } catch (cause) {
      setOnboardingError(cause instanceof Error ? cause.message : String(cause));
    } finally {
      setIsBindingCommitAuthor("");
    }
  }

  async function showProfileForHandle(handle: string) {
    setOnboardingError("");
    try {
      const result = await invoke<CommandResult>("show_github_profile", {
        handle,
        rhoHome: onboarding?.rho_home
      });
      setActionResult(formatCommandResult(`rho id show ${handle}`, result));
    } catch (cause) {
      setOnboardingError(cause instanceof Error ? cause.message : String(cause));
    }
  }

  async function checkProfileEnv() {
    setIsCheckingEnv(true);
    try {
      const result = await invoke<CommandResult>("profile_rho_env", {
        profile: selection()
      });
      setActionResult(formatCommandResult("rho env status", result));
    } catch (cause) {
      setActionResult(cause instanceof Error ? cause.message : String(cause));
    } finally {
      setIsCheckingEnv(false);
    }
  }

  async function loadProjects(identity = selectedIdentity) {
    setIsLoadingProjects(true);
    setProjectsError("");
    try {
      const result = await invoke<DesktopProject[]>("desktop_projects", {
        profile: selection(identity)
      });
      setProjects(result);
      if (selectedProjectPath && !result.some((project) => project.path === selectedProjectPath)) {
        setSelectedProjectPath("");
        setRepoDetail(null);
      }
    } catch (cause) {
      setProjectsError(cause instanceof Error ? cause.message : String(cause));
    } finally {
      setIsLoadingProjects(false);
    }
  }

  async function addLocalProject() {
    if (!localProjectPath.trim()) {
      setProjectsError("Enter a local repository path first.");
      return;
    }
    setIsAddingProject(true);
    setProjectsError("");
    try {
      const project = await invoke<DesktopProject>("add_local_project", {
        path: localProjectPath,
        profile: selection()
      });
      setActionResult(`Added ${project.name}`);
      setLocalProjectPath("");
      await loadProjects();
      await selectProject(project.path);
    } catch (cause) {
      setProjectsError(cause instanceof Error ? cause.message : String(cause));
    } finally {
      setIsAddingProject(false);
    }
  }

  async function cloneProject() {
    if (!cloneUrl.trim()) {
      setProjectsError("Enter a GitHub repository URL first.");
      return;
    }
    setIsCloningProject(true);
    setProjectsError("");
    try {
      const project = await invoke<DesktopProject>("clone_github_project", {
        url: cloneUrl,
        destination: cloneDestination || undefined,
        profile: selection()
      });
      setActionResult(`Cloned ${project.name}`);
      setCloneUrl("");
      setCloneDestination("");
      await loadProjects();
      await selectProject(project.path);
    } catch (cause) {
      setProjectsError(cause instanceof Error ? cause.message : String(cause));
    } finally {
      setIsCloningProject(false);
    }
  }

  async function setupRhoRepo() {
    if (!setupRepoPath.trim()) {
      setProjectsError("Enter a repository folder path first.");
      return;
    }
    if (!selectedIdentity) {
      setProjectsError("Select a Rho profile before setting up a repo.");
      return;
    }
    setIsSettingUpRhoRepo(true);
    setProjectsError("");
    try {
      const result = await invoke<CommandResult>("setup_rho_repo", {
        input: {
          path: setupRepoPath,
          repoId: setupRepoId || undefined,
          remoteUrl: setupRemoteUrl || undefined,
          profile: selection(),
          protectOwnerInbox: setupProtectOwnerInbox
        }
      });
      setActionResult(formatCommandResult("setup rho repo", result));
      setSetupRepoPath("");
      setSetupRepoId("");
      setSetupRemoteUrl("");
      await loadProjects();
    } catch (cause) {
      setProjectsError(cause instanceof Error ? cause.message : String(cause));
    } finally {
      setIsSettingUpRhoRepo(false);
    }
  }

  async function selectProject(path: string) {
    setSelectedProjectPath(path);
    setRepoDetailError("");
    setIsLoadingRepoDetail(true);
    try {
      const detail = await invoke<RepoDetail>("repo_detail", {
        path,
        profile: selection()
      });
      setRepoDetail(detail);
    } catch (cause) {
      setRepoDetail(null);
      setRepoDetailError(cause instanceof Error ? cause.message : String(cause));
    } finally {
      setIsLoadingRepoDetail(false);
    }
  }

  async function openProjectFolder(path: string) {
    try {
      const result = await invoke<CommandResult>("open_project_folder", { path });
      if (!result.ok) {
        setActionResult(formatCommandResult("open folder", result));
      }
    } catch (cause) {
      setActionResult(cause instanceof Error ? cause.message : String(cause));
    }
  }

  async function runRepoAction(
    action: string,
    overrides: { target?: string; requestId?: string } = {}
  ) {
    if (!repoDetail) {
      return;
    }
    setIsRunningRepoAction(action);
    try {
      const result = await invoke<CommandResult>("run_repo_cli_action", {
        input: {
          path: repoDetail.project.path,
          profile: selection(),
          action,
          target: (overrides.target ?? repoActionTargetHandle) || undefined,
          requestId: (overrides.requestId ?? repoActionRequestId) || undefined
        }
      });
      setActionResult(formatCommandResult(action.replace(/_/g, " "), result));
      await loadProjects();
      await selectProject(repoDetail.project.path);
    } catch (cause) {
      setActionResult(cause instanceof Error ? cause.message : String(cause));
    } finally {
      setIsRunningRepoAction("");
    }
  }

  async function commitRepoChanges() {
    if (!repoDetail) {
      return;
    }
    if (!commitMessage.trim()) {
      setActionResult("Enter a commit message first.");
      return;
    }
    setIsCommittingRepo(true);
    try {
      const result = await invoke<CommandResult>("commit_repo_changes", {
        input: {
          path: repoDetail.project.path,
          profile: selection(),
          message: commitMessage
        }
      });
      setActionResult(formatCommandResult("rho commit", result));
      setCommitMessage("");
      await loadProjects();
      await selectProject(repoDetail.project.path);
    } catch (cause) {
      setActionResult(cause instanceof Error ? cause.message : String(cause));
    } finally {
      setIsCommittingRepo(false);
    }
  }

  async function sendProjectMessage() {
    if (!repoDetail) {
      return;
    }
    if (!messageRecipient.trim()) {
      setActionResult("Enter a recipient GitHub handle first.");
      return;
    }
    if (!messageText.trim()) {
      setActionResult("Enter a message first.");
      return;
    }
    setIsSendingMessage(true);
    try {
      const result = await invoke<CommandResult>("send_project_message", {
        input: {
          path: repoDetail.project.path,
          profile: selection(),
          to: messageRecipient,
          thread: messageThread || undefined,
          text: messageText,
          messageType: "chat"
        }
      });
      setActionResult(formatCommandResult("send message", result));
      setMessageThread("");
      setMessageText("");
      await loadProjects();
      await selectProject(repoDetail.project.path);
    } catch (cause) {
      setActionResult(cause instanceof Error ? cause.message : String(cause));
    } finally {
      setIsSendingMessage(false);
    }
  }

  async function runGitAction(action: string, branch?: string) {
    if (!repoDetail) {
      return;
    }
    setIsRunningGitAction(action);
    try {
      const result = await invoke<CommandResult>("run_git_repo_action", {
        input: {
          path: repoDetail.project.path,
          profile: selection(),
          action,
          branch: (branch ?? branchName) || undefined
        }
      });
      setActionResult(formatCommandResult(action.replace(/_/g, " "), result));
      await loadProjects();
      await selectProject(repoDetail.project.path);
    } catch (cause) {
      setActionResult(cause instanceof Error ? cause.message : String(cause));
    } finally {
      setIsRunningGitAction("");
    }
  }

  function formatCommandResult(label: string, result: CommandResult): string {
    const body = [result.stdout, result.stderr].filter(Boolean).join("\n");
    const statusText = result.ok ? "ok" : `exit ${result.code ?? "unknown"}`;
    return `${label}: ${statusText}${body ? `\n${body}` : ""}`;
  }

  function shortPath(path: string): string {
    return path.length > 70 ? `...${path.slice(-67)}` : path;
  }

  function profileForHandle(handle: string): DesktopProfile | undefined {
    return profiles.find((profile) => profile.handle === handle);
  }

  function requestIdFromPath(path: string): string {
    return path.split("/").find((part) => part.startsWith("req-")) || "";
  }

  return (
    <main className="app-shell">
      <section className="workspace">
        <header className="topbar">
          <div>
            <h1>Rho</h1>
            <p>Local-first collaboration for protected agent workflows.</p>
          </div>
          <span className="status" data-state={status}>
            {status === "ready" ? `v${version}` : status}
          </span>
        </header>

        <div className="profile-toolbar">
          <label>
            <span>Profile</span>
            <select
              value={selectedIdentity}
              onChange={(event) => setSelectedIdentity(event.target.value)}
            >
              {profiles.length === 0 ? (
                <option value="">No local profiles found</option>
              ) : null}
              {profiles.map((profile) => (
                <option key={profile.identity} value={profile.identity}>
                  {profile.handle} - {profile.source}
                </option>
              ))}
            </select>
          </label>
          <div className="profile-actions">
            <button type="button" onClick={() => void runChecks()} disabled={isChecking}>
              {isChecking ? "Checking" : "Recheck"}
            </button>
            <button
              type="button"
              onClick={() => void switchGhProfile()}
              disabled={isSwitchingGh || !selectedIdentity}
            >
              {isSwitchingGh ? "Switching" : "Switch gh"}
            </button>
            <button
              type="button"
              onClick={() => void checkProfileEnv()}
              disabled={isCheckingEnv || !selectedIdentity}
            >
              {isCheckingEnv ? "Checking" : "Check Rho Env"}
            </button>
            <button type="button" onClick={() => void openProfileWindow()}>
              New Profile Window
            </button>
          </div>
        </div>

        {selectedProfile ? (
          <section className="profile-summary">
            <div>
              <h2>{selectedProfile.display_name}</h2>
              <p>{selectedProfile.identity}</p>
              {selectedProfile.git_commit_binding ? (
                <p>
                  Commit author: {selectedProfile.git_commit_binding.commit_name} &lt;
                  {selectedProfile.git_commit_binding.commit_email}&gt;
                </p>
              ) : (
                <p>Commit author not bound for this profile.</p>
              )}
            </div>
            <code>{selectedProfile.rho_home}</code>
          </section>
        ) : null}

        <section className="onboarding-panel">
          <div className="section-heading">
            <div>
              <h2>Onboarding</h2>
              <p>{onboarding?.rho_home || "Detecting local Rho home"}</p>
            </div>
            <button
              type="button"
              onClick={() => void refreshProfilesAndOnboarding()}
              disabled={isLoadingOnboarding}
            >
              {isLoadingOnboarding ? "Detecting" : "Detect Accounts"}
            </button>
          </div>

          {onboardingError ? <p className="error">{onboardingError}</p> : null}

          {onboarding?.gh_accounts.length ? (
            <div className="onboarding-summary">
              <div>
                <strong>Detected GitHub accounts</strong>
                <span>
                  {onboarding.gh_accounts.map((account) => account.login).join(", ")}
                </span>
              </div>
              <button
                type="button"
                onClick={() => void createMissingDetectedProfiles()}
                disabled={Boolean(isCreatingProfile)}
              >
                {isCreatingProfile ? `Creating ${isCreatingProfile}` : "Create Missing Profiles"}
              </button>
            </div>
          ) : null}

          <div className="detected-accounts">
            {onboarding?.gh_accounts.map((account) => (
              <article
                key={`${account.host}-${account.login}`}
                className="account-card"
                data-state={account.has_rho_profile && account.has_local_private_keys ? "pass" : "warn"}
              >
                <div className="account-main">
                  <div>
                    <h2>{account.login}</h2>
                    <p>{account.matching_identity}</p>
                  </div>
                  <span>{account.active ? "active gh" : "available"}</span>
                </div>
                <div className="project-meta">
                  <span>{account.host}</span>
                  <span>{account.git_protocol || "git"}</span>
                  <span>{account.has_rho_profile ? "rho profile" : "needs rho profile"}</span>
                  <span>{account.has_local_private_keys ? "private keys" : "needs keys"}</span>
                  <span>{account.git_commit_binding ? "commit bound" : "commit unbound"}</span>
                  <span>{account.proof_verified ? "verified" : "proof pending"}</span>
                </div>
                {account.git_commit_binding ? (
                  <p>
                    Commit author: {account.git_commit_binding.commit_name} &lt;
                    {account.git_commit_binding.commit_email}&gt; via gh{" "}
                    {account.git_commit_binding.github_login}
                  </p>
                ) : account.has_rho_profile ? (
                  <p>Commit author is not bound; rho commit will use the active gh account fallback.</p>
                ) : null}
                {account.proof_url ? <p>{account.proof_url}</p> : null}
                {account.signing_key_path ? <code>{account.signing_key_path}</code> : null}
                {account.encryption_key_path ? <code>{account.encryption_key_path}</code> : null}
                <div className="project-card-actions">
                  <button
                    type="button"
                    onClick={() => {
                      const profile = profileForHandle(account.login);
                      setSelectedIdentity(profile?.identity || account.matching_identity);
                    }}
                    disabled={!account.has_rho_profile}
                  >
                    Use Profile
                  </button>
                  <button
                    type="button"
                    onClick={() => void openProfileWindowForHandle(account.login)}
                    disabled={!account.has_rho_profile}
                  >
                    New Window
                  </button>
                  <button
                    type="button"
                    onClick={() => void createProfileForHandle(account.login)}
                    disabled={isCreatingProfile === account.login}
                  >
                    {account.has_rho_profile ? "Reuse Profile" : "Create Profile"}
                  </button>
                  <button
                    type="button"
                    onClick={() => void switchGhHandle(account.login)}
                    disabled={isSwitchingGh}
                  >
                    Switch gh
                  </button>
                  <button
                    type="button"
                    onClick={() => void bindCommitAuthorForHandle(account.login)}
                    disabled={!account.has_rho_profile || isBindingCommitAuthor === account.login}
                  >
                    {isBindingCommitAuthor === account.login
                      ? "Binding"
                      : account.git_commit_binding
                        ? "Rebind Author"
                        : "Bind Author"}
                  </button>
                  <button
                    type="button"
                    onClick={() => void verifyProfileForHandle(account.login)}
                    disabled={!account.has_rho_profile || isVerifyingProfile === account.login}
                  >
                    {isVerifyingProfile === account.login ? "Verifying" : "Verify"}
                  </button>
                  <button
                    type="button"
                    onClick={() => void showProfileForHandle(account.login)}
                    disabled={!account.has_rho_profile}
                  >
                    Show
                  </button>
                </div>
              </article>
            ))}
            {onboarding && onboarding.gh_accounts.length === 0 ? (
              <div className="empty-state">
                <h2>No GitHub CLI accounts detected</h2>
                <p>Use the manual profile field if this machine has a GitHub identity that is not registered with gh.</p>
              </div>
            ) : null}
          </div>

          <div className="manual-profile">
            <label>
              <span>GitHub handle</span>
              <input
                value={manualHandle}
                onChange={(event) => setManualHandle(event.target.value)}
                placeholder="madhavajay-test"
              />
            </label>
            <button
              type="button"
              onClick={() => void createProfileForHandle(manualHandle)}
              disabled={Boolean(isCreatingProfile)}
            >
              Create Manual Profile
            </button>
          </div>
        </section>

        <section className="checks" aria-label="Profile readiness checks">
          {checks.map((check) => (
            <article key={check.id} data-state={check.status}>
              <div>
                <h2>{check.label}</h2>
                <p>{check.detail || "No detail returned"}</p>
              </div>
              <span>{check.status}</span>
            </article>
          ))}
        </section>

        {actionResult ? <pre className="action-result">{actionResult}</pre> : null}

        <section className="projects-panel">
          <div className="section-heading">
            <div>
              <h2>Projects</h2>
              <p>Repos tracked for this profile window.</p>
            </div>
            <button type="button" onClick={() => void loadProjects()} disabled={isLoadingProjects}>
              {isLoadingProjects ? "Refreshing" : "Refresh"}
            </button>
          </div>

          <div className="project-actions">
            <label>
              <span>Local repo path</span>
              <input
                value={localProjectPath}
                onChange={(event) => setLocalProjectPath(event.target.value)}
                placeholder="~/dev/rho-project"
              />
            </label>
            <button
              type="button"
              onClick={() => void addLocalProject()}
              disabled={isAddingProject}
            >
              {isAddingProject ? "Adding" : "Add Repo"}
            </button>
          </div>

          <div className="project-actions">
            <label>
              <span>GitHub repo URL</span>
              <input
                value={cloneUrl}
                onChange={(event) => setCloneUrl(event.target.value)}
                placeholder="https://github.com/org/repo"
              />
            </label>
            <label>
              <span>Destination</span>
              <input
                value={cloneDestination}
                onChange={(event) => setCloneDestination(event.target.value)}
                placeholder="Default: ~/.rho/projects/repo"
              />
            </label>
            <button
              type="button"
              onClick={() => void cloneProject()}
              disabled={isCloningProject}
            >
              {isCloningProject ? "Cloning" : "Clone"}
            </button>
          </div>

          <section className="setup-repo-panel">
            <div className="section-heading">
              <div>
                <h2>Setup Rho Repo</h2>
                <p>{selectedIdentity || "Select an owner profile before setup."}</p>
              </div>
            </div>
            <div className="setup-repo-grid">
              <label>
                <span>Folder</span>
                <input
                  value={setupRepoPath}
                  onChange={(event) => setSetupRepoPath(event.target.value)}
                  placeholder="~/dev/rho-project"
                />
              </label>
              <label>
                <span>Repo id</span>
                <input
                  value={setupRepoId}
                  onChange={(event) => setSetupRepoId(event.target.value)}
                  placeholder="owner/repo or rho://repo/..."
                />
              </label>
              <label>
                <span>Origin remote</span>
                <input
                  value={setupRemoteUrl}
                  onChange={(event) => setSetupRemoteUrl(event.target.value)}
                  placeholder="git@github.com:owner/repo.git"
                />
              </label>
            </div>
            <div className="setup-repo-controls">
              <label>
                <input
                  type="checkbox"
                  checked={setupProtectOwnerInbox}
                  onChange={(event) => setSetupProtectOwnerInbox(event.target.checked)}
                />
                <span>Protect owner inbox</span>
              </label>
              <button
                type="button"
                onClick={() => void setupRhoRepo()}
                disabled={isSettingUpRhoRepo || !selectedIdentity}
              >
                {isSettingUpRhoRepo ? "Setting Up" : "Setup Rho Repo"}
              </button>
            </div>
          </section>

          {projectsError ? <p className="error">{projectsError}</p> : null}

          {projects.length === 0 ? (
            <div className="empty-state">
              <h2>No projects yet</h2>
              <p>Add a local git repo, clone a GitHub repo, or set up a new Rho repo from here.</p>
            </div>
          ) : (
            <div className="project-grid">
              {projects.map((project) => (
                <article
                  key={project.id}
                  className="project-card"
                  data-state={project.warning ? "warn" : project.dirty ? "dirty" : "pass"}
                >
                  <div className="project-card-main">
                    <div>
                      <h2>{project.name}</h2>
                      <p>{project.rho_project_id || project.path}</p>
                    </div>
                    <span>{project.role}</span>
                  </div>
                  <div className="project-meta">
                    <span>{project.is_rho ? "rho repo" : "not rho"}</span>
                    <span>{project.current_branch || "no branch"}</span>
                    <span>{project.status_summary}</span>
                    {project.upstream ? <span>{project.upstream}</span> : null}
                  </div>
                  {project.owner ? <p>Owner: {project.owner}</p> : null}
                  {project.remote_url ? <p>{project.remote_url}</p> : null}
                  {project.warning ? <p className="project-warning">{project.warning}</p> : null}
                  <div className="project-card-actions">
                    <button
                      type="button"
                      onClick={() => void openProjectFolder(project.path)}
                      disabled={!project.exists}
                    >
                      Open Folder
                    </button>
                    <button
                      type="button"
                      onClick={() => void selectProject(project.path)}
                      disabled={!project.exists || isLoadingRepoDetail}
                    >
                      {selectedProjectPath === project.path ? "Refresh Repo" : "Open Repo"}
                    </button>
                    <button
                      type="button"
                      onClick={() => void selectProject(project.path)}
                      disabled={!project.exists || isLoadingRepoDetail}
                    >
                      Messages
                    </button>
                  </div>
                </article>
              ))}
            </div>
          )}
        </section>

        {repoDetailError ? <p className="error">{repoDetailError}</p> : null}

        {isLoadingRepoDetail ? (
          <section className="repo-detail-panel">
            <div className="section-heading">
              <div>
                <h2>Loading Repository</h2>
                <p>{selectedProjectPath}</p>
              </div>
            </div>
          </section>
        ) : null}

        {repoDetail ? (
          <section className="repo-detail-panel">
            <div className="section-heading">
              <div>
                <h2>{repoDetail.project.name}</h2>
                <p>{repoDetail.project.rho_project_id || repoDetail.project.path}</p>
              </div>
              <div className="detail-actions">
                <button
                  type="button"
                  onClick={() => void selectProject(repoDetail.project.path)}
                  disabled={isLoadingRepoDetail}
                >
                  Refresh Detail
                </button>
                <button
                  type="button"
                  onClick={() => void openProjectFolder(repoDetail.project.path)}
                >
                  Open Folder
                </button>
              </div>
            </div>

            <div className="detail-summary">
              <span>{repoDetail.project.current_branch || "no branch"}</span>
              <span>{repoDetail.project.status_summary}</span>
              <span>{repoDetail.members.length} member(s)</span>
              <span>{repoDetail.messages.length} message file(s)</span>
              <span>{repoDetail.pending_actions.length} pending action(s)</span>
            </div>

            <section className="repo-actions-panel">
              <div className="section-heading">
                <div>
                  <h2>Branches</h2>
                  <p>{repoDetail.project.upstream || repoDetail.project.remote_url || "No upstream configured."}</p>
                </div>
              </div>
              <div className="repo-action-buttons">
                <button
                  type="button"
                  onClick={() => void runGitAction("fetch")}
                  disabled={Boolean(isRunningGitAction)}
                >
                  Fetch
                </button>
                <button
                  type="button"
                  onClick={() => void runGitAction("pull")}
                  disabled={Boolean(isRunningGitAction) || repoDetail.project.dirty}
                >
                  Pull
                </button>
                <button
                  type="button"
                  onClick={() => void runGitAction("push")}
                  disabled={Boolean(isRunningGitAction) || !selectedIdentity}
                >
                  Push
                </button>
                <button
                  type="button"
                  onClick={() => void runGitAction("push_set_upstream")}
                  disabled={Boolean(isRunningGitAction) || !selectedIdentity}
                >
                  Push Upstream
                </button>
              </div>
              <div className="repo-action-form">
                <label>
                  <span>Branch</span>
                  <input
                    value={branchName}
                    onChange={(event) => setBranchName(event.target.value)}
                    placeholder={repoDetail.project.current_branch || "feature-branch"}
                  />
                </label>
                <button
                  type="button"
                  onClick={() => void runGitAction("switch")}
                  disabled={Boolean(isRunningGitAction) || !branchName.trim() || repoDetail.project.dirty}
                >
                  Switch
                </button>
                <button
                  type="button"
                  onClick={() => void runGitAction("create_branch")}
                  disabled={Boolean(isRunningGitAction) || !branchName.trim()}
                >
                  New Branch
                </button>
              </div>
            </section>

            <section className="repo-actions-panel">
              <div className="section-heading">
                <div>
                  <h2>Repo Actions</h2>
                  <p>{selectedIdentity || "Select a profile before running profile-scoped actions."}</p>
                </div>
              </div>
              <div className="repo-action-buttons">
                <button
                  type="button"
                  onClick={() => void runRepoAction("repo_status")}
                  disabled={Boolean(isRunningRepoAction)}
                >
                  Status
                </button>
                <button
                  type="button"
                  onClick={() => void runRepoAction("repo_doctor")}
                  disabled={Boolean(isRunningRepoAction)}
                >
                  Doctor
                </button>
                <button
                  type="button"
                  onClick={() => void runRepoAction("repo_doctor_flow")}
                  disabled={Boolean(isRunningRepoAction)}
                >
                  Flow Doctor
                </button>
                <button
                  type="button"
                  onClick={() => void runRepoAction("import_users")}
                  disabled={Boolean(isRunningRepoAction)}
                >
                  Import Users
                </button>
                <button
                  type="button"
                  onClick={() => void runRepoAction("join")}
                  disabled={Boolean(isRunningRepoAction) || !selectedIdentity}
                >
                  Request Join
                </button>
              </div>
              <div className="repo-action-form">
                <label>
                  <span>GitHub handle</span>
                  <input
                    value={repoActionTargetHandle}
                    onChange={(event) => setRepoActionTargetHandle(event.target.value)}
                    placeholder="madhavajay-test"
                  />
                </label>
                <button
                  type="button"
                  onClick={() => void runRepoAction("admit")}
                  disabled={Boolean(isRunningRepoAction) || !repoActionTargetHandle.trim()}
                >
                  Admit User
                </button>
                <button
                  type="button"
                  onClick={() => void runRepoAction("add_user")}
                  disabled={Boolean(isRunningRepoAction) || !repoActionTargetHandle.trim()}
                >
                  Add User
                </button>
              </div>
              <div className="repo-action-form">
                <label>
                  <span>Request id</span>
                  <input
                    value={repoActionRequestId}
                    onChange={(event) => setRepoActionRequestId(event.target.value)}
                    placeholder="req-..."
                  />
                </label>
                <button
                  type="button"
                  onClick={() => void runRepoAction("review_request")}
                  disabled={Boolean(isRunningRepoAction) || !repoActionRequestId.trim()}
                >
                  Review Request
                </button>
              </div>
            </section>

            <section className="repo-actions-panel">
              <div className="section-heading">
                <div>
                  <h2>Commit Changes</h2>
                  <p>{repoDetail.project.status_summary}</p>
                </div>
              </div>
              <div className="repo-action-form">
                <label>
                  <span>Commit message</span>
                  <input
                    value={commitMessage}
                    onChange={(event) => setCommitMessage(event.target.value)}
                    placeholder="Describe this Rho change"
                  />
                </label>
                <button
                  type="button"
                  onClick={() => void commitRepoChanges()}
                  disabled={
                    isCommittingRepo ||
                    !selectedIdentity ||
                    !commitMessage.trim() ||
                    !repoDetail.project.dirty
                  }
                >
                  {isCommittingRepo ? "Committing" : "Stage All And Commit"}
                </button>
              </div>
            </section>

            <section className="repo-actions-panel">
              <div className="section-heading">
                <div>
                  <h2>Send Message</h2>
                  <p>{selectedIdentity || "Select a profile before sending a project message."}</p>
                </div>
              </div>
              <div className="repo-action-form">
                <label>
                  <span>Recipient</span>
                  <input
                    value={messageRecipient}
                    onChange={(event) => setMessageRecipient(event.target.value)}
                    placeholder={repoDetail.project.owner || "github/handle"}
                  />
                </label>
                <label>
                  <span>Thread</span>
                  <input
                    value={messageThread}
                    onChange={(event) => setMessageThread(event.target.value)}
                    placeholder="Optional"
                  />
                </label>
              </div>
              <div className="repo-action-form">
                <label>
                  <span>Message</span>
                  <textarea
                    value={messageText}
                    onChange={(event) => setMessageText(event.target.value)}
                    placeholder="Write a project message"
                    rows={4}
                  />
                </label>
                <button
                  type="button"
                  onClick={() => void sendProjectMessage()}
                  disabled={
                    isSendingMessage ||
                    !selectedIdentity ||
                    !messageRecipient.trim() ||
                    !messageText.trim()
                  }
                >
                  {isSendingMessage ? "Sending" : "Write And Sign"}
                </button>
              </div>
            </section>

            <div className="detail-grid">
              <section className="detail-block">
                <h2>Files</h2>
                <div className="file-list">
                  {repoDetail.files.slice(0, 80).map((file) => (
                    <div key={file.path} className="file-row">
                      <span>{file.status || file.kind}</span>
                      <code>{shortPath(file.path)}</code>
                    </div>
                  ))}
                  {repoDetail.files.length === 0 ? <p>No files found.</p> : null}
                </div>
              </section>

              <section className="detail-block">
                <h2>Members</h2>
                <div className="compact-list">
                  {repoDetail.members.map((member) => (
                    <div key={member.identity}>
                      <strong>{member.handle}</strong>
                      <span>{member.role}</span>
                      <code>{member.identity}</code>
                    </div>
                  ))}
                  {repoDetail.members.length === 0 ? <p>No membership file found.</p> : null}
                </div>
              </section>

              <section className="detail-block">
                <h2>Participants</h2>
                <div className="compact-list">
                  {repoDetail.participants.map((participant) => (
                    <div key={participant.handle}>
                      <strong>{participant.display_name || participant.handle}</strong>
                      <span>{participant.handle}</span>
                      {participant.signing_fingerprint ? (
                        <code>sign {participant.signing_fingerprint}</code>
                      ) : null}
                      {participant.encryption_fingerprint ? (
                        <code>enc {participant.encryption_fingerprint}</code>
                      ) : null}
                    </div>
                  ))}
                  {repoDetail.participants.length === 0 ? <p>No participant bundles found.</p> : null}
                </div>
              </section>

              <section className="detail-block">
                <h2>Policy</h2>
                <div className="compact-list">
                  {repoDetail.policy_files.map((file) => (
                    <div key={file.path}>
                      <strong>{file.title}</strong>
                      <span>{file.summary}</span>
                      <code>{file.path}</code>
                    </div>
                  ))}
                  {repoDetail.policy_files.length === 0 ? <p>No policy files found.</p> : null}
                </div>
              </section>

              <section className="detail-block">
                <h2>Tools</h2>
                <div className="compact-list">
                  {repoDetail.tools.map((tool) => (
                    <div key={tool.path}>
                      <strong>{tool.id}</strong>
                      <span>{tool.action_type || "action"}</span>
                      <span>{tool.approval_required ? "approval required" : "no approval"}</span>
                      <code>{tool.path}</code>
                    </div>
                  ))}
                  {repoDetail.tools.length === 0 ? <p>No tools found.</p> : null}
                </div>
              </section>

              <section className="detail-block">
                <h2>Messages</h2>
                <div className="compact-list">
                  {repoDetail.messages.map((message) => (
                    <div key={message.path}>
                      <strong>{message.kind}</strong>
                      <span>{message.summary}</span>
                      <span>
                        {message.inbox} / {message.thread}
                      </span>
                      <code>{message.path}</code>
                    </div>
                  ))}
                  {repoDetail.messages.length === 0 ? <p>No inbox messages for this profile.</p> : null}
                </div>
              </section>
            </div>

            <section className="detail-block pending-block">
              <h2>Pending Actions</h2>
              <div className="compact-list">
                {repoDetail.pending_actions.map((action) => (
                  <div key={action.id}>
                    <strong>{action.kind}</strong>
                    <span>{action.summary}</span>
                    {action.actor ? <span>{action.actor}</span> : null}
                    <code>{action.path}</code>
                    {action.kind === "request" ? (
                      <button
                        type="button"
                        onClick={() => {
                          const requestId = requestIdFromPath(action.path);
                          setRepoActionRequestId(requestId);
                          if (requestId) {
                            void runRepoAction("review_request", { requestId });
                          }
                        }}
                        disabled={Boolean(isRunningRepoAction)}
                      >
                        Review
                      </button>
                    ) : null}
                  </div>
                ))}
                {repoDetail.pending_actions.length === 0 ? <p>No pending actions detected.</p> : null}
              </div>
            </section>
          </section>
        ) : null}

        {status === "error" ? <p className="error">{error}</p> : null}
      </section>
    </main>
  );
}
