import { SEARCH_SCOPE } from "@/lib/frontend/search/urlState";
import { ApiClientError } from "@/lib/frontend/apiClient";
import { getSearchDateRangeValidation } from "@/lib/frontend/search/searchDateValidation";
import { isAdminLike as isAdminLikeRole } from "@/lib/frontend/auth/roles";

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

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

function buildValidationError(code, message, details) {
	return new ApiClientError({
		status: 400,
		code,
		message,
		details,
	});
}

/**
 * Build the apiClient.search(...) input from URL state + current user context.
 *
 * Return shape:
 * - input: object for apiClient.search(...) or null (no search yet / not ready)
 * - error: ApiClientError or null (local validation / fast-fail)
 *
 * UX policy for MULTI without branches:
 * - Treat it as "not ready" (input=null, error=null) instead of an error.
 *
 * @param {{
 *   urlState: {
 *     q: string|null,
 *     scope: "single"|"multi"|"all",
 *     branch: string|null,
 *     branches: string[],
 *     from: string|null,
 *     to: string|null
 *   },
 *   routeBranch: string,
 *   user: { role: string, branchId: string|null }|null,
 *   cursor?: string|null,
 *   limit?: number
 * }} args
 * @returns {{ input: any|null, error: any|null }}
 */
export function buildSearchApiInput({
	urlState,
	routeBranch,
	user,
	cursor = null,
	limit = 100,
}) {
	const q = isNonEmptyString(urlState?.q) ? urlState.q.trim() : null;

	// UI policy (RHL-024): q is required to trigger a search.
	if (!q) return { input: null, error: null };

	// --- Date range validation (RHL-025) ------------------------------------
	const from = toTrimmedOrNull(urlState?.from);
	const to = toTrimmedOrNull(urlState?.to);

	const dateValidation = getSearchDateRangeValidation(from, to);
	if (dateValidation) {
		return {
			input: null,
			error: buildValidationError(
				dateValidation.code,
				dateValidation.message,
				dateValidation.details,
			),
		};
	}

	// --- Build input ---------------------------------------------------------
	const input = { q, limit };

	if (from) input.from = from;
	if (to) input.to = to;

	if (isNonEmptyString(cursor)) input.cursor = cursor.trim();

	const role = user?.role;

	// Branch users: always restricted to the current route branch.
	if (role === "branch") {
		input.branch = routeBranch;
		return { input, error: null };
	}

	// Admin-like: respect scope rules from URL state.
	if (isAdminLikeRole(role)) {
		if (urlState.scope === SEARCH_SCOPE.ALL) {
			input.scope = "all";
			return { input, error: null };
		}

		if (urlState.scope === SEARCH_SCOPE.MULTI) {
			const branches = Array.isArray(urlState.branches)
				? urlState.branches
				: [];

			// UX: missing branches is not an error, it's "not ready".
			if (branches.length === 0) {
				return { input: null, error: null };
			}

			input.scope = "multi";
			input.branches = branches;
			return { input, error: null };
		}

		// SINGLE
		input.branch = routeBranch;
		return { input, error: null };
	}

	// Unknown role: fail-safe to single-branch using the route context.
	input.branch = routeBranch;
	return { input, error: null };
}
