/**
 * Fabric crash killer (controls).
 *
 * Symptom:
 *  - After canvas.loadFromJSON + first selection, Fabric crashes in drawControls:
 *      Cannot read properties of undefined (reading 'x')
 *    Stack goes through InteractiveObject.forEachControl.
 *
 * Root cause (most common):
 *  - `object.controls` contains enumerable keys that resolve to `undefined`.
 *    This can happen via prototype pollution / inherited enumerable props / bad rehydration.
 *
 * Fix:
 *  - Patch InteractiveObject.prototype.forEachControl to iterate only over OWN keys and
 *    skip invalid entries.
 *
 * This file is imported from src/main.tsx to guarantee it runs before any canvas exists.
 */

import { fabric } from './fabric';

function installCrashKiller(fab: any) {
  const proto = fab?.InteractiveObject?.prototype;
  if (!proto) return { installed: false, reason: 'No InteractiveObject.prototype' };
  if (proto.__ASUKA_CONTROLS_CRASH_KILLER__) {
    return { installed: false, reason: 'Already installed' };
  }

  const original = proto.forEachControl;

  proto.forEachControl = function forEachControlSafe(fn: any) {
    const controls = (this as any)?.controls;

    // Prefer safe path: own enumerable keys only.
    if (controls && typeof controls === 'object') {
      const keys = Object.keys(controls);
      for (const key of keys) {
        const control = (controls as any)[key];
        if (!control || typeof control !== 'object') continue;
        fn(control, key, this);
      }
      return;
    }

    // Fallback to Fabric behavior if controls missing.
    return original?.call(this, fn);
  };

  proto.__ASUKA_CONTROLS_CRASH_KILLER__ = true;
  proto.forEachControl.__ASUKA_CONTROLS_CRASH_KILLER__ = true;

  return { installed: true, version: fab?.version };
}

try {
  installCrashKiller(fabric);
} catch {}
