'use client';

import React, { useEffect, useState } from 'react';
import { useRouter } from 'next/navigation';
import { useAuthStore } from '../../../stores/auth-store';
import { Role } from '@goodgo/types';
import { Card } from '../components/ui/card';
import { Button } from '../components/ui/button';

/**
 * EN: Auth Guard Props
 * VI: Props cho Auth Guard
 */
interface AuthGuardProps {
  /** EN: Content to render when authenticated / VI: Nội dung để render khi đã xác thực */
  children: React.ReactNode;
  /** EN: Required authentication / VI: Yêu cầu xác thực */
  requireAuth?: boolean;
  /** EN: Required roles for access / VI: Vai trò yêu cầu để truy cập */
  requiredRoles?: Role[];
  /** EN: Redirect path when not authenticated / VI: Đường dẫn redirect khi chưa xác thực */
  redirectTo?: string;
  /** EN: Fallback component while checking auth / VI: Component fallback trong khi kiểm tra auth */
  fallback?: React.ReactNode;
  /** EN: Whether to check on client side only / VI: Có chỉ kiểm tra ở client side không */
  clientOnly?: boolean;
}

/**
 * EN: Auth Guard Component - Protects routes based on authentication and role requirements
 * VI: Auth Guard Component - Bảo vệ routes dựa trên xác thực và yêu cầu vai trò
 *
 * Features:
 * - Client-side authentication checking
 * - Role-based access control
 * - Automatic redirects
 * - Loading states
 * - Custom fallback components
 *
 * @example
 * ```tsx
 * // Require authentication
 * <AuthGuard>
 *   <ProtectedContent />
 * </AuthGuard>
 *
 * // Require specific role
 * <AuthGuard requiredRoles={[Role.ADMIN]}>
 *   <AdminContent />
 * </AuthGuard>
 *
 * // Require multiple roles
 * <AuthGuard requiredRoles={[Role.ADMIN, Role.SUPER_ADMIN]}>
 *   <SuperAdminContent />
 * </AuthGuard>
 * ```
 */
export function AuthGuard({
  children,
  requireAuth = true,
  requiredRoles = [],
  redirectTo,
  fallback,
  clientOnly = true,
}: AuthGuardProps) {
  const router = useRouter();
  const { user, isAuthenticated, isLoading, fetchUser } = useAuthStore();
  const [isChecking, setIsChecking] = useState(true);

  useEffect(() => {
    // If clientOnly is true, skip server-side checks
    if (clientOnly) {
      setIsChecking(false);
      return;
    }

    // Fetch user data if not loaded
    if (!user && !isLoading) {
      fetchUser().finally(() => setIsChecking(false));
    } else {
      setIsChecking(false);
    }
  }, [user, isLoading, fetchUser, clientOnly]);

  // Show loading state
  if (isChecking || isLoading) {
    if (fallback) {
      return <>{fallback}</>;
    }

    return (
      <div className="min-h-screen flex items-center justify-center">
        <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600"></div>
      </div>
    );
  }

  // Check authentication requirement
  if (requireAuth && !isAuthenticated) {
    // Redirect to login or custom path
    const redirectPath = redirectTo || '/auth/login';
    if (typeof window !== 'undefined') {
      router.push(redirectPath);
    }
    return null;
  }

  // Check role requirements
  if (requiredRoles.length > 0 && user) {
    const hasRequiredRole = requiredRoles.includes(user.role);
    if (!hasRequiredRole) {
      // Show access denied
      return (
        <div className="min-h-screen flex items-center justify-center p-4">
          <Card className="p-8 text-center max-w-md">
            <h2 className="text-2xl font-bold text-red-600 mb-4">Access Denied</h2>
            <p className="text-gray-600 mb-6">
              You don't have permission to access this resource.
            </p>
            <div className="flex gap-4 justify-center">
              <Button onClick={() => router.back()}>
                Go Back
              </Button>
              <Button variant="ghost" onClick={() => router.push('/dashboard')}>
                Dashboard
              </Button>
            </div>
          </Card>
        </div>
      );
    }
  }

  // All checks passed, render children
  return <>{children}</>;
}

/**
 * EN: Require Auth HOC - Higher-order component for authentication
 * VI: Require Auth HOC - Higher-order component cho xác thực
 *
 * @example
 * ```tsx
 * const ProtectedPage = requireAuth(MyComponent);
 * const AdminPage = requireAuth(MyComponent, [Role.ADMIN]);
 * ```
 */
export function requireAuth<P extends object>(
  Component: React.ComponentType<P>,
  requiredRoles?: Role[]
) {
  return function AuthenticatedComponent(props: P) {
    return (
      <AuthGuard requiredRoles={requiredRoles}>
        <Component {...props} />
      </AuthGuard>
    );
  };
}

/**
 * EN: Role-based guard components
 * VI: Components guard dựa trên vai trò
 */
export const RequireAdmin: React.FC<{ children: React.ReactNode }> = ({ children }) => (
  <AuthGuard requiredRoles={[Role.ADMIN, Role.SUPER_ADMIN]}>
    {children}
  </AuthGuard>
);

export const RequireSuperAdmin: React.FC<{ children: React.ReactNode }> = ({ children }) => (
  <AuthGuard requiredRoles={[Role.SUPER_ADMIN]}>
    {children}
  </AuthGuard>
);

/**
 * EN: Utility functions for role checking
 * VI: Hàm utility để kiểm tra vai trò
 */
export const hasRole = (userRole: Role | undefined, requiredRoles: Role[]): boolean => {
  if (!userRole) return false;
  return requiredRoles.includes(userRole);
};

export const hasAdminRole = (userRole: Role | undefined): boolean => {
  return hasRole(userRole, [Role.ADMIN, Role.SUPER_ADMIN]);
};

export const hasSuperAdminRole = (userRole: Role | undefined): boolean => {
  return hasRole(userRole, [Role.SUPER_ADMIN]);
};

export const canManageUsers = (userRole: Role | undefined): boolean => {
  return hasRole(userRole, [Role.ADMIN, Role.SUPER_ADMIN]);
};

export const canDeleteUsers = (currentUserRole: Role | undefined, targetUserRole: Role): boolean => {
  if (!currentUserRole) return false;

  // Super admin can delete anyone
  if (currentUserRole === Role.SUPER_ADMIN) return true;

  // Admin can delete users but not other admins or super admins
  if (currentUserRole === Role.ADMIN) {
    return targetUserRole === Role.USER;
  }

  // Users cannot delete anyone
  return false;
};