/* Node component */
const { useRef, useEffect, useState, useCallback, useMemo } = React;

function NodeView({
  node, selected, isHostOfCollapsed, hasChildren, childCount, subtotal,
  onPointerDown, onClick, onDoubleClick, onDoubleClickNode, onTitleChange,
  onStartConnect, onToggleCollapse, onContextMenu,
  onSetStatus, onAddChild, onTidyChildren,
  onDuplicate, onDelete, onEdit, onToggleMenu,
}) {
  const [editing, setEditing] = useState(false);
  const titleRef = useRef(null);
  const clickTimer = useRef(null);

  useEffect(() => {
    if (editing && titleRef.current) {
      titleRef.current.focus();
      titleRef.current.select();
    }
  }, [editing]);

  // External rename requests (from the context menu's "Rename" item).
  useEffect(() => {
    const onStartEdit = (e) => {
      if (e.detail?.nodeId === node.id) setEditing(true);
    };
    window.addEventListener("tv:start-edit", onStartEdit);
    return () => window.removeEventListener("tv:start-edit", onStartEdit);
  }, [node.id]);

  const doneChecks = node.checks.filter(c => c.done).length;
  const totalChecks = node.checks.length;
  const hasValue = node.value !== null && node.value !== undefined && node.value !== "";
  const formatValue = (v) => {
    const n = Number(v);
    if (!isFinite(n)) return String(v);
    // tidy formatting: thousand separators, up to 2 decimals
    return n.toLocaleString(undefined, { maximumFractionDigits: 2 });
  };
  const valueDisplay = hasValue
    ? `${node.valueCurrency || "$"}${formatValue(node.value)}${node.valueSuffix || ""}`
    : null;
  const subtotalDisplay = (subtotal !== null && subtotal !== undefined)
    ? `${node.valueCurrency || "$"}${formatValue(subtotal)}${node.valueSuffix || ""}`
    : null;

  return (
    <div
      className={`node shape-${node.shape} ${selected ? 'selected' : ''} ${node.collapsed ? 'collapsed-host' : ''} ${hasValue ? 'has-value' : ''} ${node.status ? 'status-' + node.status : ''}`}
      data-id={node.id}
      data-childcount={childCount > 0 ? childCount : undefined}
      style={{ left: node.x, top: node.y }}
      onPointerDown={(e) => { if (!editing) onPointerDown(e, node.id); }}
      onClick={(e) => {
        e.stopPropagation();
        if (editing) return;
        // Delay the click action so a double-click can cancel it.
        if (clickTimer.current) clearTimeout(clickTimer.current);
        clickTimer.current = setTimeout(() => {
          clickTimer.current = null;
          onClick && onClick(node.id);
        }, 220);
      }}
      onDoubleClick={(e) => {
        e.stopPropagation();
        if (clickTimer.current) { clearTimeout(clickTimer.current); clickTimer.current = null; }
        setEditing(true);
        onDoubleClickNode && onDoubleClickNode(node.id);
      }}
      onContextMenu={(e) => { e.preventDefault(); e.stopPropagation(); onContextMenu(e, node.id); }}
    >
      {node.emoji && <span className="node-emoji">{node.emoji}</span>}
      {editing ? (
        node.shape === "card" ? (
          <textarea
            ref={titleRef}
            className="node-title-edit"
            defaultValue={node.title}
            rows={1}
            onBlur={(e) => { onTitleChange(node.id, e.target.value); setEditing(false); }}
            onKeyDown={(e) => {
              if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); e.target.blur(); }
              if (e.key === "Escape") { setEditing(false); }
            }}
            onPointerDown={(e) => e.stopPropagation()}
          />
        ) : (
          <input
            ref={titleRef}
            className="node-title-edit"
            defaultValue={node.title}
            onBlur={(e) => { onTitleChange(node.id, e.target.value); setEditing(false); }}
            onKeyDown={(e) => {
              if (e.key === "Enter") { e.target.blur(); }
              if (e.key === "Escape") { setEditing(false); }
            }}
            onPointerDown={(e) => e.stopPropagation()}
          />
        )
      ) : (
        <div className="node-title">{node.title || <span style={{color:'var(--muted)'}}>Untitled</span>}</div>
      )}

      {node.shape === "card" && totalChecks > 0 && (
        <div className="node-checks">
          <Icon name="check" size={11} />
          <span>{doneChecks}/{totalChecks}</span>
        </div>
      )}
      {valueDisplay && node.shape !== "card" && (
        <div className="node-value-inline">{valueDisplay}</div>
      )}
      {!valueDisplay && subtotalDisplay && node.shape !== "card" && (
        <div className="node-value-inline subtotal" title="Sum of all descendant values">Σ {subtotalDisplay}</div>
      )}
      {valueDisplay && node.shape === "card" && (
        <div className="node-value-card">{valueDisplay}</div>
      )}
      {!valueDisplay && subtotalDisplay && node.shape === "card" && (
        <div className="node-value-card subtotal" title="Sum of all descendant values">Σ {subtotalDisplay}</div>
      )}
      {/* Hover action buttons — appear above the node, side-by-side */}
      <div className="node-actions">
        <button className="node-action" title="Add child"
          onPointerDown={(e) => e.stopPropagation()}
          onClick={(e) => { e.stopPropagation(); onAddChild && onAddChild(node.id); }}>
          <Icon name="plus" size={12} />
        </button>
        <button className="node-action" title="More"
          onPointerDown={(e) => e.stopPropagation()}
          onClick={(e) => { e.stopPropagation(); onToggleMenu && onToggleMenu(node.id); }}>
          <Icon name="menu" size={12} />
        </button>
        {hasChildren && (
          <button className="node-action" title="Tidy children"
            onPointerDown={(e) => e.stopPropagation()}
            onClick={(e) => { e.stopPropagation(); onTidyChildren && onTidyChildren(node.id); }}>
            <Icon name="fit" size={11} />
          </button>
        )}
        {["red", "yellow", "green"].map(color => (
          <button
            key={color}
            className={`node-action color color-${color} ${node.status === color ? 'active' : ''}`}
            title={node.status === color ? `Clear ${color}` : `Fill ${color}`}
            onPointerDown={(e) => e.stopPropagation()}
            onClick={(e) => {
              e.stopPropagation();
              onSetStatus && onSetStatus(node.id, node.status === color ? null : color);
            }}
          />
        ))}
        <button className="node-action danger" title="Delete"
          onPointerDown={(e) => e.stopPropagation()}
          onClick={(e) => { e.stopPropagation(); onDelete && onDelete(node.id); }}>
          <Icon name="trash" size={11} />
        </button>
      </div>

      {/* Connection handle (drag from here to create an edge) */}
      <div
        className="node-handle"
        title="Drag to connect"
        onPointerDown={(e) => { e.stopPropagation(); onStartConnect(e, node.id); }}
      />

      {/* Collapse toggle, only when has children */}
      {hasChildren && (
        <button
          className="node-collapse"
          title={node.collapsed ? "Expand" : "Collapse"}
          onPointerDown={(e) => e.stopPropagation()}
          onClick={(e) => { e.stopPropagation(); onToggleCollapse(node.id); }}
        >
          {node.collapsed ? "+" : "–"}
        </button>
      )}
    </div>
  );
}

window.NodeView = NodeView;
