"use client";

import { createContext, useContext, useEffect, useState, ReactNode } from "react";
import { auth, type Instance, type Role, type SessionUser } from "@/lib/api";

export type { Instance, Role, SessionUser };

interface AuthContextType {
    user: SessionUser | null;
    instance: Instance | null;
    /** True for owner and admin the roles the /api/settings and /api/instance routes require. */
    isAdmin: boolean;
}

const AuthContext = createContext<AuthContextType>({ user: null, instance: null, isAdmin: false });

export function useAuth() {
    return useContext(AuthContext);
}

/**
 * Wraps the authenticated app shell only (see app/(app)/layout.tsx). /login and
 * /setup live outside the group, so no pathname guard is needed here.
 */
export function AuthProvider({ children }: { children: ReactNode }) {
    const [user, setUser] = useState<SessionUser | null>(null);
    const [instance, setOrg] = useState<Instance | null>(null);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState<string | null>(null);

    useEffect(() => {
        let cancelled = false;

        (async () => {
            try {
                const status = await auth.bootstrapStatus();
                if (status.needs_setup) {
                    window.location.href = "/setup";
                    return;
                }

                const me = await auth.me();
                if (cancelled) return;
                setUser(me.user);
                setOrg(me.instance);
                setLoading(false);
            } catch (err) {
                if (cancelled) return;
                const status = (err as { status?: number }).status;
                if (status === 401) {
                    window.location.href = "/login";
                    return;
                }

                setError((err as Error).message || "Unable to load your session.");
                setLoading(false);
            }
        })();

        return () => {
            cancelled = true;
        };
    }, []);

    if (loading) {
        return (
            <div className="flex h-screen items-center justify-center bg-background">
                <div className="h-8 w-8 animate-spin rounded-full border-2 border-border border-t-accent" />
            </div>
        );
    }

    if (error || !user) {
        return (
            <div className="flex h-screen items-center justify-center bg-background p-4">
                <div className="w-full max-w-md rounded-xl border border-border bg-surface p-6 text-center">
                    <h1 className="text-base font-semibold text-text-primary">Can&apos;t load your session</h1>
                    <p className="mt-2 text-sm text-text-secondary">{error ?? "Unable to load your session."}</p>
                    <div className="mt-5 flex justify-center gap-2">
                        <button onClick={() => window.location.reload()} className="rounded-lg bg-accent px-3 py-2 text-sm font-medium text-white">
                            Retry
                        </button>
                        <a href="/login" className="rounded-lg border border-border px-3 py-2 text-sm font-medium text-text-secondary">
                            Sign in
                        </a>
                    </div>
                </div>
            </div>
        );
    }

    const isAdmin = user.role === "owner" || user.role === "admin";

    return <AuthContext.Provider value={{ user, instance, isAdmin }}>{children}</AuthContext.Provider>;
}
