"use client";

import React from "react";

import { useAuth } from "@/components/auth/authContext";
import { getBranches } from "@/lib/frontend/apiClient";
import {
	decideBranchUi,
	BRANCH_UI_DECISION,
} from "@/lib/frontend/rbac/branchUiDecision";
import { isAdminLike as isAdminLikeRole } from "@/lib/frontend/auth/roles";

import ForbiddenView from "@/components/system/ForbiddenView";
import NotFoundView from "@/components/system/NotFoundView";

const BRANCH_LIST_STATE = Object.freeze({
	IDLE: "idle",
	LOADING: "loading",
	READY: "ready",
	ERROR: "error",
});

/**
 * BranchGuard
 *
 * UX improvement:
 * - We do NOT block rendering while admin-like branch list is loading.
 * - Existence validation is applied once the list is READY.
 * - While LOADING/ERROR we fail open to avoid "solo spinner" screens.
 *
 * Security note:
 * - Backend RBAC remains authoritative.
 * - Branch users are enforced immediately (no existence check needed).
 */
export default function BranchGuard({ branch, children }) {
	const { status, user } = useAuth();

	const isAuthenticated = status === "authenticated" && user;
	const needsExistenceCheck = isAuthenticated && isAdminLikeRole(user.role);

	const [branchList, setBranchList] = React.useState({
		status: BRANCH_LIST_STATE.IDLE,
		branches: null,
	});

	React.useEffect(() => {
		if (!needsExistenceCheck) return;

		let cancelled = false;

		setBranchList({ status: BRANCH_LIST_STATE.LOADING, branches: null });

		(async () => {
			try {
				const res = await getBranches();
				if (cancelled) return;

				const branches = Array.isArray(res?.branches) ? res.branches : [];
				setBranchList({ status: BRANCH_LIST_STATE.READY, branches });
			} catch (err) {
				if (cancelled) return;

				// Fail open: do not block navigation if validation fails.
				console.error("[BranchGuard] getBranches failed:", err);
				setBranchList({ status: BRANCH_LIST_STATE.ERROR, branches: null });
			}
		})();

		return () => {
			cancelled = true;
		};
	}, [needsExistenceCheck, user?.userId]);

	if (!isAuthenticated) return children;

	// Only apply existence validation when the list is READY.
	const allowedBranches =
		branchList.status === BRANCH_LIST_STATE.READY ? branchList.branches : null;

	const decision = decideBranchUi({
		user,
		branch,
		allowedBranches,
	});

	if (decision === BRANCH_UI_DECISION.FORBIDDEN) {
		return <ForbiddenView attemptedBranch={branch} />;
	}

	if (decision === BRANCH_UI_DECISION.NOT_FOUND) {
		return <NotFoundView />;
	}

	return children;
}
