'use client';

import { useEffect } from 'react';
import { useDrop } from 'react-dnd';
import { Transition } from '@headlessui/react';
import type {
  DocumentListDocument,
  Folder,
  IconSize,
} from '@/types/documents';
import { formatDocumentSize } from '@/components/doclist/formatSize';
import { Button } from '@headlessui/react';
import { DocumentTile } from './DocumentTile';
import { FolderIcon } from '../window/finderIcons';
import { useDocumentSelection } from '../dnd/DocumentSelectionContext';
import { DND_DOCUMENT, type DocumentDragItem } from '../dnd/dndTypes';

interface IconsViewProps {
  folders: Folder[];
  unfolderedDocs: DocumentListDocument[];
  iconSize: IconSize;
  collapsedFolders: Set<string>;
  onToggleCollapse: (folderId: string) => void;
  onDeleteFolder: (folderId: string) => void;
  onDeleteDoc: (doc: DocumentListDocument) => void;
  onDropOnFolder: (folderId: string, item: DocumentDragItem) => void;
  onMergeIntoFolder: (sources: DocumentListDocument[], target: DocumentListDocument) => void;
}

const TILE_WIDTH_PX: Record<IconSize, number> = {
  sm: 112,
  md: 136,
  lg: 162,
  xl: 192,
};

function responsiveGridTemplate(iconSize: IconSize): string {
  const width = TILE_WIDTH_PX[iconSize];
  return `repeat(auto-fit, minmax(${width}px, 1fr))`;
}

const gridGap = '12px';

function gridStyle(iconSize: IconSize): React.CSSProperties {
  return {
    gridTemplateColumns: responsiveGridTemplate(iconSize),
    gap: gridGap,
  };
}

function FolderGridRow({
  folder,
  collapsed,
  onToggleCollapse,
  onDelete,
  iconSize,
  onDropOnFolder,
  onDeleteDoc,
  onMergeIntoFolder,
}: {
  folder: Folder;
  collapsed: boolean;
  onToggleCollapse: () => void;
  onDelete: () => void;
  iconSize: IconSize;
  onDropOnFolder: (folderId: string, item: DocumentDragItem) => void;
  onDeleteDoc: (doc: DocumentListDocument) => void;
  onMergeIntoFolder: (sources: DocumentListDocument[], target: DocumentListDocument) => void;
}) {
  const [{ isOver, canDrop }, dropRef] = useDrop<
    DocumentDragItem,
    void,
    { isOver: boolean; canDrop: boolean }
  >(() => ({
    accept: DND_DOCUMENT,
    canDrop: (item) => item.docs.some((d) => d.folderId !== folder.id),
    drop: (item) => onDropOnFolder(folder.id, item),
    collect: (m) => ({ isOver: m.isOver({ shallow: true }), canDrop: m.canDrop() }),
  }), [folder.id, onDropOnFolder]);

  const totalSize = folder.documents.reduce((acc, d) => acc + d.size, 0);
  const isTarget = isOver && canDrop;

  return (
    <div
      ref={dropRef as unknown as React.RefObject<HTMLDivElement>}
      className={
        'col-span-full rounded-md border border-offbase overflow-hidden bg-base ' +
        (isTarget ? 'ring-1 ring-accent' : '')
      }
    >
      <div className="flex items-center justify-between px-2 py-1 bg-offbase border-b border-offbase">
        <button
          type="button"
          onClick={onToggleCollapse}
          className="flex items-center gap-1.5 text-[12px] font-semibold text-foreground hover:text-accent transition-colors duration-200 ease-out"
          aria-expanded={!collapsed}
        >
          <FolderIcon className="w-3.5 h-3.5 text-accent" />
          {folder.name}
          <span className="text-[10px] font-normal text-muted ml-1">
            {folder.documents.length} • {formatDocumentSize(totalSize)}
          </span>
          <svg
            className={`w-3 h-3 transition-transform ${collapsed ? '-rotate-90' : ''}`}
            fill="none"
            stroke="currentColor"
            viewBox="0 0 24 24"
          >
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M19 9l-7 7-7-7" />
          </svg>
        </button>
        <Button
          onClick={onDelete}
          className="p-1 text-muted hover:text-accent hover:bg-base hover:scale-[1.02] rounded-md transition-all duration-200 ease-out"
          aria-label={`Delete ${folder.name}`}
        >
          <svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path
              strokeLinecap="round"
              strokeLinejoin="round"
              strokeWidth="2"
              d="M6 18L18 6M6 6l12 12"
            />
          </svg>
        </Button>
      </div>
      <Transition
        show={!collapsed}
        enter="transition-all duration-200 ease-out"
        enterFrom="opacity-0 max-h-0"
        enterTo="opacity-100 max-h-[2000px]"
        leave="transition-all duration-150 ease-in"
        leaveFrom="opacity-100 max-h-[2000px]"
        leaveTo="opacity-0 max-h-0"
      >
        <div
          className="grid p-2"
          style={gridStyle(iconSize)}
        >
          {folder.documents.map((doc) => (
            <DocumentTile
              key={`${doc.type}-${doc.id}`}
              doc={doc}
              iconSize={iconSize}
              onDelete={onDeleteDoc}
              onMergeIntoFolder={onMergeIntoFolder}
            />
          ))}
        </div>
      </Transition>
    </div>
  );
}

export function IconsView({
  folders,
  unfolderedDocs,
  iconSize,
  collapsedFolders,
  onToggleCollapse,
  onDeleteFolder,
  onDeleteDoc,
  onDropOnFolder,
  onMergeIntoFolder,
}: IconsViewProps) {
  const { setVisibleOrder, clear } = useDocumentSelection();

  useEffect(() => {
    const all: DocumentListDocument[] = [
      ...folders.flatMap((f) => f.documents),
      ...unfolderedDocs,
    ];
    setVisibleOrder(all);
  }, [folders, unfolderedDocs, setVisibleOrder]);

  const handleBackgroundClick: React.MouseEventHandler = (e) => {
    if ((e.target as HTMLElement).closest('[data-doc-tile]')) return;
    clear();
  };

  return (
    <div
      onClick={handleBackgroundClick}
      className="flex-1 min-h-0 overflow-y-auto p-3"
    >
      <div
        className="grid"
        style={gridStyle(iconSize)}
      >
        {folders.map((folder) => (
          <FolderGridRow
            key={folder.id}
            folder={folder}
            collapsed={collapsedFolders.has(folder.id)}
            onToggleCollapse={() => onToggleCollapse(folder.id)}
            onDelete={() => onDeleteFolder(folder.id)}
            iconSize={iconSize}
            onDropOnFolder={onDropOnFolder}
            onDeleteDoc={onDeleteDoc}
            onMergeIntoFolder={onMergeIntoFolder}
          />
        ))}
        {unfolderedDocs.map((doc) => (
          <DocumentTile
            key={`${doc.type}-${doc.id}`}
            doc={doc}
            iconSize={iconSize}
            onDelete={onDeleteDoc}
            onMergeIntoFolder={onMergeIntoFolder}
          />
        ))}
      </div>
    </div>
  );
}
