import {
	SEARCH_SCOPE,
	DEFAULT_SEARCH_LIMIT,
	SEARCH_LIMITS,
} from "@/lib/frontend/search/urlState";
import { isAdminLike as isAdminLikeRole } from "@/lib/frontend/auth/roles";

function isNonEmptyString(value) {
	return typeof value === "string" && value.trim().length > 0;
}

function normalizeBranch(value) {
	return isNonEmptyString(value) ? value.trim() : null;
}

function normalizeLimit(value) {
	const n = Number(value);
	if (!Number.isInteger(n)) return DEFAULT_SEARCH_LIMIT;
	return SEARCH_LIMITS.includes(n) ? n : DEFAULT_SEARCH_LIMIT;
}

/**
 * Normalize URL-derived search state for the current user and route context.
 *
 * Why this exists:
 * - The URL is shareable and can contain stale/foreign params.
 * - The UI route already defines the "branch context" (/:branch/search).
 * - Branch users must never get cross-branch scope semantics in the UI.
 *
 * Policy:
 * - branch users: force SINGLE on the current route branch
 * - admin-like: SINGLE always uses the current route branch
 * - MULTI/ALL: do not carry a single-branch value (branch=null)
 *
 * @param {{
 *   q: string|null,
 *   scope: "single"|"multi"|"all",
 *   branch: string|null,
 *   branches: string[],
 *   limit: number,
 *   from: string|null,
 *   to: string|null
 * }|null|undefined} state
 * @param {{ routeBranch: string, user: { role: string, branchId: string|null }|null }} options
 * @returns {{
 *   q: string|null,
 *   scope: "single"|"multi"|"all",
 *   branch: string|null,
 *   branches: string[],
 *   limit: number,
 *   from: string|null,
 *   to: string|null
 * }}
 */
export function normalizeSearchUrlStateForUser(
	state,
	{ routeBranch, user } = {},
) {
	const route = normalizeBranch(routeBranch);

	const base = {
		q: isNonEmptyString(state?.q) ? state.q.trim() : null,
		scope: state?.scope || SEARCH_SCOPE.SINGLE,
		branch: normalizeBranch(state?.branch),
		branches: Array.isArray(state?.branches) ? state.branches : [],
		limit: normalizeLimit(state?.limit),
		from: isNonEmptyString(state?.from) ? state.from.trim() : null,
		to: isNonEmptyString(state?.to) ? state.to.trim() : null,
	};

	// Defensive: if no routeBranch is available (should not happen in this app),
	// fall back to the parsed branch value.
	if (!route) {
		return {
			...base,
			branch: base.scope === SEARCH_SCOPE.SINGLE ? base.branch : null,
			branches: base.scope === SEARCH_SCOPE.MULTI ? base.branches : [],
		};
	}

	const role = user?.role;

	// Branch users: force SINGLE on the current route branch.
	if (role === "branch") {
		return {
			...base,
			scope: SEARCH_SCOPE.SINGLE,
			branch: route,
			branches: [],
		};
	}

	// Admin-like: SINGLE always uses the current route branch (route context wins over URL param).
	if (isAdminLikeRole(role)) {
		if (base.scope === SEARCH_SCOPE.SINGLE) {
			return { ...base, branch: route, branches: [] };
		}

		if (base.scope === SEARCH_SCOPE.MULTI) {
			return { ...base, branch: null };
		}

		// ALL
		return { ...base, scope: SEARCH_SCOPE.ALL, branch: null, branches: [] };
	}

	// Unknown roles: fail-safe to route-branch SINGLE.
	return { ...base, scope: SEARCH_SCOPE.SINGLE, branch: route, branches: [] };
}
