1import { threadPullRequestLinkMode } from "@t3tools/client-runtime/thread-pull-request-compatibility";
2import type { PullRequestDetail } from "@t3tools/contracts";
3import { parseChangeRequestUrl } from "@t3tools/shared/changeRequestUrl";
4import { useMemo } from "react";
5import { useEnvironmentServerConfig, useNavigationThreadShells } from "../../state/entities";
6import { pullRequestStackAtom } from "../../state/pull-requests";
7import { useEnvironmentQuery } from "../../state/query";
8import { savedPullRequestStack } from "./pullRequestStack";
9import { pullRequestTarget, type PullRequestParams } from "./usePullRequestDiff";
10
11export function usePullRequestStack(params: PullRequestParams, pr: PullRequestDetail | null) {
12 const target = pullRequestTarget(params);
13 const config = useEnvironmentServerConfig(target.environmentId);
14 const threads = useNavigationThreadShells();
15 const supported =
16 threadPullRequestLinkMode(config?.environment.capabilities) === "multiple" &&
17 pr?.capabilities.stacks === true;
18 const reference = useMemo(
19 () => ({
20 ...pullRequestTarget(params).input,
21 host: params.host ?? (pr ? parseChangeRequestUrl(pr.url)?.host : undefined),
22 }),
23 [params, pr],
24 );
25 const saved = useMemo(
26 () =>
27 savedPullRequestStack(
28 threads
29 .filter((thread) => thread.environmentId === target.environmentId)
30 .flatMap((thread) => thread.pullRequests ?? []),
31 reference,
32 ),
33 [threads, target.environmentId, reference],
34 );
35 const query = useEnvironmentQuery(
36 supported ? pullRequestStackAtom({ ...target, input: reference }) : null,
37 );
38 const stack = query.isSuccess ? query.data : (query.data ?? saved);
39 return {
40 ...query,
41 stack,
42 isFresh: supported && query.isSuccess && !query.isPending,
43 supportsStackActions:
44 supported &&
45 pr?.capabilities.stackActions === true &&
46 config?.environment.capabilities.pullRequestStackActions === true,
47 };
48}
49
50export type PullRequestStackState = ReturnType<typeof usePullRequestStack>;