import { scopeProjectRef, scopeThreadRef } from "@t3tools/client-runtime";
import type { EnvironmentId, ThreadId } from "@t3tools/contracts";
import {
ChevronDownIcon,
CloudIcon,
FolderGit2Icon,
FolderGitIcon,
FolderIcon,
MonitorIcon,
} from "lucide-react";
import { memo, useMemo } from "react";
import { useComposerDraftStore, type DraftId } from "../composerDraftStore";
import { useIsMobile } from "../hooks/useMediaQuery";
import { useStore } from "../store";
import { createProjectSelectorByRef, createThreadSelectorByRef } from "../storeSelectors";
import {
type EnvMode,
type EnvironmentOption,
resolveCurrentWorkspaceLabel,
resolveEnvModeLabel,
resolveEffectiveEnvMode,
resolveLockedWorkspaceLabel,
} from "./BranchToolbar.logic";
import { BranchToolbarBranchSelector } from "./BranchToolbarBranchSelector";
import { BranchToolbarEnvironmentSelector } from "./BranchToolbarEnvironmentSelector";
import { BranchToolbarEnvModeSelector } from "./BranchToolbarEnvModeSelector";
import { Button } from "./ui/button";
import {
Menu,
MenuGroup,
MenuGroupLabel,
MenuPopup,
MenuRadioGroup,
MenuRadioItem,
MenuSeparator,
MenuTrigger,
} from "./ui/menu";
import { Separator } from "./ui/separator";
interface BranchToolbarProps {
environmentId: EnvironmentId;
threadId: ThreadId;
draftId?: DraftId;
onEnvModeChange: (mode: EnvMode) => void;
effectiveEnvModeOverride?: EnvMode;
activeThreadBranchOverride?: string | null;
onActiveThreadBranchOverrideChange?: (branch: string | null) => void;
envLocked: boolean;
onCheckoutPullRequestRequest?: (reference: string) => void;
onComposerFocusRequest?: () => void;
availableEnvironments?: readonly EnvironmentOption[];
onEnvironmentChange?: (environmentId: EnvironmentId) => void;
}
interface MobileRunContextSelectorProps {
envLocked: boolean;
envModeLocked: boolean;
environmentId: EnvironmentId;
availableEnvironments: readonly EnvironmentOption[] | undefined;
showEnvironmentPicker: boolean;
onEnvironmentChange: ((environmentId: EnvironmentId) => void) | undefined;
effectiveEnvMode: EnvMode;
activeWorktreePath: string | null;
onEnvModeChange: (mode: EnvMode) => void;
}
const MobileRunContextSelector = memo(function MobileRunContextSelector({
envLocked,
envModeLocked,
environmentId,
availableEnvironments,
showEnvironmentPicker,
onEnvironmentChange,
effectiveEnvMode,
activeWorktreePath,
onEnvModeChange,
}: MobileRunContextSelectorProps) {
const activeEnvironment = useMemo(
() => availableEnvironments?.find((env) => env.environmentId === environmentId) ?? null,
[availableEnvironments, environmentId],
);
const WorkspaceIcon =
effectiveEnvMode === "worktree"
? FolderGit2Icon
: activeWorktreePath
? FolderGitIcon
: FolderIcon;
const workspaceLabel = envModeLocked
? resolveLockedWorkspaceLabel(activeWorktreePath)
: effectiveEnvMode === "worktree"
? resolveEnvModeLabel("worktree")
: resolveCurrentWorkspaceLabel(activeWorktreePath);
const isLocked = envLocked || envModeLocked;
const EnvironmentIcon = activeEnvironment?.isPrimary ? MonitorIcon : CloudIcon;
const icon = showEnvironmentPicker ? (
// Button's base styles apply `-mx-0.5` to descendant SVGs, which eats 4px
// out of whatever gap we set. mx-0! cancels that so gap-0.5 reads as 2px.