'use client';

import React, { ReactNode, HTMLAttributes, forwardRef } from 'react';
import Link from 'next/link';
import { cn } from '@/lib/utils';
import { Card } from '@/components/ui';

// Base card sizes
export type CardSize = 'sm' | 'md' | 'lg';

// Base card layouts
export type CardLayout = 'vertical' | 'horizontal';

// Base card props interface
export interface BaseCardProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
  /** Card title */
  title?: ReactNode;
  /** Card description/excerpt */
  description?: ReactNode;
  /** Card image URL */
  image?: string;
  /** Card image alt text */
  imageAlt?: string;
  /** Card size */
  size?: CardSize;
  /** Card layout */
  layout?: CardLayout;
  /** Card href/link */
  href?: string;
  /** Card badge/badges */
  badge?: ReactNode;
  /** Card footer content */
  footer?: ReactNode;
  /** Card header content */
  header?: ReactNode;
  /** Loading state */
  loading?: boolean;
  /** Hover effect */
  hoverable?: boolean;
  /** Card variant */
  variant?: 'elevated' | 'flat' | 'bordered';
  /** Image height */
  imageHeight?: 'sm' | 'md' | 'lg' | 'xl';
  /** Children content */
  children?: ReactNode;
}

// Helper function to get size styles
const getSizeStyles = (size: CardSize, layout: CardLayout) => {
  const sizeMap = {
    vertical: {
      sm: { container: 'max-w-xs', image: 'h-32', padding: 'p-3' },
      md: { container: 'max-w-sm', image: 'h-48', padding: 'p-4' },
      lg: { container: 'max-w-md', image: 'h-64', padding: 'p-6' },
    },
    horizontal: {
      sm: { container: 'max-w-sm', image: 'h-24 w-24', padding: 'p-3' },
      md: { container: 'max-w-lg', image: 'h-32 w-32', padding: 'p-4' },
      lg: { container: 'max-w-xl', image: 'h-40 w-40', padding: 'p-6' },
    },
  };

  return sizeMap[layout][size];
};

// Helper function to get image height
const getImageHeight = (height: CardSize | 'sm' | 'md' | 'lg' | 'xl') => {
  const heightMap = {
    sm: 'h-32',
    md: 'h-48',
    lg: 'h-64',
    xl: 'h-80',
  };
  return heightMap[height] || heightMap['md'];
};

// Skeleton loader component
const CardSkeleton = ({ layout, size }: { layout: CardLayout; size: CardSize }) => {
  const sizeStyles = getSizeStyles(size, layout);
  
  return (
    <div className={cn('animate-pulse bg-gray-200 rounded-lg', sizeStyles.container)}>
      <div className={cn('bg-gray-300 rounded-t-lg', sizeStyles.image)} />
      <div className={sizeStyles.padding}>
        <div className="h-6 bg-gray-300 rounded mb-2 w-3/4" />
        <div className="h-4 bg-gray-300 rounded mb-1 w-full" />
        <div className="h-4 bg-gray-300 rounded mb-1 w-5/6" />
        <div className="h-4 bg-gray-300 rounded w-2/3 mt-3" />
      </div>
    </div>
  );
};

// Main BaseCard Component
export const BaseCard = forwardRef<HTMLDivElement, BaseCardProps>(
  (
    {
      title,
      description,
      image,
      imageAlt = '',
      size = 'md',
      layout = 'vertical',
      href,
      badge,
      footer,
      header,
      loading = false,
      hoverable = true,
      variant = 'elevated',
      imageHeight,
      className = '',
      children,
      ...props
    },
    ref
  ) => {
    const sizeStyles = getSizeStyles(size, layout);

    // Loading state
    if (loading) {
      return <CardSkeleton layout={layout} size={size} />;
    }

    // Content sections
    const renderImage = () => {
      if (!image) return null;

      const imageClasses = layout === 'horizontal' 
        ? cn('flex-shrink-0 overflow-hidden rounded-lg', sizeStyles.image)
        : cn('w-full overflow-hidden rounded-t-lg', imageHeight ? getImageHeight(imageHeight) : sizeStyles.image);

      return (
        <div className={imageClasses}>
          {/* eslint-disable-next-line @next/next/no-img-element */}
          <img
            src={image}
            alt={imageAlt}
            className="w-full h-full object-cover transition-transform duration-200 group-hover:scale-105"
          />
        </div>
      );
    };

    const renderHeader = () => {
      if (!header && !badge) return null;
      return (
        <div className="flex items-start justify-between gap-2 mb-2">
          {header}
          {badge}
        </div>
      );
    };

    const renderTitle = () => {
      if (!title) return null;
      return (
        <h3 className={cn(
          'font-semibold text-gray-900 leading-tight',
          size === 'sm' && 'text-base',
          size === 'md' && 'text-lg',
          size === 'lg' && 'text-xl'
        )}>
          {title}
        </h3>
      );
    };

    const renderDescription = () => {
      if (!description) return null;
      return (
        <div className={cn(
          'text-gray-600 mt-1',
          size === 'sm' && 'text-sm',
          size === 'md' && 'text-sm',
          size === 'lg' && 'text-base'
        )}>
          {description}
        </div>
      );
    };

    const renderFooter = () => {
      if (!footer) return null;
      return (
        <div className="mt-3 pt-3 border-t border-gray-100">
          {footer}
        </div>
      );
    };

    // Card content
    const cardContent = (
      <div className={cn(
        'flex',
        layout === 'horizontal' && 'flex-row',
        layout === 'vertical' && 'flex-col',
        sizeStyles.padding
      )}>
        {layout === 'horizontal' && renderImage()}
        <div className={cn('flex-1', layout === 'horizontal' && 'ml-4')}>
          {renderHeader()}
          {renderTitle()}
          {renderDescription()}
          {children}
          {renderFooter()}
        </div>
        {layout === 'vertical' && renderImage()}
      </div>
    );

    // If href is provided, wrap in a Next.js Link
    if (href) {
      return (
        <Link
          href={href}
          className={cn(
            'group block',
            'transition-all duration-200 ease-in-out',
            hoverable && 'hover:-translate-y-1 hover:shadow-xl',
            className
          )}
        >
          <Card variant={variant} padding="none" className={sizeStyles.container}>
            {cardContent}
          </Card>
        </Link>
      );
    }

    // Otherwise, just return the card
    return (
      <Card
        ref={ref}
        variant={variant}
        padding="none"
        className={cn(sizeStyles.container, className)}
        hoverable={hoverable}
        {...props}
      >
        {cardContent}
      </Card>
    );
  }
);

BaseCard.displayName = 'BaseCard';