"use client";

import React from "react";
import { Loader2 } from "lucide-react";

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

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",
});

function BranchValidationLoading() {
	return (
		<div className="flex items-center gap-3 text-sm text-muted-foreground">
			<Loader2 className="h-4 w-4 animate-spin" />
			<span>Niederlassung wird geprüft…</span>
		</div>
	);
}

export default function BranchGuard({ branch, children }) {
	const { status, user } = useAuth();

	const isAuthenticated = status === "authenticated" && user;
	const needsExistenceCheck =
		isAuthenticated && (user.role === "admin" || user.role === "dev");

	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;
		};

		// IMPORTANT:
		// - depend only on user identity + needsExistenceCheck
		// - do NOT depend on branchList.status (would cancel itself when setting LOADING)
	}, [needsExistenceCheck, user?.userId]);

	if (!isAuthenticated) return children;

	if (needsExistenceCheck && branchList.status === BRANCH_LIST_STATE.LOADING) {
		return <BranchValidationLoading />;
	}

	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;
}
