"use client";
import { useCallback, useEffect, useMemo, useState } from "react";
import { IconInfoCircle, IconLoader2 } from "@tabler/icons-react";
import { Button } from "@kandev/ui/button";
import { Tooltip, TooltipContent, TooltipTrigger } from "@kandev/ui/tooltip";
import { useAppStore } from "@/components/state-provider";
import { AgentSelector } from "@/components/task-create-dialog-selectors";
import { useAgentProfileOptions } from "@/components/task-create-dialog-options";
import { WorkspaceRepoChips } from "@/components/task-create-dialog-workspace-repo-chips";
import { useRepositoriesState } from "@/components/task-create-dialog-repositories-state";
import { useRepositories } from "@/hooks/domains/workspace/use-repositories";
import { useFeature } from "@/hooks/domains/features/use-feature";
import type { QuickChatRepositoryInput } from "@/lib/api/domains/workspace-api";
import type { AgentProfileOption } from "@/lib/state/slices";
import { isSelectableAgentProfile } from "@/lib/state/slices/settings/types";
import type { Repository } from "@/lib/types/http";
import type { QuickChatSessionKind } from "@/lib/state/slices/ui/types";
import { ConfigurationChatToggle } from "./configuration-chat-toggle";
import { useTranslation } from "react-i18next";
import type { TFunction } from "i18next";
type QuickChatSetupProps = {
workspaceId: string;
canCreateConfigurationChat: boolean;
pendingAgentId: string | null;
onStart: (agentId: string, repositories: QuickChatRepositoryInput[]) => void;
onCancel: () => void;
onKindChange: (kind: QuickChatSessionKind) => void;
};
function useQuickChatAgentSelection(
agentProfiles: AgentProfileOption[],
defaultAgentId: string,
dynamicRoutingEnabled: boolean,
) {
const selectableDefault =
defaultAgentId &&
agentProfiles.some(
(profile) =>
profile.id === defaultAgentId && isSelectableAgentProfile(profile, dynamicRoutingEnabled),
)
? defaultAgentId
: "";
const [agentProfileId, setAgentProfileId] = useState(selectableDefault);
const hasSelectedEnabledProfile = agentProfiles.some(
(profile) =>
profile.id === agentProfileId && isSelectableAgentProfile(profile, dynamicRoutingEnabled),
);
useEffect(() => {
if (!hasSelectedEnabledProfile) setAgentProfileId(selectableDefault);
}, [hasSelectedEnabledProfile, selectableDefault]);
return { agentProfileId, setAgentProfileId, hasSelectedEnabledProfile };
}
function repositoryAddState(
t: TFunction,
isLoading: boolean,
repositoryCount: number,
rowCount: number,
) {
if (isLoading) return { canAddMore: false, addHint: t("chat:loadingRepositories") };
if (repositoryCount === 0) {
return { canAddMore: false, addHint: t("chat:noRepositoriesAvailableInWorkspace") };
}
if (rowCount >= repositoryCount) {
return { canAddMore: false, addHint: t("chat:allWorkspaceRepositoriesAdded") };
}
return { canAddMore: true, addHint: undefined };
}
function QuickChatIntroduction() {
const { t } = useTranslation();
return (
{t("chat:quickChatIntro")}
{t("chat:quickChatIntroSecondary")}
);
}
function QuickChatSetupHeader() {
const { t } = useTranslation();
return (
{t("common:commandQuickChat")}
);
}
function AgentField({
profiles,
value,
disabled,
onChange,
}: {
profiles: AgentProfileOption[];
value: string;
disabled: boolean;
onChange: (value: string) => void;
}) {
const { t } = useTranslation();
const options = useAgentProfileOptions(profiles, "quick_chat");
return (
{t("chat:agentProfile")}
{t("chat:agentProfileHelp")}
0 ? t("chat:selectAgent") : t("chat:noAgentsAvailable")}
triggerClassName="h-11 w-full justify-between border border-input bg-background px-3 shadow-xs hover:bg-accent/50 data-[state=open]:border-ring data-[state=open]:ring-[2px] data-[state=open]:ring-ring/35"
popoverPortal
/>
);
}
type RepositoryFieldProps = {
workspaceId: string;
repositories: Repository[];
rows: ReturnType["repositories"];
canAddMore: boolean;
addHint?: string;
onAdd: () => void;
onRemove: (key: string) => void;
onRepositoryChange: (key: string, value: string) => void;
onBranchChange: (key: string, value: string) => void;
};
function RepositoryField(props: RepositoryFieldProps) {
const { t } = useTranslation();
return (
{t("chat:repositories")}{" "}
{t("chat:optional")}
{t("chat:repositoriesHelp")}
);
}
function RepositoryContextHelp() {
const { t } = useTranslation();
return (
{t("chat:repositoryContextHelp")}
);
}
function SetupFooter({
isStarting,
startDisabled,
onCancel,
onStart,
}: {
isStarting: boolean;
startDisabled: boolean;
onCancel: () => void;
onStart: () => void;
}) {
const { t } = useTranslation();
return (
);
}
export function QuickChatSetup({
workspaceId,
canCreateConfigurationChat,
pendingAgentId,
onStart,
onCancel,
onKindChange,
}: QuickChatSetupProps) {
const { t } = useTranslation();
const dynamicRoutingEnabled = useFeature("dynamicAgentRouting");
const agentProfiles = useAppStore((state) => state.agentProfiles.items ?? []);
const defaultAgentId = useAppStore(
(state) =>
state.workspaces.items.find((workspace) => workspace.id === workspaceId)
?.default_agent_profile_id ?? "",
);
const { agentProfileId, setAgentProfileId, hasSelectedEnabledProfile } =
useQuickChatAgentSelection(agentProfiles, defaultAgentId, dynamicRoutingEnabled);
const { repositories, isLoading } = useRepositories(workspaceId, true);
const repoState = useRepositoriesState();
const isStarting = pendingAgentId !== null;
const hasIncompleteRow = repoState.repositories.some((row) => !row.repositoryId || !row.branch);
const { canAddMore, addHint } = repositoryAddState(
t,
isLoading,
repositories.length,
repoState.repositories.length,
);
const handleRepositoryChange = useCallback(
(key: string, repositoryId: string) => {
repoState.updateRepository(key, { repositoryId, localPath: undefined, branch: "" });
},
[repoState],
);
const handleBranchChange = useCallback(
(key: string, branch: string) => repoState.updateRepository(key, { branch }),
[repoState],
);
const selectedRepositories = useMemo(
() =>
repoState.repositories
.filter((row) => row.repositoryId && row.branch)
.map((row) => ({ repository_id: row.repositoryId as string, base_branch: row.branch })),
[repoState.repositories],
);
const startDisabled = !hasSelectedEnabledProfile || hasIncompleteRow || isStarting;
return (
{canCreateConfigurationChat && (
checked && onKindChange("config")}
/>
)}
{
if (hasSelectedEnabledProfile) onStart(agentProfileId, selectedRepositories);
}}
/>
);
}