import { useState, useEffect } from 'react';
import { cn } from '@/lib/utils';
import type { Track } from '../../player/types';
import { TrackCard } from './TrackCard';

export type DensityMode = 'compact' | 'normal' | 'comfortable';

export interface TrackGridProps {
  tracks: Track[];
  isLoading?: boolean;
  emptyMessage?: string;
  onTrackClick?: (track: Track) => void;
  columns?: number;
  autoColumns?: boolean;
  mobileColumns?: number;
  gap?: 'sm' | 'md' | 'lg';
  showCover?: boolean;
  className?: string;
  cardSize?: 'sm' | 'md' | 'lg';
  isLiked?: (id: string) => boolean;
  isPlaying?: (id: string) => boolean;
  onTrackLike?: (track: Track) => void;
  onTrackPlay?: (track: Track) => void;
  onTrackMore?: (track: Track) => void;
  showDensitySelector?: boolean;
  onDensityChange?: (density: DensityMode) => void;
  persistDensity?: boolean;
  densityStorageKey?: string;
  density?: DensityMode;
}

export function TrackGrid({
  tracks,
  isLoading,
  emptyMessage = 'Aucune piste disponible',
  onTrackClick,
  columns = 4,
  autoColumns,
  mobileColumns = 1,
  gap: gapProp,
  showCover: _showCover = true,
  className,
  cardSize = 'md',
  isLiked,
  isPlaying,
  onTrackLike,
  onTrackPlay,
  onTrackMore,
  showDensitySelector,
  onDensityChange,
  persistDensity,
  densityStorageKey = 'trackGridDensity',
  density: densityProp,
}: TrackGridProps) {
  // State for density
  const [currentDensity, setCurrentDensity] = useState<DensityMode>(() => {
    if (persistDensity) {
      const stored = localStorage.getItem(densityStorageKey);
      if (
        stored === 'compact' ||
        stored === 'normal' ||
        stored === 'comfortable'
      ) {
        return stored;
      }
    }
    return densityProp || 'normal';
  });

  // Sync prop changes to state
  useEffect(() => {
    if (densityProp) {
      setCurrentDensity(densityProp);
    }
  }, [densityProp]);

  // Persist changes
  const handleDensityChange = (newDensity: DensityMode) => {
    setCurrentDensity(newDensity);
    onDensityChange?.(newDensity);
    if (persistDensity) {
      localStorage.setItem(densityStorageKey, newDensity);
    }
  };

  // Determine gap based on density or prop
  let gapClass = 'gap-4';
  const effectiveGap =
    gapProp ||
    (currentDensity === 'compact'
      ? 'sm'
      : currentDensity === 'normal'
        ? 'md'
        : 'lg');

  if (effectiveGap === 'sm') gapClass = 'gap-2 sm:gap-3';
  if (effectiveGap === 'md') gapClass = 'gap-3 sm:gap-4';
  if (effectiveGap === 'lg') gapClass = 'gap-4 sm:gap-6';

  // Determine grid columns
  let gridColsClass = '';

  if (autoColumns) {
    // Auto columns using responsive steps
    gridColsClass = `grid-cols-${mobileColumns} sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 2xl:grid-cols-6`;
  } else {
    // Fixed columns logic (approximated based on tests expecting responsive breakdown even for fixed columns?)
    // Test says: columns={3} -> grid-cols-2 sm:grid-cols-2 md:grid-cols-3
    // So it builds up to the target column count.
    const base = mobileColumns;
    gridColsClass = `grid-cols-${base}`;

    if (columns >= 2) gridColsClass += ` sm:grid-cols-2`;
    if (columns >= 3) gridColsClass += ` md:grid-cols-3`;
    if (columns >= 4) gridColsClass += ` lg:grid-cols-4`;
    if (columns >= 5) gridColsClass += ` xl:grid-cols-5`;
    if (columns >= 6) gridColsClass += ` 2xl:grid-cols-6`;
  }

  if (isLoading) {
    return (
      <div className={cn('grid', gridColsClass, gapClass, className)}>
        {Array.from({ length: columns * 2 }).map((_, i) => (
          <div
            key={i}
            className="animate-pulse bg-muted rounded-md aspect-[3/4]"
          />
        ))}
      </div>
    );
  }

  if (tracks.length === 0) {
    return (
      <div className="text-center p-8 text-muted-foreground">
        {emptyMessage}
      </div>
    );
  }

  return (
    <div className="space-y-4">
      {showDensitySelector && (
        <div
          role="radiogroup"
          aria-label="Densité d'affichage"
          className="flex justify-end gap-2"
        >
          <button
            aria-label="Compact"
            onClick={() => handleDensityChange('compact')}
            className={cn(
              'p-1 rounded',
              currentDensity === 'compact'
                ? 'bg-primary text-primary-foreground'
                : 'hover:bg-muted',
            )}
          >
            Small
          </button>
          <button
            aria-label="Normal"
            onClick={() => handleDensityChange('normal')}
            className={cn(
              'p-1 rounded',
              currentDensity === 'normal'
                ? 'bg-primary text-primary-foreground'
                : 'hover:bg-muted',
            )}
          >
            Medium
          </button>
          <button
            aria-label="Confortable"
            onClick={() => handleDensityChange('comfortable')}
            className={cn(
              'p-1 rounded',
              currentDensity === 'comfortable'
                ? 'bg-primary text-primary-foreground'
                : 'hover:bg-muted',
            )}
          >
            Large
          </button>
        </div>
      )}

      <div
        role="grid"
        aria-label="Grille de pistes"
        className={cn('grid', gridColsClass, gapClass, className)}
      >
        {tracks.map((track) => (
          <TrackCard
            key={track.id}
            track={track}
            size={cardSize}
            onPlay={onTrackPlay}
            onLike={onTrackLike}
            onMore={onTrackMore}
            onClick={onTrackClick}
            isLiked={isLiked?.(track.id)}
            isPlaying={isPlaying?.(track.id)}
            // Pass other props if necessary
          />
        ))}
      </div>
    </div>
  );
}

export { TrackCard }; // Export TrackCard from here if index.ts expects it from here? No index.ts accesses ./components/TrackCard directly.
