'use client';

/**
 * Global Priority-Based Loading System
 * Enterprise FinTech Platform
 *
 * Implements P0-P3 progressive loading:
 * - P0: Instant shell, auth, layout, critical controls
 * - P1: High priority cards, tables, important data
 * - P2: Background charts, analytics, logs
 * - P3: Idle/predictive heavy components
 */

import { useState, useEffect, useMemo, useCallback } from 'react';

export type Priority = 0 | 1 | 2 | 3;

export interface PriorityLoaderOptions {
  priority: Priority;
  fallback?: React.ReactNode;
  onLoad?: () => void;
  suspenseId?: string;
}

const PRIORITY_SCHEDULES: Record<Priority, 'immediate' | 'high' | 'normal' | 'idle'> = {
  0: 'immediate',
  1: 'high',
  2: 'normal',
  3: 'idle',
};

let globalLoaderId = 0;

export function createPriorityLoader<T>(options: PriorityLoaderOptions) {
  const { priority, fallback, onLoad, suspenseId } = options;
  const schedule = PRIORITY_SCHEDULES[priority];
  const id = suspenseId || `priority-${++globalLoaderId}`;

  return {
    id,
    priority,
    schedule,
    fallback: fallback || getDefaultFallback(priority),
    onLoad,
  };
}

export function getDefaultFallback(priority: Priority): React.ReactNode {
  switch (priority) {
    case 0:
      return null;
    case 1:
      return (
        <div className="animate-pulse rounded-lg bg-white/5 p-4">
          <div className="h-4 w-3/4 rounded bg-white/10" />
          <div className="mt-2 h-3 w-1/2 rounded bg-white/10" />
        </div>
      );
    case 2:
      return (
        <div className="animate-pulse rounded-lg bg-white/5 p-6">
          <div className="h-32 w-full rounded bg-white/10" />
        </div>
      );
    case 3:
      return (
        <div className="animate-pulse rounded-lg bg-white/5 p-4">
          <div className="h-3 w-1/3 rounded bg-white/10" />
        </div>
      );
  }
}

export function usePriorityLoad(
  loader: ReturnType<typeof createPriorityLoader>,
  execute: () => Promise<void> | void,
  deps: readonly unknown[] = []
) {
  const [loaded, setLoaded] = useState(false);
  const [error, setError] = useState<Error | null>(null);

  useEffect(() => {
    let cancelled = false;

    const run = async () => {
      try {
        if (loader.schedule === 'idle') {
          if (typeof requestIdleCallback !== 'undefined') {
            await new Promise<void>((resolve) => {
              requestIdleCallback(() => resolve(), { timeout: 2000 });
            });
          } else {
            await new Promise((resolve) => setTimeout(resolve, 300));
          }
        } else if (loader.schedule === 'normal') {
          await new Promise((resolve) => setTimeout(resolve, 50));
        }
        await execute();
        if (!cancelled) {
          setLoaded(true);
          loader.onLoad?.();
        }
      } catch (err) {
        if (!cancelled) {
          setError(err instanceof Error ? err : new Error(String(err)));
        }
      }
    };

    run();

    return () => {
      cancelled = true;
    };
  }, deps);

  return { loaded, error };
}

export function usePrefetchOnHover(
  prefetchFn: () => void,
  delay = 100
) {
  useEffect(() => {
    let timer: ReturnType<typeof setTimeout> | undefined;
    return () => { if (timer) clearTimeout(timer); };
  }, []);
}

export function usePredictivePrefetch(
  role: string | null,
  currentPath: string
) {
  const prefetchPaths = useMemo(() => {
    if (!role) return [];
    const map: Record<string, Record<string, string[]>> = {
      USER: {
        '/dashboard': ['/wallet', '/orders', '/transactions', '/referrals'],
        '/wallet': ['/orders', '/transactions'],
        '/orders': ['/trading', '/transactions'],
        '/trading': ['/orders', '/wallet'],
      },
      ADMIN: {
        '/admin/dashboard': ['/admin/users', '/admin/orders', '/admin/support'],
        '/admin/users': ['/admin/orders', '/admin/wallet'],
        '/admin/orders': ['/admin/support', '/admin/reports'],
      },
      SUPER_ADMIN: {
        '/super-admin/dashboard': ['/super-admin/users', '/super-admin/admins', '/super-admin/feature-flags'],
        '/super-admin/users': ['/super-admin/admins', '/super-admin/logs'],
        '/super-admin/admins': ['/super-admin/super-admins', '/super-admin/permissions'],
        '/super-admin/feature-flags': ['/super-admin/settings', '/super-admin/maintenance'],
      },
    };
    return map[role]?.[currentPath] || [];
  }, [role, currentPath]);

  useEffect(() => {
    const timer = setTimeout(() => {
      prefetchPaths.forEach((path) => {
        if (typeof window !== 'undefined') {
          const link = document.createElement('link');
          link.rel = 'prefetch';
          link.href = path;
          link.as = 'document';
          document.head.appendChild(link);
        }
      });
    }, 2000);

    return () => clearTimeout(timer);
  }, [prefetchPaths]);
}
