import React, { forwardRef, ReactNode, HTMLAttributes } from 'react';
import { cn } from '../../lib/utils';

// Card variants
type CardVariant = 'elevated' | 'flat' | 'bordered';

// Card props interface
interface CardProps extends HTMLAttributes<HTMLDivElement> {
  variant?: CardVariant;
  children?: ReactNode;
  padding?: 'none' | 'sm' | 'md' | 'lg' | 'xl';
  hoverable?: boolean;
  shadow?: boolean;
}

// Card header props
interface CardHeaderProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
  title?: ReactNode;
  subtitle?: ReactNode;
  icon?: ReactNode;
  action?: ReactNode;
}

// Card body props
interface CardBodyProps extends HTMLAttributes<HTMLDivElement> {
  children?: ReactNode;
}

// Card footer props
interface CardFooterProps extends HTMLAttributes<HTMLDivElement> {
  children?: ReactNode;
  align?: 'left' | 'center' | 'right';
}

// Card image props
interface CardImageProps extends HTMLAttributes<HTMLDivElement> {
  src: string;
  alt?: string;
  height?: 'sm' | 'md' | 'lg' | 'xl';
  position?: 'top' | 'background';
}

// Helper function to get variant styles
const getVariantStyles = (variant: CardVariant) => {
  switch (variant) {
    case 'elevated':
      return 'bg-white shadow-lg shadow-gray-200/50 border border-gray-100';
    case 'flat':
      return 'bg-white shadow-sm border border-gray-100';
    case 'bordered':
      return 'bg-white border-2 border-gray-200';
    default:
      return 'bg-white shadow-md border border-gray-100';
  }
};

// Helper function to get padding styles
const getPaddingStyles = (padding: CardProps['padding']) => {
  switch (padding) {
    case 'none':
      return '';
    case 'sm':
      return 'p-3';
    case 'md':
      return 'p-4';
    case 'lg':
      return 'p-6';
    case 'xl':
      return 'p-8';
    default:
      return 'p-4';
  }
};

// Helper function to get image height
const getImageHeight = (height: CardImageProps['height']) => {
  switch (height) {
    case 'sm':
      return 'h-32';
    case 'md':
      return 'h-48';
    case 'lg':
      return 'h-64';
    case 'xl':
      return 'h-80';
    default:
      return 'h-48';
  }
};

// Main Card Component
export const Card = forwardRef<HTMLDivElement, CardProps>(
  (
    {
      variant = 'elevated',
      padding = 'md',
      hoverable = false,
      shadow = true,
      className = '',
      children,
      ...props
    },
    ref
  ) => {
    return (
      <div
        ref={ref}
        className={cn(
          'rounded-lg',
          'transition-all duration-200 ease-in-out',
          // Variant styles
          getVariantStyles(variant),
          // Padding
          getPaddingStyles(padding),
          // Hover effect
          hoverable && 'hover:shadow-xl hover:shadow-gray-200/70 hover:-translate-y-1',
          // Shadow override
          !shadow && 'shadow-none',
          // Custom classes
          className
        )}
        {...props}
      >
        {children}
      </div>
    );
  }
);

Card.displayName = 'Card';

// Card Header Component
export const CardHeader = forwardRef<HTMLDivElement, CardHeaderProps>(
  ({ title, subtitle, icon, action, className = '', children, ...props }, ref) => {
    return (
      <div
        ref={ref}
        className={cn(
          'flex items-start justify-between gap-4',
          'border-b border-gray-100 pb-4 mb-4',
          className
        )}
        {...props}
      >
        <div className="flex items-start gap-3 flex-1">
          {icon && <div className="text-gray-500 mt-0.5">{icon}</div>}
          <div className="flex-1">
            {title && (
              <div className="text-lg font-semibold text-gray-900 leading-tight">
                {title}
              </div>
            )}
            {subtitle && (
              <div className="text-sm text-gray-600 mt-1 leading-relaxed">
                {subtitle}
              </div>
            )}
            {children}
          </div>
        </div>
        {action && <div className="flex-shrink-0">{action}</div>}
      </div>
    );
  }
);

CardHeader.displayName = 'CardHeader';

// Card Body Component
export const CardBody = forwardRef<HTMLDivElement, CardBodyProps>(
  ({ className = '', children, ...props }, ref) => {
    return (
      <div
        ref={ref}
        className={cn('space-y-3', className)}
        {...props}
      >
        {children}
      </div>
    );
  }
);

CardBody.displayName = 'CardBody';

// Card Footer Component
export const CardFooter = forwardRef<HTMLDivElement, CardFooterProps>(
  ({ align = 'left', className = '', children, ...props }, ref) => {
    const alignmentClasses = {
      left: 'justify-start',
      center: 'justify-center',
      right: 'justify-end',
    };

    return (
      <div
        ref={ref}
        className={cn(
          'flex items-center gap-3',
          'border-t border-gray-100 pt-4 mt-4',
          alignmentClasses[align],
          className
        )}
        {...props}
      >
        {children}
      </div>
    );
  }
);

CardFooter.displayName = 'CardFooter';

// Card Image Component
export const CardImage = forwardRef<HTMLDivElement, CardImageProps>(
  ({ src, alt, height = 'md', position = 'top', className = '', ...props }, ref) => {
    const heightClasses = getImageHeight(height);
    
    if (position === 'background') {
      return (
        <div
          ref={ref}
          className={cn(
            'relative w-full overflow-hidden rounded-t-lg',
            heightClasses,
            className
          )}
          {...props}
        >
          {/* eslint-disable-next-line @next/next/no-img-element */}
          <img
            src={src}
            alt={alt || ''}
            className="absolute inset-0 w-full h-full object-cover"
          />
          <div className="absolute inset-0 bg-gradient-to-t from-black/50 to-transparent" />
        </div>
      );
    }

    return (
      <div
        ref={ref}
        className={cn(
          'w-full overflow-hidden rounded-t-lg',
          heightClasses,
          className
        )}
        {...props}
      >
        {/* eslint-disable-next-line @next/next/no-img-element */}
        <img
          src={src}
          alt={alt || ''}
          className="w-full h-full object-cover"
        />
      </div>
    );
  }
);

CardImage.displayName = 'CardImage';

// Export types for external use
export type { CardProps, CardHeaderProps, CardBodyProps, CardFooterProps, CardImageProps, CardVariant };