"use client";

import { createContext, useContext, useState, useEffect, useCallback, ReactNode } from "react";
import { getToken, setToken as saveToken, clearToken, getUserData, setUserData, clearUserData } from "@/lib/auth";
import { API, authFetch } from "@/lib/api";

export interface AuthUser {
  id: string;
  email: string;
  name: string;
  role: string;
  employeeId?: string | null;
  effectivePermissions: string[];
}

interface AuthContextType {
  user: AuthUser | null;
  loading: boolean;
  login: (email: string, password: string) => Promise<void>;
  logout: () => void;
  hasPermission: (perm: string) => boolean;
  hasAnyPermission: (...perms: string[]) => boolean;
  isSuperAdmin: boolean;
}

const AuthContext = createContext<AuthContextType>({
  user: null,
  loading: true,
  login: async () => {},
  logout: () => {},
  hasPermission: () => false,
  hasAnyPermission: () => false,
  isSuperAdmin: false,
});

export function AuthProvider({ children }: { children: ReactNode }) {
  const [user, setUser] = useState<AuthUser | null>(null);
  const [loading, setLoading] = useState(true);

  const restoreSession = useCallback(async () => {
    const token = getToken();
    if (!token) {
      setLoading(false);
      return;
    }
    const cached = getUserData();
    if (cached) {
      setUser(cached);
      setLoading(false);
    }
    try {
      const res = await authFetch(`${API}/auth/me`);
      if (res.ok) {
        const data = await res.json();
        const u: AuthUser = {
          id: data.id,
          email: data.email,
          name: data.name || "",
          role: data.role,
          employeeId: data.employeeId ?? null,
          effectivePermissions: data.effectivePermissions ?? [],
        };
        setUser(u);
        setUserData(u);
      } else {
        clearToken();
        clearUserData();
        setUser(null);
      }
    } catch {
      // keep cached user if network fails
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    restoreSession();
  }, [restoreSession]);

  const login = async (email: string, password: string) => {
    const res = await fetch(`${API}/auth/login`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ email, password }),
    });
    if (!res.ok) {
      const err = await res.json().catch(() => ({}));
      throw new Error(err.message || "Invalid email or password");
    }
    const data = await res.json();
    saveToken(data.accessToken);
    const u: AuthUser = {
      id: data.user.id,
      email: data.user.email,
      name: data.user.name || data.user.fullName || "",
      role: data.user.role,
      employeeId: data.user.employeeId ?? null,
      effectivePermissions: data.user.effectivePermissions ?? [],
    };
    setUserData(u);
    setUser(u);
  };

  const logout = () => {
    clearToken();
    clearUserData();
    setUser(null);
  };

  const hasPermission = (perm: string) => {
    if (!user) return false;
    return user.effectivePermissions.includes(perm);
  };

  const hasAnyPermission = (...perms: string[]) => {
    if (!user) return false;
    return perms.some((p) => user.effectivePermissions.includes(p));
  };

  const isSuperAdmin = user?.role === "ADMIN" && user?.effectivePermissions.includes("users:manage");

  return (
    <AuthContext.Provider value={{ user, loading, login, logout, hasPermission, hasAnyPermission, isSuperAdmin }}>
      {children}
    </AuthContext.Provider>
  );
}

export function useAuth() {
  return useContext(AuthContext);
}
