import React from "react";
import { cn } from "~/lib/utils";
import { Loader2 } from "lucide-react";

interface LoadingSpinnerProps {
  size?: "xs" | "sm" | "md" | "lg" | "xl";
  variant?: "primary" | "secondary" | "muted" | "white";
  className?: string;
}

export function LoadingSpinner({
  size = "md",
  variant = "primary",
  className,
}: LoadingSpinnerProps) {
  const sizes = {
    xs: "w-3 h-3",
    sm: "w-4 h-4",
    md: "w-6 h-6",
    lg: "w-8 h-8",
    xl: "w-12 h-12",
  };

  const variants = {
    primary: "text-primary",
    secondary: "text-secondary",
    muted: "text-muted-foreground",
    white: "text-white",
  };

  return (
    <Loader2
      className={cn("animate-spin", sizes[size], variants[variant], className)}
    />
  );
}

interface LoadingDotsProps {
  size?: "sm" | "md" | "lg";
  variant?: "primary" | "secondary" | "muted" | "white";
  className?: string;
}

export function LoadingDots({
  size = "md",
  variant = "primary",
  className,
}: LoadingDotsProps) {
  const sizes = {
    sm: "w-1 h-1",
    md: "w-2 h-2",
    lg: "w-3 h-3",
  };

  const variants = {
    primary: "bg-primary",
    secondary: "bg-secondary",
    muted: "bg-muted-foreground",
    white: "bg-white",
  };

  const dotClass = cn(
    "rounded-full animate-pulse",
    sizes[size],
    variants[variant],
  );

  return (
    <div className={cn("flex items-center space-x-1", className)}>
      <div className={cn(dotClass, "animation-delay-0")} />
      <div className={cn(dotClass, "animation-delay-200")} />
      <div className={cn(dotClass, "animation-delay-400")} />
    </div>
  );
}

interface LoadingBarProps {
  progress?: number;
  variant?: "primary" | "secondary" | "success" | "warning" | "error";
  size?: "sm" | "md" | "lg";
  className?: string;
  showPercentage?: boolean;
}

export function LoadingBar({
  progress,
  variant = "primary",
  size = "md",
  className,
  showPercentage = false,
}: LoadingBarProps) {
  const variants = {
    primary: "bg-primary",
    secondary: "bg-secondary",
    success: "bg-green-500",
    warning: "bg-yellow-500",
    error: "bg-red-500",
  };

  const sizes = {
    sm: "h-1",
    md: "h-2",
    lg: "h-3",
  };

  return (
    <div className={cn("w-full", className)}>
      {showPercentage && progress !== undefined && (
        <div className="flex justify-between text-sm text-muted-foreground mb-1 font-persian">
          <span>در حال بارگذاری...</span>
          <span>{Math.round(progress)}%</span>
        </div>
      )}
      <div
        className={cn(
          "w-full bg-muted rounded-full overflow-hidden",
          sizes[size],
        )}
      >
        <div
          className={cn(
            "h-full transition-all duration-300 ease-out rounded-full",
            variants[variant],
            progress === undefined && "animate-pulse",
          )}
          style={{
            width:
              progress !== undefined ? `${Math.min(progress, 100)}%` : "100%",
          }}
        />
      </div>
    </div>
  );
}

interface LoadingPageProps {
  title?: string;
  description?: string;
  variant?: "primary" | "white";
  className?: string;
}

export function LoadingPage({
  title = "در حال بارگذاری...",
  description,
  variant = "primary",
  className,
}: LoadingPageProps) {
  const isWhite = variant === "white";

  return (
    <div
      className={cn(
        "min-h-screen flex items-center justify-center",
        isWhite ? "bg-background" : "bg-slate-800",
        className,
      )}
    >
      <div className="text-center space-y-6 max-w-md mx-auto p-8">
        <div className="flex justify-center">
          <LoadingSpinner size="xl" variant={isWhite ? "primary" : "white"} />
        </div>
        <div className="space-y-2">
          <h2
            className={cn(
              "text-lg font-medium font-persian",
              isWhite ? "text-foreground" : "text-white",
            )}
          >
            {title}
          </h2>
          {description && (
            <p
              className={cn(
                "text-sm font-persian leading-relaxed",
                isWhite ? "text-muted-foreground" : "text-slate-300",
              )}
            >
              {description}
            </p>
          )}
        </div>
      </div>
    </div>
  );
}

