// Inspector — toggle in Tweaks. Hover any element to see its component path,
// click to copy. Reads React fiber via __reactFiber$<hash> on DOM nodes.

const INSPECTOR_SKIP = new Set(['Inspector', 'TweaksPanel']);
const INSPECTOR_WRAPPERS = new Set(['App', 'Phone']);

function _inspectorFiber(node) {
  if (!node) return null;
  for (const k in node) {
    if (k.charCodeAt(0) === 95 && k.indexOf('__reactFiber$') === 0) return node[k];
  }
  return null;
}

function _inspectorName(fiber) {
  const t = fiber && fiber.type;
  if (!t || typeof t === 'string') return null;
  return t.displayName || t.name || null;
}

function _inspectorBuildPath(node) {
  const start = _inspectorFiber(node);
  if (!start) return null;

  const stack = [];
  for (let f = start; f; f = f.return) {
    const n = _inspectorName(f);
    if (n) stack.push({ name: n, fiber: f });
  }
  if (!stack.length) return null;

  const chain = stack.reverse(); // root → leaf
  if (chain.some(c => INSPECTOR_SKIP.has(c.name))) return null;

  let trimmed = chain;
  const screenStart = chain.findIndex(c => /Screen$/.test(c.name) && c.name !== 'Screen');
  if (screenStart >= 0) {
    trimmed = chain.slice(screenStart);
  } else {
    let i = 0;
    while (i < chain.length && INSPECTOR_WRAPPERS.has(chain[i].name)) i++;
    trimmed = chain.slice(i);
  }
  if (!trimmed.length) return null;

  const parts = trimmed.map(c => {
    const parent = c.fiber.return;
    if (!parent) return c.name;
    let count = 0, mine = 0;
    for (let ch = parent.child; ch; ch = ch.sibling) {
      if (_inspectorName(ch) === c.name) {
        count++;
        if (ch === c.fiber) mine = count;
      }
    }
    return count > 1 ? `${c.name}[${mine}]` : c.name;
  });

  return parts.join(' › ');
}

function Inspector({ enabled, theme, onDisable }) {
  const [target, setTarget] = React.useState(null);
  const [copied, setCopied] = React.useState(false);
  const [mouseXY, setMouseXY] = React.useState({ x: 0, y: 0 });
  const copyTimer = React.useRef(0);

  React.useEffect(() => {
    if (!enabled) {
      setTarget(null);
      setCopied(false);
      return;
    }

    const onMove = (e) => {
      setMouseXY({ x: e.clientX, y: e.clientY });
      const el = document.elementFromPoint(e.clientX, e.clientY);
      if (!el) { setTarget(null); return; }
      const path = _inspectorBuildPath(el);
      if (!path) { setTarget(null); return; }
      setTarget({ rect: el.getBoundingClientRect(), path });
    };

    const block = (e) => {
      const el = document.elementFromPoint(e.clientX, e.clientY);
      const path = el ? _inspectorBuildPath(el) : null;
      if (!path) return;
      e.preventDefault();
      e.stopPropagation();
      if (e.type === 'click') {
        try { navigator.clipboard.writeText(path); } catch (_) {}
        setCopied(true);
        window.clearTimeout(copyTimer.current);
        copyTimer.current = window.setTimeout(() => setCopied(false), 900);
      }
    };

    const onKey = (e) => {
      if (e.key === 'Escape') { e.preventDefault(); onDisable && onDisable(); }
    };

    window.addEventListener('mousemove', onMove, true);
    window.addEventListener('mousedown', block, true);
    window.addEventListener('mouseup', block, true);
    window.addEventListener('click', block, true);
    window.addEventListener('keydown', onKey, true);
    return () => {
      window.removeEventListener('mousemove', onMove, true);
      window.removeEventListener('mousedown', block, true);
      window.removeEventListener('mouseup', block, true);
      window.removeEventListener('click', block, true);
      window.removeEventListener('keydown', onKey, true);
      window.clearTimeout(copyTimer.current);
    };
  }, [enabled, onDisable]);

  if (!enabled || !target) return null;

  const { rect, path } = target;
  const accent = theme.accentOverride;
  const tipX = Math.min(window.innerWidth - 16, mouseXY.x + 14);
  const tipY = Math.min(window.innerHeight - 16, mouseXY.y + 18);

  return (
    <div style={{ position: 'fixed', inset: 0, zIndex: 300, pointerEvents: 'none' }}>
      <div style={{
        position: 'fixed',
        left: rect.left - 2, top: rect.top - 2,
        width: rect.width + 4, height: rect.height + 4,
        border: `1.5px solid ${accent}`,
        borderRadius: 4,
        boxShadow: `0 0 0 4px ${accent}22`,
        transition: 'left 60ms ease, top 60ms ease, width 60ms ease, height 60ms ease',
        pointerEvents: 'none',
      }}/>
      <div style={{
        position: 'fixed', left: tipX, top: tipY,
        background: theme.surface,
        border: `0.5px solid ${theme.line2}`,
        borderRadius: 8,
        padding: '6px 10px',
        boxShadow: '0 8px 24px rgba(0,0,0,0.18)',
        fontFamily: FONTS.mono, fontSize: 11, color: theme.text,
        whiteSpace: 'nowrap',
        pointerEvents: 'none',
      }}>
        {copied && <span style={{ color: theme.positive || accent, marginRight: 6 }}>✓</span>}
        {path}
      </div>
    </div>
  );
}

Object.assign(window, { Inspector });
