'use client';

import {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useState,
} from 'react';
import { usePathname, useRouter } from 'next/navigation';
import Cookies from 'js-cookie';
import { ACCESS_TOKEN_KEY } from '@/lib/api-client';
import {
  AuthUser,
  logout as logoutRequest,
  me as meRequest,
  roleHome,
  UserRole,
} from '@/lib/auth';

interface AuthContextValue {
  user: AuthUser | null;
  loading: boolean;
  logout: () => Promise<void>;
}

const AuthContext = createContext<AuthContextValue>({
  user: null,
  loading: true,
  logout: async () => undefined,
});

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

/** Protege a área autenticada e redireciona visitantes para o login. */
export function AuthProvider({ children }: { children: React.ReactNode }) {
  const router = useRouter();
  const pathname = usePathname();
  const [user, setUser] = useState<AuthUser | null>(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    let active = true;

    async function resolve() {
      const token = Cookies.get(ACCESS_TOKEN_KEY);
      if (!token) {
        router.replace(`/login?next=${encodeURIComponent(pathname)}`);
        return;
      }
      try {
        const current = await meRequest();
        if (active) setUser(current);
      } catch {
        Cookies.remove(ACCESS_TOKEN_KEY);
        router.replace('/login');
      } finally {
        if (active) setLoading(false);
      }
    }

    resolve();
    return () => {
      active = false;
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const logout = useCallback(async () => {
    await logoutRequest();
    setUser(null);
    router.replace('/login');
  }, [router]);

  if (loading) {
    return (
      <div className="d-flex justify-content-center align-items-center vh-100">
        <div className="text-center">
          <span className="spinner-border text-primary" role="status" />
          <p className="text-muted mt-3 mb-0">Carregando…</p>
        </div>
      </div>
    );
  }

  if (!user) return null;

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

/** Restringe a página a determinados papéis, redirecionando o restante. */
export function RequireRole({
  roles,
  children,
}: {
  roles: UserRole[];
  children: React.ReactNode;
}) {
  const { user } = useAuth();
  const router = useRouter();

  useEffect(() => {
    if (user && !roles.includes(user.role)) {
      router.replace(roleHome[user.role]);
    }
  }, [user, roles, router]);

  if (!user || !roles.includes(user.role)) return null;
  return <>{children}</>;
}
