"use client";

import { Component, ReactNode, useState, useEffect, Suspense } from "react";
import { Alert, AlertDescription, AlertTitle } from "@/components/common/alert";
import { Button } from "@/components/common/button";
import { AlertCircle, RefreshCw } from "lucide-react";
import { Skeleton } from "@/components/common/skeleton";
import { Card, CardContent, CardHeader } from "@/components/common/card";
import { useRouter } from "next/navigation";
import { sidebarConfig } from "@/config/sidebar";

// Error Boundary Component
interface ErrorBoundaryState {
  hasError: boolean;
  error: Error | null;
}

interface ErrorBoundaryProps {
  children: ReactNode;
  fallback?: ReactNode;
  componentName?: string;
}

class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
  private retryCount = 0;
  private maxRetries = 2;

  constructor(props: ErrorBoundaryProps) {
    super(props);
    this.state = { hasError: false, error: null };
  }

  static getDerivedStateFromError(error: Error): ErrorBoundaryState {
    return { hasError: true, error };
  }

  componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
    console.error(`Error loading ${this.props.componentName || 'component'}:`, error, errorInfo);
  }

  handleRetry = () => {
    if (this.retryCount < this.maxRetries) {
      this.retryCount++;
      this.setState({ hasError: false, error: null });
    } else {
      window.location.reload();
    }
  };

  render() {
    if (this.state.hasError) {
      if (this.props.fallback) {
        return this.props.fallback;
      }

      return (
        <Alert variant="destructive" className="animate-in fade-in duration-300">
          <AlertCircle className="h-4 w-4" />
          <AlertTitle>Failed to load {this.props.componentName || 'component'}</AlertTitle>
          <AlertDescription className="mt-2">
            <p className="mb-3">
              {this.state.error?.message || 'An unexpected error occurred while loading this component.'}
            </p>
            {this.retryCount < this.maxRetries && (
              <p className="text-xs text-muted-foreground mb-3">
                Retry attempt {this.retryCount + 1} of {this.maxRetries + 1}
              </p>
            )}
            <div className="flex gap-2">
              <Button
                variant="outline"
                size="sm"
                onClick={this.handleRetry}
              >
                <RefreshCw className="h-3 w-3 mr-2" />
                {this.retryCount < this.maxRetries ? 'Try Again' : 'Reload Page'}
              </Button>
              <Button
                variant="ghost"
                size="sm"
                onClick={() => window.location.reload()}
              >
                Full Reload
              </Button>
            </div>
          </AlertDescription>
        </Alert>
      );
    }

    return this.props.children;
  }
}

