import { isAdminLike as isAdminLikeRole } from "@/lib/frontend/auth/roles";
import { isValidBranchParam } from "@/lib/frontend/params";

export const OVERVIEW_BRANCH_FALLBACK = "NL01";

export const OVERVIEW_BRANCH_SOURCE = Object.freeze({
	NONE: "none",
	USER: "user",
	ROUTE: "route",
	STORED: "stored",
	FALLBACK: "fallback",
	API_FIRST: "api-first",
});

function normalizeBranch(value) {
	if (typeof value !== "string") return null;
	const trimmed = value.trim();
	return isValidBranchParam(trimmed) ? trimmed : null;
}

function normalizeAvailableBranches(value) {
	if (!Array.isArray(value)) return null;

	const deduped = [];
	for (const item of value) {
		const normalized = normalizeBranch(item);
		if (!normalized) continue;
		if (!deduped.includes(normalized)) deduped.push(normalized);
	}

	return deduped;
}

export function resolveOverviewBranchTarget(input = {}) {
	const role = input?.role ?? null;
	const routeBranch = normalizeBranch(input?.routeBranch);
	const storedBranch = normalizeBranch(input?.storedBranch);
	const ownBranch = normalizeBranch(input?.userBranchId);
	const fallbackBranch =
		normalizeBranch(input?.fallbackBranch) || OVERVIEW_BRANCH_FALLBACK;
	const availableBranches = normalizeAvailableBranches(input?.availableBranches);

	if (role === "branch") {
		return {
			branch: ownBranch,
			source: ownBranch
				? OVERVIEW_BRANCH_SOURCE.USER
				: OVERVIEW_BRANCH_SOURCE.NONE,
			shouldFetchBranches: false,
		};
	}

	if (!isAdminLikeRole(role)) {
		return {
			branch: null,
			source: OVERVIEW_BRANCH_SOURCE.NONE,
			shouldFetchBranches: false,
		};
	}

	const candidates = [
		{ source: OVERVIEW_BRANCH_SOURCE.ROUTE, branch: routeBranch },
		{ source: OVERVIEW_BRANCH_SOURCE.STORED, branch: storedBranch },
		{ source: OVERVIEW_BRANCH_SOURCE.FALLBACK, branch: fallbackBranch },
	];

	if (Array.isArray(availableBranches)) {
		if (availableBranches.length === 0) {
			return {
				branch: null,
				source: OVERVIEW_BRANCH_SOURCE.NONE,
				shouldFetchBranches: false,
			};
		}

		for (const candidate of candidates) {
			if (!candidate.branch) continue;
			if (availableBranches.includes(candidate.branch)) {
				return {
					branch: candidate.branch,
					source: candidate.source,
					shouldFetchBranches: false,
				};
			}
		}

		return {
			branch: availableBranches[0],
			source: OVERVIEW_BRANCH_SOURCE.API_FIRST,
			shouldFetchBranches: false,
		};
	}

	const firstLocal = candidates.find((candidate) => Boolean(candidate.branch));
	if (!firstLocal) {
		return {
			branch: null,
			source: OVERVIEW_BRANCH_SOURCE.NONE,
			shouldFetchBranches: true,
		};
	}

	return {
		branch: firstLocal.branch,
		source: firstLocal.source,
		shouldFetchBranches:
			firstLocal.source === OVERVIEW_BRANCH_SOURCE.FALLBACK,
	};
}
