"use client";

import { createContext, useContext, useEffect, useState } from "react";
import { onAuthStateChanged, signOut as firebaseSignOut, User } from "firebase/auth";
import { auth } from "@/lib/firebase";
import type { UserRole } from "@/lib/types";

interface AuthContextType {
  user: User | null;
  loading: boolean;
  role: UserRole | null;
  isAdmin: boolean;
  isOperator: boolean;
  ownedNodeIds: string[];
  signOut: () => Promise<void>;
}

const AuthContext = createContext<AuthContextType>({
  user: null,
  loading: true,
  role: null,
  isAdmin: false,
  isOperator: false,
  ownedNodeIds: [],
  signOut: async () => {},
});

export function AuthProvider({ children }: { children: React.ReactNode }) {
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState(true);
  const [role, setRole] = useState<UserRole | null>(null);
  const [ownedNodeIds, setOwnedNodeIds] = useState<string[]>([]);

  useEffect(() => {
    return onAuthStateChanged(auth, async (u) => {
      setUser(u);
      setLoading(false);

      if (u) {
        document.cookie = "drb_session=1; path=/; SameSite=Strict";
        const result = await u.getIdTokenResult(true);
        const claims = result.claims;

        // Derive role: prefer granular "role" claim, fall back to legacy "admin" boolean
        let effectiveRole: UserRole = "viewer";
        if (claims.role === "admin" || claims.admin) {
          effectiveRole = "admin";
        } else if (claims.role === "operator") {
          effectiveRole = "operator";
        } else if (claims.role === "viewer") {
          effectiveRole = "viewer";
        }

        setRole(effectiveRole);
        setOwnedNodeIds((claims.owned_node_ids as string[]) ?? []);
      } else {
        document.cookie = "drb_session=; path=/; max-age=0";
        setRole(null);
        setOwnedNodeIds([]);
      }
    });
  }, []);

  async function signOut() {
    await firebaseSignOut(auth);
    document.cookie = "drb_session=; path=/; max-age=0";
  }

  const isAdmin = role === "admin";
  const isOperator = role === "operator";

  return (
    <AuthContext.Provider value={{ user, loading, role, isAdmin, isOperator, ownedNodeIds, signOut }}>
      {children}
    </AuthContext.Provider>
  );
}

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