import React, { useCallback, useEffect, useRef } from 'react';
import { createPortal } from 'react-dom';
import { useEditor, useNode } from '@craftjs/core';

interface RenderNodeProps {
  render: React.ReactElement;
}

/**
 * Craft.js `<Editor onRender>` override -- wraps every node's render output.
 * For the currently-selected node it portals a floating badge (component
 * displayName + a "select parent" chevron) positioned over the node's real
 * DOM element. Non-selected nodes (the overwhelming majority) and ROOT pass
 * straight through as a Fragment, so this never touches layout, never
 * appears in `toHtml` export (that walks the Craft node tree, not this
 * portal), and doesn't wrap every node in extra DOM.
 *
 * It also imperatively tags each node's real DOM element with two
 * editor-only data attributes (never part of `toHtml` export, which walks
 * the Craft node tree, not the live DOM):
 *  - `data-craft-node`: set on actual Craft.js droppable containers
 *    (`node.data.isCanvas`, excluding ROOT). `editor.css`'s dashed "guide"
 *    outlines target this attribute instead of blanket tag selectors
 *    (div/section/header/...), so a component's own internal wrapper markup
 *    no longer picks up a guide outline it isn't a real drop target for.
 *  - `data-craft-hovered`: mirrors `node.events.hovered` (Craft's hover
 *    event set). Craft's own `connectors.connect()` (called by every
 *    component) wires a native mouseover/mouseleave listener to this event
 *    internally, so a plain mouse hover over any connected node sets it --
 *    this attribute is a real-mouse-hover canvas highlight. (The Layers
 *    panel's row-hover -> canvas-highlight sync, item 12, uses a sibling
 *    `data-layer-hovered` attribute written directly by LayersPanel.tsx
 *    instead of this event, since the action that would drive it here
 *    -- `actions.setNodeEvent` -- is stripped from the public `useEditor()`
 *    API at runtime.) editor.css matches both attributes for the same
 *    outline and suppresses both under `.guides-off`.
 */
export const RenderNode: React.FC<RenderNodeProps> = ({ render }) => {
  const { actions } = useEditor();
  const { id, isSelected, dom, name, parent, isCanvas, isHovered } = useNode((node) => ({
    isSelected: node.events.selected,
    isHovered: node.events.hovered,
    dom: node.dom,
    name: (node.data.props?.aiName as string) || node.data.displayName,
    parent: node.data.parent,
    isCanvas: node.data.isCanvas,
  }));

  const badgeRef = useRef<HTMLDivElement>(null);
  const active = isSelected && id !== 'ROOT' && !!dom;

  const updatePosition = useCallback(() => {
    if (!dom || !badgeRef.current) return;
    const rect = dom.getBoundingClientRect();
    const badgeHeight = 22;
    badgeRef.current.style.left = `${Math.max(rect.left, 0)}px`;
    badgeRef.current.style.top = `${Math.max(rect.top - badgeHeight, 0)}px`;
  }, [dom]);

  useEffect(() => {
    if (!active) return;
    updatePosition();
    window.addEventListener('resize', updatePosition);
    document.addEventListener('scroll', updatePosition, true);
    return () => {
      window.removeEventListener('resize', updatePosition);
      document.removeEventListener('scroll', updatePosition, true);
    };
  }, [active, updatePosition]);

  useEffect(() => {
    if (!dom) return;
    if (isCanvas && id !== 'ROOT') {
      dom.setAttribute('data-craft-node', '');
    } else {
      dom.removeAttribute('data-craft-node');
    }
  }, [dom, isCanvas, id]);

  useEffect(() => {
    if (!dom) return;
    if (isHovered) {
      dom.setAttribute('data-craft-hovered', '');
    } else {
      dom.removeAttribute('data-craft-hovered');
    }
  }, [dom, isHovered]);

  if (!active) return <>{render}</>;

  return (
    <>
      {render}
      {createPortal(
        <div ref={badgeRef} className="component-indicator" style={{ position: 'fixed' }}>
          <span>{name}</span>
          {parent && (
            <button
              type="button"
              className="component-indicator-parent-btn"
              title="Select parent"
              aria-label={`Select parent of ${name}`}
              onMouseDown={(e) => {
                e.stopPropagation();
                actions.selectNode(parent);
              }}
            >
              <i className="fa fa-chevron-up" aria-hidden />
            </button>
          )}
        </div>,
        document.body
      )}
    </>
  );
};
