import { useState } from 'react';
import { Icon } from '@iconify/react';
import type { ObjectTreeNode } from '@tts/extract';
import { iconsForObject } from './objectIcons';

interface Props {
  nodes: ObjectTreeNode[];
  selectedPath: string | null;
  onSelect: (path: string) => void;
}

export default function ObjectTree({ nodes, selectedPath, onSelect }: Props) {
  return (
    <ul className="space-y-0.5">
      {nodes.map((node, index) => (
        <TreeNode
          key={index}
          node={node}
          depth={0}
          path={`${index}`}
          selectedPath={selectedPath}
          onSelect={onSelect}
        />
      ))}
    </ul>
  );
}

function TreeNode({
  node,
  depth,
  path,
  selectedPath,
  onSelect,
}: {
  node: ObjectTreeNode;
  depth: number;
  /** Index path from the root, used as a stable unique key and selection id. */
  path: string;
  selectedPath: string | null;
  onSelect: (path: string) => void;
}) {
  // Selection is keyed by the node's unique index path, not its GUID: cards in
  // a deck frequently share a GUID (the deck's), so GUID-based selection would
  // highlight and render the wrong card.
  const selected = path === selectedPath;
  const hasChildren = node.children.length > 0;
  const [expanded, setExpanded] = useState(false);
  return (
    <li>
      <div
        className={`flex items-center rounded pr-2 ${
          selected
            ? 'bg-zinc-700 text-zinc-100'
            : 'text-zinc-300 hover:bg-zinc-800 hover:text-zinc-100'
        }`}
        style={{ paddingLeft: `${depth * 16 + 4}px` }}
      >
        {hasChildren ? (
          <button
            onClick={() => setExpanded((e) => !e)}
            aria-label={expanded ? 'Collapse' : 'Expand'}
            className="flex h-6 w-6 shrink-0 items-center justify-center rounded text-zinc-500 hover:text-zinc-200"
          >
            <span
              className={`inline-block text-xs transition-transform ${expanded ? 'rotate-90' : ''}`}
            >
              ▸
            </span>
          </button>
        ) : (
          <span className="h-6 w-6 shrink-0" />
        )}
        <button
          onClick={() => onSelect(path)}
          className="block min-w-0 flex-1 truncate py-1 text-left text-sm"
        >
          <span
            title={node.object.Name}
            className="mr-1.5 inline-flex items-center gap-0.5 align-middle text-zinc-400"
          >
            {iconsForObject(node.object.Name).map((icon) => (
              <Icon key={icon} icon={icon} className="h-4 w-4" />
            ))}
          </span>
          <span className="truncate">{node.label}</span>
        </button>
      </div>
      {hasChildren && expanded && (
        <ul>
          {node.children.map((child, index) => (
            <TreeNode
              key={`${path}-${index}`}
              node={child}
              depth={depth + 1}
              path={`${path}-${index}`}
              selectedPath={selectedPath}
              onSelect={onSelect}
            />
          ))}
        </ul>
      )}
    </li>
  );
}