"use client";
import React from "react";
import { useRouter, useSearchParams } from "next/navigation";
import { RefreshCw } from "lucide-react";
import { useAuth } from "@/components/auth/authContext";
import { buildLoginUrl, LOGIN_REASONS } from "@/lib/frontend/authRedirect";
import { searchPath } from "@/lib/frontend/routes";
import { isValidBranchParam } from "@/lib/frontend/params";
import {
parseSearchUrlState,
serializeSearchUrlState,
SEARCH_SCOPE,
} from "@/lib/frontend/search/urlState";
import { normalizeSearchUrlStateForUser } from "@/lib/frontend/search/normalizeState";
import { mapSearchError } from "@/lib/frontend/search/errorMapping";
import { useSearchQuery } from "@/lib/frontend/search/useSearchQuery";
import {
useSearchBranches,
BRANCH_LIST_STATE,
} from "@/lib/frontend/search/useSearchBranches";
import {
buildSearchHref,
buildSearchKey,
getScopeLabel,
needsMultiBranchSelectionHint,
buildNextStateForScopeChange,
buildNextStateForToggleBranch,
buildNextStateForClearAllBranches,
buildHrefForSingleBranchSwitch,
} from "@/lib/frontend/search/pageHelpers";
import ExplorerPageShell from "@/components/explorer/ExplorerPageShell";
import ExplorerSectionCard from "@/components/explorer/ExplorerSectionCard";
import ForbiddenView from "@/components/system/ForbiddenView";
import { Button } from "@/components/ui/button";
import SearchForm from "@/components/search/SearchForm";
import SearchResults from "@/components/search/SearchResults";
export default function SearchPage({ branch: routeBranch }) {
const router = useRouter();
const searchParams = useSearchParams();
const { status: authStatus, user } = useAuth();
const isAuthenticated = authStatus === "authenticated" && user;
const isAdminDev =
isAuthenticated && (user.role === "admin" || user.role === "dev");
const parsedUrlState = React.useMemo(() => {
return parseSearchUrlState(searchParams, { routeBranch });
}, [searchParams, routeBranch]);
const urlState = React.useMemo(() => {
return normalizeSearchUrlStateForUser(parsedUrlState, {
routeBranch,
user,
});
}, [parsedUrlState, routeBranch, user]);
const searchKey = React.useMemo(() => {
return buildSearchKey({ routeBranch, urlState });
}, [routeBranch, urlState]);
const [qDraft, setQDraft] = React.useState(urlState.q || "");
React.useEffect(() => {
setQDraft(urlState.q || "");
}, [urlState.q]);
const branchesQuery = useSearchBranches({ enabled: isAdminDev });
const query = useSearchQuery({
searchKey,
urlState,
routeBranch,
user,
limit: urlState.limit,
});
const mappedError = React.useMemo(
() => mapSearchError(query.error),
[query.error]
);
const mappedLoadMoreError = React.useMemo(
() => mapSearchError(query.loadMoreError),
[query.loadMoreError]
);
React.useEffect(() => {
if (mappedError?.kind !== "unauthenticated") return;
const next =
typeof window !== "undefined"
? `${window.location.pathname}${window.location.search}`
: searchPath(routeBranch);
window.location.replace(
buildLoginUrl({ reason: LOGIN_REASONS.EXPIRED, next })
);
}, [mappedError?.kind, routeBranch]);
const pushStateToUrl = React.useCallback(
(nextState) => {
router.push(buildSearchHref({ routeBranch, state: nextState }));
},
[router, routeBranch]
);
const replaceStateToUrl = React.useCallback(
(nextState) => {
router.replace(buildSearchHref({ routeBranch, state: nextState }));
},
[router, routeBranch]
);
const handleSubmit = React.useCallback(() => {
pushStateToUrl({ ...urlState, q: qDraft });
}, [pushStateToUrl, urlState, qDraft]);
const handleScopeChange = React.useCallback(
(nextScope) => {
if (!isAdminDev) return;
replaceStateToUrl(buildNextStateForScopeChange({ urlState, nextScope }));
},
[isAdminDev, urlState, replaceStateToUrl]
);
const handleToggleBranch = React.useCallback(
(branchId) => {
if (!isAdminDev) return;
replaceStateToUrl(buildNextStateForToggleBranch({ urlState, branchId }));
},
[isAdminDev, urlState, replaceStateToUrl]
);
const handleClearAllBranches = React.useCallback(() => {
if (!isAdminDev) return;
replaceStateToUrl(buildNextStateForClearAllBranches({ urlState }));
}, [isAdminDev, urlState, replaceStateToUrl]);
const handleLimitChange = React.useCallback(
(nextLimit) => {
replaceStateToUrl({ ...urlState, limit: nextLimit });
},
[urlState, replaceStateToUrl]
);
const handleSingleBranchChange = React.useCallback(
(nextBranch) => {
if (!isAdminDev) return;
if (!isValidBranchParam(nextBranch)) return;
const href = buildHrefForSingleBranchSwitch({ nextBranch, urlState });
if (!href) return;
router.push(href);
},
[isAdminDev, urlState, router]
);
if (mappedError?.kind === "forbidden") {
return ;
}
const actions = (
);
const resultsHeaderRight = urlState.q ? (
{urlState.q}
) : null;
const scopeLabel = getScopeLabel({ routeBranch, urlState });
const resultsDescription = urlState.q
? `Suchbereich: ${scopeLabel}`
: "Geben Sie einen Suchbegriff ein, um zu starten.";
const needsBranchSelection = needsMultiBranchSelectionHint({
isAdminDev,
urlState,
});
return (
);
}