"use client";

import { useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
import { useRouter, usePathname } from "next/navigation";
import AppShell from "@/app/components/AppShell";
import { MedoraScope } from "@/components/design-system/medora-scope";
import { PageError } from "@/components/medora/errors";
import { screenOf, useMenuPermissions } from "@/lib/permissions";
import { Toaster } from "@/components/ui/toast";
import { TooltipProvider } from "@/components/ui/tooltip";
import { SettingsProvider, useSettings } from "@/lib/SettingsContext";
import { UsersApi } from "@/lib/api";
import { isDesktopApp, useIsDesktop } from "@/lib/desktop";
import { useSessionExpiredRedirect } from "@/lib/useSessionExpired";
import { Home, Lock, LogOut } from "lucide-react";
import { Loading } from "@/components/medora/loading";

/* Session timeout — logs out after N minutes of inactivity */
function SessionGuard({ children }: { children: React.ReactNode }) {
    const router = useRouter();
    const { s } = useSettings();
    const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);

    useEffect(() => {
        const minutes = parseInt(s("security_session_timeout", "0"), 10);
        if (!minutes) return;
        const ms = minutes * 60 * 1000;
        const reset = () => {
            if (timerRef.current) clearTimeout(timerRef.current);
            timerRef.current = setTimeout(() => {
                localStorage.removeItem("token");
                localStorage.removeItem("user");
                router.push("/login");
            }, ms);
        };
        reset();
        const events = ["mousemove", "keydown", "mousedown", "touchstart"];
        events.forEach(e => window.addEventListener(e, reset));
        return () => {
            if (timerRef.current) clearTimeout(timerRef.current);
            events.forEach(e => window.removeEventListener(e, reset));
        };
    }, [s, router]);

    return <>{children}</>;
}

const noSubscribe = () => () => {};

/**
 * ST-09: a page is seen only with Read on one of its permission pages. Pages fetch data the API also serves to
 * other screens (the till reads settings, the desktop caches users), so the page itself must not render for a
 * role without Read. Waits for permissions rather than flashing the page; an older API (no permissions) passes.
 */
function RouteGate({ children }: { children: React.ReactNode }) {
    const pathname = usePathname();
    const { settled, mayOpen } = useMenuPermissions();
    const screen = screenOf(pathname);
    if (!screen) return <>{children}</>;
    if (!settled) return <Loading what="this page" columns={5} rows={6} />;
    if (mayOpen(screen)) return <>{children}</>;
    const home = screen !== "/dashboard" && mayOpen("/dashboard") ? undefined : mayOpen("/pos") && screen !== "/pos" ? { label: "Go to the till", href: "/pos" } : { label: "Sign out", href: "/login" };
    return <PageError kind="no-access" action={home} />;
}