interface LoadingOverlayProps {
  visible: boolean;
  title?: string;
  description?: string;
  className?: string;
}

export function LoadingOverlay({
  visible,
  title = "در حال پردازش...",
  description,
  className,
}: LoadingOverlayProps) {
  if (!visible) return null;

  return (
    <div
      className={cn(
        "fixed inset-0 bg-black/50 backdrop-blur-sm z-50 flex items-center justify-center transition-all duration-200",
        className,
      )}
    >
      <div className="bg-card border border-border rounded-lg p-6 max-w-sm mx-4 shadow-lg">
        <div className="text-center space-y-4">
          <LoadingSpinner size="lg" />
          <div className="space-y-1">
            <h3 className="text-sm font-medium font-persian text-card-foreground">
              {title}
            </h3>
            {description && (
              <p className="text-xs text-muted-foreground font-persian">
                {description}
              </p>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

interface LoadingButtonProps {
  loading: boolean;
  children: React.ReactNode;
  className?: string;
}

export function LoadingButton({
  loading,
  children,
  className,
  ...props
}: LoadingButtonProps & React.ButtonHTMLAttributes<HTMLButtonElement>) {
  return (
    <button
      className={cn(
        "relative inline-flex items-center justify-center",
        className,
      )}
      disabled={loading}
      {...props}
    >
      {loading && (
        <LoadingSpinner
          size="sm"
          className="absolute left-1/2 top-1/2 transform -translate-x-1/2 -translate-y-1/2"
        />
      )}
      <span className={cn(loading && "opacity-0")}>{children}</span>
    </button>
  );
}

interface LoadingCardProps {
  title?: string;
  lines?: number;
  showAvatar?: boolean;
  className?: string;
}

export function LoadingCard({
  title,
  lines = 3,
  showAvatar = false,
  className,
}: LoadingCardProps) {
  return (
    <div className={cn("animate-pulse p-4 space-y-4", className)}>
      {title && <div className="h-4 bg-muted rounded w-3/4" />}

      <div className="flex items-start space-x-4">
        {showAvatar && <div className="w-10 h-10 bg-muted rounded-full" />}
        <div className="flex-1 space-y-2">
          {Array.from({ length: lines }).map((_, index) => (
            <div
              key={index}
              className={cn(
                "h-3 bg-muted rounded",
                index === lines - 1 ? "w-2/3" : "w-full",
              )}
            />
          ))}
        </div>
      </div>
    </div>
  );
}

interface LoadingSkeletonProps {
  className?: string;
  variant?: "text" | "circular" | "rectangular";
  width?: string | number;
  height?: string | number;
}

export function LoadingSkeleton({
  className,
  variant = "rectangular",
  width,
  height,
}: LoadingSkeletonProps) {
  const variants = {
    text: "h-4 w-full",
    circular: "rounded-full",
    rectangular: "rounded",
  };

  const style: React.CSSProperties = {};
  if (width) style.width = typeof width === "number" ? `${width}px` : width;
  if (height)
    style.height = typeof height === "number" ? `${height}px` : height;

  return (
    <div
      className={cn(
        "animate-pulse bg-muted",
        variants[variant],
        !width && !height && variants.text,
        className,
      )}
      style={style}
    />
  );
}

// Utility component for loading states
interface LoadingStateProps {
  loading: boolean;
  error?: string | null;
  children: React.ReactNode;
  loadingComponent?: React.ReactNode;
  errorComponent?: React.ReactNode;
}

export function LoadingState({
  loading,
  error,
  children,
  loadingComponent,
  errorComponent,
}: LoadingStateProps) {
  if (loading) {
    return loadingComponent || <LoadingSpinner />;
  }

  if (error) {
    return (
      errorComponent || (
        <div className="text-center p-4">
          <p className="text-destructive text-sm font-persian">{error}</p>
        </div>
      )
    );
  }

  return <>{children}</>;
}

// Default export for convenience
export default LoadingSpinner;