// Suspense wrapper with timeout
function SuspenseWithTimeout({
  children,
  fallback,
  timeout = 5000,
  timeoutFallback
}: {
  children: ReactNode;
  fallback: ReactNode;
  timeout?: number;
  timeoutFallback?: ReactNode;
}) {
  const [showTimeoutWarning, setShowTimeoutWarning] = useState(false);

  useEffect(() => {
    const timer = setTimeout(() => {
      setShowTimeoutWarning(true);
    }, timeout);

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

  return (
    <Suspense fallback={showTimeoutWarning && timeoutFallback ? timeoutFallback : fallback}>
      {children}
    </Suspense>
  );
}

// Loading skeleton with timeout warning
function DashboardContentSkeletonWithWarning() {
  return (
    <div className="space-y-6 animate-in fade-in duration-500 relative">
      <Alert className="mb-4 animate-in fade-in duration-300">
        <AlertCircle className="h-4 w-4" />
        <AlertTitle>Taking longer than expected</AlertTitle>
        <AlertDescription>
          The dashboard is still loading. This may be due to a slow connection. Please wait...
        </AlertDescription>
      </Alert>
      <div className="space-y-6">
        <div>
          <Skeleton className="h-8 w-64 mb-2" />
          <Skeleton className="h-4 w-96 max-w-full" />
        </div>
        <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4 lg:gap-6">
          {[...Array(4)].map((_, i) => (
            <Card key={i}>
              <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
                <Skeleton className="h-4 w-20" />
                <Skeleton className="h-5 w-5 rounded" />
              </CardHeader>
              <CardContent>
                <Skeleton className="h-7 w-16 mb-1" />
                <Skeleton className="h-3 w-24" />
              </CardContent>
            </Card>
          ))}
        </div>
      </div>
    </div>
  );
}

// Import the skeleton from the page
function DashboardContentSkeleton() {
  return (
    <div
      className="space-y-6 animate-in fade-in duration-500 relative"
      role="status"
      aria-label="Loading dashboard content"
      aria-live="polite"
    >
      {/* Subtle loading indicator */}
      <div className="absolute top-0 left-0 right-0 h-1 bg-muted overflow-hidden rounded-full">
        <div className="h-full bg-primary w-1/3"
          style={{
            background: 'linear-gradient(90deg, transparent, hsl(var(--primary)), transparent)',
            backgroundSize: '200% 100%',
            animation: 'shimmer 2s ease-in-out infinite',
          }}
        />
      </div>

      {/* Header skeleton */}
      <div>
        <Skeleton className="h-8 w-64 mb-2" />
        <Skeleton className="h-4 w-96 max-w-full" />
      </div>

      {/* Stats cards skeleton */}
      <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4 lg:gap-6">
        {[...Array(4)].map((_, i) => (
          <Card
            key={i}
            className="animate-in fade-in slide-in-from-bottom-4"
            style={{
              animationDelay: `${i * 75}ms`,
              animationDuration: '400ms',
              animationFillMode: 'both',
            }}
          >
            <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
              <Skeleton className="h-4 w-20" />
              <Skeleton className="h-5 w-5 rounded" />
            </CardHeader>
            <CardContent>
              <Skeleton className="h-7 w-16 mb-1" />
              <Skeleton className="h-3 w-24" />
            </CardContent>
          </Card>
        ))}
      </div>

      {/* Best selling products skeleton */}
      <Card className="animate-in fade-in slide-in-from-bottom-4"
        style={{
          animationDelay: '300ms',
          animationDuration: '400ms',
          animationFillMode: 'both',
        }}
      >
        <CardHeader>
          <Skeleton className="h-6 w-48" />
          <Skeleton className="h-4 w-72 max-w-full" />
        </CardHeader>
        <CardContent>
          <div className="space-y-4">
            {[...Array(5)].map((_, i) => (
              <div
                key={i}
                className="flex items-center gap-4 animate-in fade-in"
                style={{
                  animationDelay: `${400 + i * 50}ms`,
                  animationDuration: '300ms',
                  animationFillMode: 'both',
                }}
              >
                <Skeleton className="h-12 w-12 rounded-md" />
                <div className="space-y-2">
                  <Skeleton className="h-4 w-40" />
                  <Skeleton className="h-4 w-20" />
                </div>
                <div className="ml-auto text-right">
                  <Skeleton className="h-4 w-16 ml-auto" />
                  <Skeleton className="h-4 w-16 ml-auto mt-2" />
                </div>
              </div>
            ))}
          </div>
        </CardContent>
      </Card>
    </div>
  );
}

export default function DashboardContentWrapper({ children }: { children: ReactNode }) {
  const router = useRouter();

  useEffect(() => {
    // Prefetch main dashboard routes for snappier navigation
    const prefetchRoutes = async () => {
      // Small delay to prioritize initial page load
      await new Promise(resolve => setTimeout(resolve, 2000));

      sidebarConfig.forEach(section => {
        section.items.forEach(item => {
          if (item.href && item.href !== "/dashboard") {
            router.prefetch(item.href);
          }
        });
      });
    };

    prefetchRoutes();
  }, [router]);

  return (
    <ErrorBoundary componentName="Dashboard Content">
      <SuspenseWithTimeout
        fallback={<DashboardContentSkeleton />}
        timeout={5000}
        timeoutFallback={<DashboardContentSkeletonWithWarning />}
      >
        {children}
      </SuspenseWithTimeout>
    </ErrorBoundary>
  );
}


