import {
  BookOpen,
  Braces,
  CassetteTape,
  ChevronRight,
  Code2,
  Cpu,
  Disc,
  File,
  FileText,
  FileType,
  Folder,
  HardDrive,
  Image as ImageIcon,
  MoreVertical,
  Music,
  Package,
  Save,
  SlidersHorizontal,
  Terminal,
} from 'lucide-react';
import { humanFileSize, type EntryInfo } from '../webdav';

// ─── Extension sets ───────────────────────────────────────────────────────────

export const TEXT_EXTS    = new Set(['txt', 'cfg', 'ini', 'seq', 'log', 'csv', 'lst']);
export const DOC_EXTS     = new Set(['doc', 'docx', 'odt', 'rtf', 'pdf', 'pages', 'tex', 'xls', 'xlsx', 'ods', 'ppt', 'pptx', 'odp']);
export const CODE_EXTS    = new Set(['asm', 'bas', 's', 'js', 'ts', 'jsx', 'tsx', 'css', 'scss', 'py', 'c', 'cpp', 'h', 'hpp', 'lua', 'sh', 'bash', 'php', 'rb', 'rs', 'go', 'java', 'cs', 'kt', 'sql', 'pl']);
export const MD_EXTS      = new Set(['md', 'markdown']);
export const JSON_EXTS    = new Set(['json', 'webmanifest']);
export const XML_EXTS     = new Set(['xml', 'html', 'htm', 'rss', 'atom', 'xsl']);
export const IMAGE_EXTS   = new Set(['png', 'jpg', 'jpeg', 'gif', 'bmp', 'webp', 'svg', 'ico']);
export const AUDIO_EXTS   = new Set(['sid', 'psid', 'rsid', 'mus', 'vgm']);
export const ROM_EXTS     = new Set(['bin', 'rom', 'crt']);
export const TAPE_EXTS    = new Set(['tap', 'htap', 't64', 'tcrt']);
export const DISK_EXTS    = new Set(['c64', 'd41', 'd64', 'd67', 'd71', 'd80', 'd81', 'd82', 'd88', 'f64', 'g41', 'g64', 'g71', 'g81', 'm2i', 'nbz', 'nib', 'p64', 'p71', 'p81', 'scp', 'x64']);
export const DISC_EXTS    = new Set(['iso', 'img', 'cue']);
export const HD_EXTS      = new Set(['d1m', 'd2m', 'd4m', 'd90', 'dhd', 'hdd', 'bbt', 'd8b', 'dfi']);
export const ARCHIVE_EXTS = new Set(['zip', '7z', 'tar', 'gz', 'bz2', 'xz', 'rar', 'arj', 'lzh', 'ace', 'z', 'lha', 'cab', 'lbr', 'arc', 'ark', 'lnx']);
export const CONFIG_EXTS  = new Set(['config']);

// ─── EntryIcon ────────────────────────────────────────────────────────────────

export function EntryIcon({ entry }: { entry: EntryInfo }) {
  if (entry.type === 'folder') return <Folder           className="w-5 h-5 text-blue-500    flex-shrink-0" />;
  const ext = entry.name.split('.').pop()?.toLowerCase() ?? '';
  if (IMAGE_EXTS.has(ext))    return <ImageIcon         className="w-5 h-5 text-purple-500  flex-shrink-0" />;
  if (DISK_EXTS.has(ext))     return <Save              className="w-5 h-5 text-amber-500   flex-shrink-0" />;
  if (HD_EXTS.has(ext))       return <HardDrive         className="w-5 h-5 text-orange-500  flex-shrink-0" />;
  if (DISC_EXTS.has(ext))     return <Disc              className="w-5 h-5 text-sky-500     flex-shrink-0" />;
  if (TAPE_EXTS.has(ext))     return <CassetteTape      className="w-5 h-5 text-rose-400    flex-shrink-0" />;
  if (ROM_EXTS.has(ext))      return <Cpu               className="w-5 h-5 text-red-500     flex-shrink-0" />;
  if (AUDIO_EXTS.has(ext))    return <Music             className="w-5 h-5 text-teal-500    flex-shrink-0" />;
  if (ARCHIVE_EXTS.has(ext))  return <Package           className="w-5 h-5 text-yellow-600  flex-shrink-0" />;
  if (CONFIG_EXTS.has(ext))   return <SlidersHorizontal className="w-5 h-5 text-slate-400   flex-shrink-0" />;
  if (JSON_EXTS.has(ext))     return <Braces            className="w-5 h-5 text-yellow-500  flex-shrink-0" />;
  if (XML_EXTS.has(ext))      return <Code2             className="w-5 h-5 text-cyan-500    flex-shrink-0" />;
  if (MD_EXTS.has(ext))       return <BookOpen          className="w-5 h-5 text-sky-400     flex-shrink-0" />;
  if (DOC_EXTS.has(ext))      return <FileType          className="w-5 h-5 text-blue-400    flex-shrink-0" />;
  if (CODE_EXTS.has(ext))     return <Terminal          className="w-5 h-5 text-green-600   flex-shrink-0" />;
  if (TEXT_EXTS.has(ext))     return <FileText          className="w-5 h-5 text-green-600   flex-shrink-0" />;
  return                             <File              className="w-5 h-5 text-neutral-400 flex-shrink-0" />;
}

// ─── MediaEntry ───────────────────────────────────────────────────────────────

export interface MediaEntryProps {
  entry: EntryInfo;
  onPrimaryClick: () => void;
  onActionsClick: (e: React.MouseEvent) => void;
  /** Optional leading slot — e.g. a checkbox in MediaManager. */
  leftSlot?: React.ReactNode;
  /** Replaces the filename text — e.g. an inline rename input. */
  nameSlot?: React.ReactNode;
  selected?: boolean;
  className?: string;
}

export function MediaEntry({
  entry, onPrimaryClick, onActionsClick, leftSlot, nameSlot, selected, className,
}: MediaEntryProps) {
  return (
    <div className={`pl-[14px] pr-4 py-3 flex items-center gap-3 border-b border-neutral-100 border-l-2 border-l-transparent transition-colors hover:bg-blue-50 hover:border-l-blue-400 ${selected ? 'bg-blue-50 border-l-blue-400' : ''} ${className ?? ''}`}>
      {leftSlot}
      <button className="flex-1 flex items-center gap-3 text-left min-w-0" onClick={onPrimaryClick}>
        <EntryIcon entry={entry} />
        <div className="min-w-0 flex-1">
          {nameSlot ?? <div className="text-neutral-900 truncate text-sm">{entry.name}</div>}
          {entry.type === 'file' && (
            <div className="text-xs text-neutral-400 truncate">
              {humanFileSize(entry.size)}
              {entry.lastModified ? ` · ${entry.lastModified.toLocaleDateString()}` : ''}
            </div>
          )}
        </div>
        {entry.type === 'folder' && <ChevronRight className="w-4 h-4 text-neutral-400 flex-shrink-0" />}
      </button>
      <button onClick={onActionsClick} className="p-2 rounded hover:bg-neutral-200 flex-shrink-0" title="Actions">
        <MoreVertical className="w-4 h-4" />
      </button>
    </div>
  );
}
