"use client";

import { createContext, useContext, useMemo, useCallback } from "react";
import { SessionProvider, useSession } from "next-auth/react";
import type { AuthContextValue, User, Role, CompanyId } from "./types";

const ROLE_HIERARCHY: Record<Role, number> = {
  admin: 4,
  manager: 3,
  user: 2,
  viewer: 1,
  guest: 0,
};

const AuthContext = createContext<AuthContextValue | null>(null);

// Stub user for development fallback
const STUB_USER: User = {
  id: "dev-user",
  name: "Utilizator Intern",
  email: "dev@architools.local",
  role: "admin",
  company: "beletage",
};

interface AuthProviderProps {
  children: React.ReactNode;
}

function AuthProviderInner({ children }: AuthProviderProps) {
  const { data: session, status } = useSession();

  // Derive user from session (all hooks must be called unconditionally)
  const user: User | null = session?.user
    ? {
        id: (session.user as any).id || "unknown",
        name: session.user.name || "Unknown User",
        email: session.user.email || "",
        role: ((session.user as any).role as Role) || "user",
        company: ((session.user as any).company as CompanyId) || "group",
      }
    : process.env.NODE_ENV === "development"
      ? STUB_USER
      : null;

  const hasRole = useCallback(
    (requiredRole: Role) => {
      if (!user) return false;
      return ROLE_HIERARCHY[user.role] >= ROLE_HIERARCHY[requiredRole];
    },
    [user],
  );

  const canAccessModule = useCallback(
    (_moduleId: string) => {
      // Future: check module-level permissions
      return !!user;
    },
    [user],
  );

  const value: AuthContextValue = useMemo(
    () => ({
      user,
      role: user?.role || "guest",
      isAuthenticated: !!user,
      hasRole,
      canAccessModule,
    }),
    [user, hasRole, canAccessModule],
  );

  // Show loading spinner while session is being validated (after all hooks)
  if (status === "loading") {
    return (
      <div className="flex h-screen items-center justify-center">
        <div className="h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent" />
      </div>
    );
  }

  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
}

export function AuthProvider({ children }: AuthProviderProps) {
  return (
    <SessionProvider>
      <AuthProviderInner>{children}</AuthProviderInner>
    </SessionProvider>
  );
}

export function useAuth(): AuthContextValue {
  const ctx = useContext(AuthContext);
  if (!ctx) throw new Error("useAuth must be used within AuthProvider");
  return ctx;
}
