import { useEffect, useRef } from 'react';
import { Navigate } from 'react-router-dom';
import { useAuthStore } from '../store/auth';

interface Props {
  children: React.ReactNode;
  requireAdmin?: boolean;
  requireTeamAdmin?: boolean;
  requireTeamMember?: boolean;
}

export function ProtectedRoute({ children, requireAdmin, requireTeamAdmin, requireTeamMember }: Props) {
  const isAuthenticated = useAuthStore((s) => s.isAuthenticated);
  const isLoading = useAuthStore((s) => s.isLoading);
  const user = useAuthStore((s) => s.user);
  const mustChangePassword = useAuthStore((s) => s.mustChangePassword);
  const fetchUserInfo = useAuthStore((s) => s.fetchUserInfo);
  const retrying = useRef(false);

  // If we have a token but user info hasn't loaded, keep retrying
  useEffect(() => {
    if (!isAuthenticated || user || isLoading) return;
    if (retrying.current) return;
    retrying.current = true;

    let cancelled = false;
    const retry = async () => {
      let delay = 500;
      while (!cancelled) {
        try {
          await fetchUserInfo();
          break; // success
        } catch {
          await new Promise(r => setTimeout(r, delay));
          delay = Math.min(delay * 2, 3000);
        }
      }
      retrying.current = false;
    };
    retry();

    return () => { cancelled = true; };
  }, [isAuthenticated, user, isLoading, fetchUserInfo]);

  if (isLoading || (isAuthenticated && !user)) {
    return (
      <div style={{
        width: '100%',
        height: '100%',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        background: 'var(--color-bg-page)',
        color: 'var(--color-text-secondary)',
      }}>
        加载中...
      </div>
    );
  }

  if (!isAuthenticated) {
    return <Navigate to="/login" replace />;
  }

  if (mustChangePassword) {
    return <Navigate to="/" replace />;
  }

  if (requireAdmin && user?.role !== 'super_admin') {
    return <Navigate to="/app" replace />;
  }

  if (requireTeamAdmin && user?.role !== 'team_admin') {
    return <Navigate to="/app" replace />;
  }

  // requireTeamMember: must have a team (team_admin or member)
  if (requireTeamMember && user?.role === 'super_admin') {
    return <Navigate to="/admin/dashboard" replace />;
  }

  return <>{children}</>;
}
