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

// Grid column types
type GridCols = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;

// Grid gap types
type GridGap = 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'responsive';

// Grid props interface
interface GridProps extends HTMLAttributes<HTMLDivElement> {
  children?: ReactNode;
  cols?: GridCols;
  gap?: GridGap;
  colsSm?: GridCols;
  colsMd?: GridCols;
  colsLg?: GridCols;
  colsXl?: GridCols;
  alignItems?: 'start' | 'center' | 'end' | 'stretch';
  justifyItems?: 'start' | 'center' | 'end' | 'stretch';
  // Mobile-first stacking
  stackMobile?: boolean;
  // Responsive columns
  responsiveCols?: {
    mobile?: GridCols;
    tablet?: GridCols;
    desktop?: GridCols;
  };
}

// Grid item props interface
interface GridItemProps extends HTMLAttributes<HTMLDivElement> {
  children?: ReactNode;
  colSpan?: GridCols;
  colSpanSm?: GridCols;
  colSpanMd?: GridCols;
  colSpanLg?: GridCols;
  colSpanXl?: GridCols;
  rowSpan?: GridCols;
  rowSpanSm?: GridCols;
  rowSpanMd?: GridCols;
  rowSpanLg?: GridCols;
  rowSpanXl?: GridCols;
}

// Helper function to get gap styles
const getGapStyles = (gap: GridGap, responsiveGap?: boolean) => {
  if (gap === 'responsive' || responsiveGap) {
    return 'gap-2 xs:gap-3 sm:gap-4 md:gap-6 lg:gap-8';
  }
  
  switch (gap) {
    case 'none':
      return 'gap-0';
    case 'xs':
      return 'gap-1';
    case 'sm':
      return 'gap-2';
    case 'md':
      return 'gap-4';
    case 'lg':
      return 'gap-6';
    case 'xl':
      return 'gap-8';
    case '2xl':
      return 'gap-12';
    default:
      return 'gap-4';
  }
};

// Helper function to get column classes
const getColClasses = (cols: GridCols | undefined, breakpoint: string = '') => {
  if (!cols) return '';
  const prefix = breakpoint ? `${breakpoint}:` : '';
  return `${prefix}grid-cols-${cols}`;
};

// Helper function to get span classes
const getSpanClasses = (span: GridCols | undefined, type: 'col' | 'row', breakpoint: string = '') => {
  if (!span) return '';
  const prefix = breakpoint ? `${breakpoint}:` : '';
  const typePrefix = type === 'col' ? 'col' : 'row';
  return `${prefix}${typePrefix}-span-${span}`;
};

// Helper function to get responsive column classes
const getResponsiveColClasses = (responsiveCols: GridProps['responsiveCols']) => {
  if (!responsiveCols) return '';
  
  let classes = '';
  
  // Mobile (default)
  if (responsiveCols.mobile) {
    classes += `grid-cols-${responsiveCols.mobile} `;
  }
  
  // Tablet
  if (responsiveCols.tablet) {
    classes += `md:grid-cols-${responsiveCols.tablet} `;
  }
  
  // Desktop
  if (responsiveCols.desktop) {
    classes += `lg:grid-cols-${responsiveCols.desktop} `;
  }
  
  return classes;
};

// Main Grid Component
export const Grid = forwardRef<HTMLDivElement, GridProps>(
  (
    {
      cols = 1,
      gap = 'md',
      colsSm,
      colsMd,
      colsLg,
      colsXl,
      alignItems,
      justifyItems,
      className = '',
      children,
      stackMobile = false,
      responsiveCols,
      ...props
    },
    ref
  ) => {
    // Get responsive column configuration
    const getResponsiveColumns = () => {
      if (responsiveCols) {
        return getResponsiveColClasses(responsiveCols);
      }
      
      if (stackMobile) {
        // Mobile-first: 1 column, then scale up
        return `grid-cols-1 sm:grid-cols-2 ${colsMd ? `md:grid-cols-${colsMd}` : 'md:grid-cols-3'} ${colsLg ? `lg:grid-cols-${colsLg}` : ''}`;
      }
      
      // Default responsive behavior
      let colClasses = `grid-cols-${cols}`;
      if (colsSm) colClasses += ` sm:grid-cols-${colsSm}`;
      if (colsMd) colClasses += ` md:grid-cols-${colsMd}`;
      if (colsLg) colClasses += ` lg:grid-cols-${colsLg}`;
      if (colsXl) colClasses += ` xl:grid-cols-${colsXl}`;
      
      return colClasses;
    };

    // Get responsive gap
    const getResponsiveGap = () => {
      if (gap === 'responsive') {
        return 'gap-2 xs:gap-3 sm:gap-4 md:gap-6 lg:gap-8';
      }
      
      // Mobile-first gap scaling
      if (stackMobile) {
        return 'gap-3 sm:gap-4 md:gap-6 lg:gap-8';
      }
      
      return getGapStyles(gap);
    };

    return (
      <div
        ref={ref}
        className={cn(
          // Base grid
          'grid',
          // Responsive columns
          getResponsiveColumns(),
          // Gap (responsive)
          getResponsiveGap(),
          // Alignment
          alignItems && `items-${alignItems}`,
          justifyItems && `justify-items-${justifyItems}`,
          // Mobile-specific: ensure full width
          'w-full',
          // Custom classes
          className
        )}
        // Add role for accessibility
        role="grid"
        {...props}
      >
        {children}
      </div>
    );
  }
);

Grid.displayName = 'Grid';

// Grid Item Component
export const GridItem = forwardRef<HTMLDivElement, GridItemProps>(
  (
    {
      colSpan,
      colSpanSm,
      colSpanMd,
      colSpanLg,
      colSpanXl,
      rowSpan,
      rowSpanSm,
      rowSpanMd,
      rowSpanLg,
      rowSpanXl,
      className = '',
      children,
      ...props
    },
    ref
  ) => {
    return (
      <div
        ref={ref}
        className={cn(
          // Column spans
          getSpanClasses(colSpan, 'col'),
          getSpanClasses(colSpanSm, 'col', 'sm'),
          getSpanClasses(colSpanMd, 'col', 'md'),
          getSpanClasses(colSpanLg, 'col', 'lg'),
          getSpanClasses(colSpanXl, 'col', 'xl'),
          // Row spans
          getSpanClasses(rowSpan, 'row'),
          getSpanClasses(rowSpanSm, 'row', 'sm'),
          getSpanClasses(rowSpanMd, 'row', 'md'),
          getSpanClasses(rowSpanLg, 'row', 'lg'),
          getSpanClasses(rowSpanXl, 'row', 'xl'),
          // Ensure item doesn't overflow
          'min-w-0',
          // Custom classes
          className
        )}
        // Add role for accessibility
        role="gridcell"
        {...props}
      >
        {children}
      </div>
    );
  }
);

GridItem.displayName = 'GridItem';

// Export types for external use
export type { GridProps, GridItemProps, GridCols, GridGap };