"use client";

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

export type { Org, Role, SessionUser };

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

const AuthContext = createContext<AuthContextType>({ user: null, org: 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 [org, setOrg] = useState<Org | null>(null);
  const [loading, setLoading] = useState(true);

  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.org);
        setLoading(false);
      } catch (err) {
        if (cancelled) return;
        const status = (err as { status?: number }).status;
        if (status === 401) {
          window.location.href = "/login";
          return;
        }
        // Backend unreachable or unexpected failure — don't trap the user on a spinner.
        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>
    );
  }

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

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