"use client";

import React, { forwardRef } from "react";
import { BaseComponentProps } from "../../types";

export interface LoadingProps extends BaseComponentProps {
  size?: "xs" | "sm" | "md" | "lg" | "xl";
  variant?: "spinner" | "dots" | "pulse" | "bars" | "ring";
  text?: string;
  center?: boolean;
  color?: "primary" | "secondary" | "muted";
  overlay?: boolean;
}

export const Loading = forwardRef<HTMLDivElement, LoadingProps>(
  (
    {
      className = "",
      size = "md",
      variant = "spinner",
      text,
      center = false,
      color = "primary",
      overlay = false,
      ...props
    },
    ref
  ) => {
    const sizeClasses = {
      xs: "w-3 h-3",
      sm: "w-4 h-4",
      md: "w-8 h-8",
      lg: "w-12 h-12",
      xl: "w-16 h-16",
    };

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

    const containerClasses = [
      center ? "flex items-center justify-center" : "inline-flex items-center",
      overlay ? "fixed inset-0 bg-background/80 backdrop-blur-sm z-50" : "",
      colorClasses[color],
    ]
      .filter(Boolean)
      .join(" ");

    const renderSpinner = () => (
      <svg
        className={`animate-spin ${sizeClasses[size]} ${className}`}
        fill="none"
        viewBox="0 0 24 24"
        aria-hidden="true"
      >
        <circle
          cx="12"
          cy="12"
          r="10"
          stroke="currentColor"
          strokeWidth="4"
          className="opacity-25"
        />
        <path
          fill="currentColor"
          d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
          className="opacity-75"
        />
      </svg>
    );

    const renderDots = () => (
      <div className={`flex space-x-1 ${className}`} aria-hidden="true">
        {[0, 1, 2].map((i) => (
          <div
            key={i}
            className={`rounded-full bg-current ${
              size === "xs"
                ? "w-1 h-1"
                : size === "sm"
                ? "w-1.5 h-1.5"
                : size === "md"
                ? "w-2 h-2"
                : size === "lg"
                ? "w-3 h-3"
                : "w-4 h-4"
            }`}
            style={{
              animation: `loading-dots 1.4s ease-in-out ${
                i * 0.2
              }s infinite both`,
            }}
          />
        ))}
      </div>
    );

    const renderPulse = () => (
      <div
        className={`rounded bg-current animate-pulse ${sizeClasses[size]} ${className}`}
        aria-hidden="true"
      />
    );

    const renderBars = () => (
      <div
        className={`flex space-x-1 items-end ${className}`}
        aria-hidden="true"
      >
        {[0, 1, 2, 3].map((i) => (
          <div
            key={i}
            className={`bg-current ${
              size === "xs"
                ? "w-0.5"
                : size === "sm"
                ? "w-0.5"
                : size === "md"
                ? "w-1"
                : size === "lg"
                ? "w-1.5"
                : "w-2"
            } ${
              size === "xs"
                ? "h-2"
                : size === "sm"
                ? "h-3"
                : size === "md"
                ? "h-4"
                : size === "lg"
                ? "h-6"
                : "h-8"
            }`}
            style={{
              animation: `loading-bars 1s ease-in-out ${i * 0.1}s infinite`,
            }}
          />
        ))}
      </div>
    );

    const renderRing = () => (
      <div
        className={`relative ${sizeClasses[size]} ${className}`}
        aria-hidden="true"
      >
        <div className="absolute inset-0 rounded-full border-2 border-current opacity-25"></div>
        <div className="absolute inset-0 rounded-full border-2 border-transparent border-t-current animate-spin"></div>
      </div>
    );

    const renderVariant = () => {
      switch (variant) {
        case "dots":
          return renderDots();
        case "pulse":
          return renderPulse();
        case "bars":
          return renderBars();
        case "ring":
          return renderRing();
        default:
          return renderSpinner();
      }
    };

    return (
      <div
        ref={ref}
        className={containerClasses}
        role="status"
        aria-live="polite"
        aria-label={text || "Loading"}
        {...props}
      >
        {renderVariant()}
        {text && <span className="ml-2 text-sm font-medium">{text}</span>}
      </div>
    );
  }
);

Loading.displayName = "Loading";