function InnerLayout({ children }: { children: React.ReactNode }) {
    const router = useRouter();
    const pathname = usePathname();
    const { s } = useSettings();
    const isDesktop = useIsDesktop();
    const [currentTime, setCurrentTime] = useState("");
    // The signed-in user, read from the browser on every render (null on the server, so hydration matches)
    const userJson = useSyncExternalStore(noSubscribe, () => localStorage.getItem("user"), () => null);
    const currentUser = useMemo(() => {
        try {
            return JSON.parse(userJson || "null") as { name?: string; username?: string; role?: string } | null;
        } catch {
            return null;
        }
    }, [userJson]);

    useEffect(() => {
        if (typeof window !== "undefined") {
            if (isDesktopApp()) {
                // Cache users for passcode login
                UsersApi.getAll()
                    .then((users) => {
                        if (users && users.length > 0) {
                            localStorage.setItem("pharmapos_cached_users", JSON.stringify(users));
                        }
                    })
                    .catch(() => {});
            }
        }
    }, [pathname]);

    useEffect(() => {
        if (typeof window !== "undefined") {
            const storeName = s("store_name", "PrismPOS");
            if (storeName) {
                localStorage.setItem("pharmapos_pharmacy_name", storeName);
            }
        }
    }, [s]);

    useEffect(() => {
        const updateClock = () => {
            const now = new Date();
            setCurrentTime(
                now.toLocaleDateString("en-GB", { day: "2-digit", month: "short", year: "numeric" }) +
                " " +
                now.toLocaleTimeString("en-GB", { hour: "2-digit", minute: "2-digit" })
            );
        };
        updateClock();
        const timer = setInterval(updateClock, 1000);
        return () => clearInterval(timer);
    }, []);

    const handleLogout = () => {
        localStorage.removeItem("token");
        localStorage.removeItem("user");
        router.push("/login");
    };

    if (isDesktop) {
        const storeName = s("store_name", "PrismPOS");
        return (
            <div className="flex flex-col h-screen w-screen overflow-hidden bg-slate-50 select-none">
                {/* Desktop Top Header Bar */}
                <header className="bg-white text-gray-800 h-14 px-4 flex items-center justify-between shrink-0 shadow-sm border-b border-gray-200">
                    <div className="flex items-center gap-4">
                        {pathname !== "/dashboard" ? (
                            <button
                                onClick={() => router.push("/dashboard")}
                                className="flex items-center gap-1.5 px-3 py-1.5 bg-red-600 hover:bg-red-700 text-white rounded-lg text-xs font-bold transition shadow-sm"
                            >
                                <Home className="w-3.5 h-3.5" />
                                <span>Main Menu</span>
                            </button>
                        ) : (
                            <div className="w-2.5 h-2.5 rounded-full bg-red-500 animate-pulse" />
                        )}
                        <span className="text-sm font-bold text-gray-900 tracking-wide">{storeName}</span>
                    </div>

                    <div className="flex items-center gap-6">
                        {currentUser && (
                            <div className="text-right hidden sm:block">
                                <span className="text-xs font-bold text-gray-800 block leading-tight">{currentUser.name || currentUser.username}</span>
                                <span className="text-[10px] text-red-600 font-semibold block leading-none">{currentUser.role}</span>
                            </div>
                        )}

                        <div className="text-right border-l border-gray-200 pl-4 hidden md:block">
                            <span className="text-xs font-mono text-gray-600 font-bold block">{currentTime}</span>
                        </div>

                        <div className="flex items-center gap-2 pl-2 border-l border-gray-200">
                            <button
                                onClick={handleLogout}
                                title="Lock Session"
                                className="p-2 bg-slate-50 hover:bg-slate-100 text-slate-600 hover:text-slate-900 rounded-lg transition border border-slate-200/50"
                            >
                                <Lock className="w-4 h-4" />
                            </button>
                            <button
                                onClick={handleLogout}
                                title="Logout"
                                className="p-2 bg-red-50 hover:bg-red-100 text-red-600 hover:text-red-700 rounded-lg transition border border-red-100"
                            >
                                <LogOut className="w-4 h-4" />
                            </button>
                        </div>
                    </div>
                </header>

                {/* Main Client Area */}
                {/* Converted pages need the Medora scope and providers here too (the web gets them from AppShell) */}
                <main className="medora flex-1 overflow-auto p-4 relative">
                    <MedoraScope />
                    <TooltipProvider>
                        <Toaster>{children}</Toaster>
                    </TooltipProvider>
                </main>
            </div>
        );
    }

    // PRD 1.6: the Medora app shell (design system), with menus from the role's permissions (1.1)
    return (
        <AppShell>
            <RouteGate>{children}</RouteGate>
        </AppShell>
    );
}

/** The signed-in app's client side: sign-in check, settings, session timeout, and the web or desktop chrome. */
export function DashboardClientLayout({ children }: { children: React.ReactNode }) {
    useSessionExpiredRedirect();
    const router = useRouter();

    useEffect(() => {
        if (typeof window !== "undefined") {
            const token = localStorage.getItem("token");
            const userStr = localStorage.getItem("user");
            if (!token || !userStr) { router.push("/login"); return; }
            try {
                const user = JSON.parse(userStr);
                if (user.role === "SuperAdmin") router.push("/admin/pharmacies");
            } catch { router.push("/login"); }
        }
    }, [router]);

    return (
        <SettingsProvider>
            <SessionGuard>
                <InnerLayout>{children}</InnerLayout>
            </SessionGuard>
        </SettingsProvider>
    );
}
