"use client";
var __async = (__this, __arguments, generator) => {
  return new Promise((resolve, reject) => {
    var fulfilled = (value) => {
      try {
        step(generator.next(value));
      } catch (e) {
        reject(e);
      }
    };
    var rejected = (value) => {
      try {
        step(generator.throw(value));
      } catch (e) {
        reject(e);
      }
    };
    var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
    step((generator = generator.apply(__this, __arguments)).next());
  });
};
import Buffer2 from "buffer";
import processBrowser from "process/browser";
import console from "console-browserify";
var buffer = {
  Buffer: Buffer2
};
import { jsx, jsxs } from "react/jsx-runtime";
import { Checkbox } from "antd";
import { DropShadowFilter } from "pixi-filters";
import * as PIXI from "pixi.js";
import "pixi.js/unsafe-eval";
import { useEffect, useMemo, useRef, useState } from "react";
import "./blackboard.css";
import { colorForName, highlightColorForType } from "./color";
import { useBlackboardPreference } from "./store";
const itemFillAlpha = 0.4;
const highlightAlpha = 0.4;
const noop = () => {
};
const rectMarkForItem = (rect, name, ifHighlight, onPointOver, onPointerOut) => {
  const { left, top, width, height } = rect;
  const themeColor = ifHighlight ? highlightColorForType("element") : colorForName(name);
  const alpha = ifHighlight ? highlightAlpha : itemFillAlpha;
  const graphics = new PIXI.Graphics();
  graphics.beginFill(themeColor, alpha);
  graphics.lineStyle(1, themeColor, 1);
  graphics.drawRect(left, top, width, height);
  graphics.endFill();
  if (onPointOver && onPointerOut) {
    graphics.interactive = true;
    graphics.on("pointerover", onPointOver);
    graphics.on("pointerout", onPointerOut);
  }
  const dropShadowFilter = new DropShadowFilter({
    blur: 2,
    quality: 3,
    alpha: 0.4,
    offset: { x: 4, y: 4 },
    color: 3355443
  });
  graphics.filters = [dropShadowFilter];
  const nameFontSize = 18;
  const texts = new PIXI.Text(name, {
    fontSize: nameFontSize,
    fill: 0
  });
  texts.x = left;
  texts.y = Math.max(top - (nameFontSize + 4), 0);
  return [graphics, texts];
};
const Blackboard = (props) => {
  const highlightElements = props.highlightElements || [];
  const highlightIds = highlightElements.map((e) => e.id);
  const context = props.uiContext;
  const { size, screenshotBase64, screenshotBase64WithElementMarker } = context;
  const screenWidth = size.width;
  const screenHeight = size.height;
  const domRef = useRef(null);
  const app = useMemo(() => new PIXI.Application(), []);
  const [appInitialed, setAppInitialed] = useState(false);
  const highlightContainer = useMemo(() => new PIXI.Container(), []);
  const elementMarkContainer = useMemo(() => new PIXI.Container(), []);
  const [hoverElement, setHoverElement] = useState(null);
  const pixiBgRef = useRef();
  const { markerVisible, setMarkerVisible, elementsVisible, setTextsVisible } = useBlackboardPreference();
  const ifMarkerAvailable = !!screenshotBase64WithElementMarker;
  useEffect(() => {
    Promise.resolve(
      (() => __async(void 0, null, function* () {
        if (!domRef.current || !screenWidth) {
          return;
        }
        yield app.init({
          width: screenWidth,
          height: screenHeight,
          background: 16777215
        });
        const canvasEl = domRef.current;
        domRef.current.appendChild(app.canvas);
        const { clientWidth } = domRef.current.parentElement;
        const targetHeight = window.innerHeight * 0.5;
        const viewportRatio = clientWidth / targetHeight;
        if (screenWidth / screenHeight <= viewportRatio) {
          const ratio = targetHeight / screenHeight;
          canvasEl.style.width = `${Math.floor(screenWidth * ratio)}px`;
          canvasEl.style.height = `${Math.floor(screenHeight * ratio)}px`;
        }
        app.stage.addChild(highlightContainer);
        app.stage.addChild(elementMarkContainer);
        setAppInitialed(true);
      }))()
    );
    return () => {
      console.log("will destroy");
      try {
        app.destroy(true, { children: true, texture: true });
      } catch (e) {
        console.warn("destroy failed", e);
      }
    };
  }, [app, screenWidth, screenHeight]);
  useEffect(() => {
    if (!appInitialed) {
      return;
    }
    const img = new Image();
    img.onload = () => {
      if (!app.stage)
        return;
      const screenshotTexture = PIXI.Texture.from(img);
      const backgroundSprite = new PIXI.Sprite(screenshotTexture);
      backgroundSprite.x = 0;
      backgroundSprite.y = 0;
      backgroundSprite.width = screenWidth;
      backgroundSprite.height = screenHeight;
      app.stage.addChildAt(backgroundSprite, 0);
      if (ifMarkerAvailable) {
        const markerImg = new Image();
        markerImg.onload = () => {
          const markerTexture = PIXI.Texture.from(markerImg);
          const markerSprite = new PIXI.Sprite(markerTexture);
          markerSprite.x = 0;
          markerSprite.y = 0;
          markerSprite.width = screenWidth;
          markerSprite.height = screenHeight;
          app.stage.addChildAt(markerSprite, 1);
          pixiBgRef.current = markerSprite;
          markerSprite.visible = markerVisible;
        };
        markerImg.onerror = (e) => {
          console.error("load marker failed", e);
        };
        markerImg.src = screenshotBase64WithElementMarker;
      }
    };
    img.onerror = (e) => {
      console.error("load screenshot failed", e);
    };
    img.src = screenshotBase64;
  }, [app.stage, appInitialed]);
  const { highlightElementRects } = useMemo(() => {
    const highlightElementRects2 = [];
    highlightContainer.removeChildren();
    elementMarkContainer.removeChildren();
    context.content.forEach((element) => {
      const { rect, content, id } = element;
      const ifHighlight = highlightIds.includes(id) || (hoverElement == null ? void 0 : hoverElement.id) === id;
      if (ifHighlight) {
        const [graphics2] = rectMarkForItem(
          rect,
          content,
          ifHighlight,
          noop,
          noop
        );
        highlightContainer.addChild(graphics2);
      }
      const removeHover = () => {
        setHoverElement(null);
      };
      const [graphics] = rectMarkForItem(
        rect,
        content,
        ifHighlight,
        (props == null ? void 0 : props.disableInteraction) ? void 0 : () => {
          setHoverElement(element);
        },
        (props == null ? void 0 : props.disableInteraction) ? void 0 : removeHover
      );
      elementMarkContainer.addChild(graphics);
    });
    elementMarkContainer.visible = elementsVisible;
    return {
      highlightElementRects: highlightElementRects2
    };
  }, [
    app,
    appInitialed,
    highlightElements,
    context.content,
    hoverElement
    // bgVisible,
    // elementsVisible,
  ]);
  const onSetMarkerVisible = (e) => {
    setMarkerVisible(e.target.checked);
    if (pixiBgRef.current) {
      pixiBgRef.current.visible = e.target.checked;
    }
  };
  const onSetElementsVisible = (e) => {
    setTextsVisible(e.target.checked);
    elementMarkContainer.visible = e.target.checked;
  };
  let bottomTipA = null;
  if (highlightElementRects.length === 1) {
    bottomTipA = /* @__PURE__ */ jsx("div", { className: "bottom-tip", children: /* @__PURE__ */ jsxs("div", { className: "bottom-tip-item", children: [
      "Element: ",
      JSON.stringify(highlightElementRects[0])
    ] }) });
  } else if (highlightElementRects.length > 1) {
    bottomTipA = /* @__PURE__ */ jsx("div", { className: "bottom-tip", children: /* @__PURE__ */ jsxs("div", { className: "bottom-tip-item", children: [
      "Element: ",
      JSON.stringify(highlightElementRects)
    ] }) });
  }
  return /* @__PURE__ */ jsxs("div", { className: "blackboard", children: [
    /* @__PURE__ */ jsx(
      "div",
      {
        className: "blackboard-main-content",
        style: { width: "100%" },
        ref: domRef
      }
    ),
    /* @__PURE__ */ jsx(
      "div",
      {
        className: "blackboard-filter",
        style: { display: props.hideController ? "none" : "block" },
        children: /* @__PURE__ */ jsxs("div", { className: "overlay-control", children: [
          /* @__PURE__ */ jsx(
            Checkbox,
            {
              checked: markerVisible,
              onChange: onSetMarkerVisible,
              disabled: !ifMarkerAvailable,
              children: "Marker"
            }
          ),
          /* @__PURE__ */ jsx(Checkbox, { checked: elementsVisible, onChange: onSetElementsVisible, children: "Elements" })
        ] })
      }
    ),
    /* @__PURE__ */ jsx(
      "div",
      {
        className: "bottom-tip",
        style: { display: props.hideController ? "none" : "block" },
        children: bottomTipA
      }
    )
  ] });
};
var blackboard_default = Blackboard;
export {
  blackboard_default as default,
  rectMarkForItem
};
