import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.95.0/helpers/decorate.js";
import { panZoomTransformContext } from "../../gui/panZoomTransformContext.js";
import { selectionContext } from "../selection/selectionContext.js";
import { calculateOverlayState, getOverlayTargets } from "./overlayState.js";
import { consume } from "@lit/context";
import { LitElement, css, html } from "lit";
import { customElement, property, state } from "lit/decorators.js";

//#region src/canvas/overlays/SelectionOverlay.ts
let SelectionOverlay = class SelectionOverlay$1 extends LitElement {
	constructor(..._args) {
		super(..._args);
		this.canvasElement = null;
		this.overlayState = {
			selection: null,
			boxSelect: null,
			highlight: null
		};
		this.lastSelectionMode = null;
		this.paused = false;
		this.rafLoopActive = false;
		this.rafLoop = () => {
			if (!this.rafLoopActive) return;
			if (!this.paused) this.updateOverlayData();
			this.animationFrame = requestAnimationFrame(this.rafLoop);
		};
	}
	static {
		this.styles = [css`
      :host {
        position: fixed;
        top: 0;
        left: 0;
        width: 100vw;
        height: 100vh;
        pointer-events: none;
        z-index: 1000;
      }
      .box-select {
        position: absolute;
        border: 2px dashed rgb(59, 130, 246);
        background: rgba(59, 130, 246, 0.05);
        pointer-events: none;
      }
      .highlight-box {
        position: absolute;
        border: 2px solid rgb(148, 163, 184);
        background: rgba(148, 163, 184, 0.1);
        pointer-events: none;
        box-shadow: 0 0 0 2px rgba(148, 163, 184, 0.3);
      }
    `];
	}
	createRenderRoot() {
		return this;
	}
	firstUpdated(changedProperties) {
		super.firstUpdated?.(changedProperties);
	}
	connectedCallback() {
		super.connectedCallback();
		this.style.position = "fixed";
		this.style.top = "0";
		this.style.left = "0";
		this.style.width = "100vw";
		this.style.height = "100vh";
		this.style.pointerEvents = "none";
		this.style.zIndex = "1000";
		this.setAttribute("data-selection-overlay", "true");
		requestAnimationFrame(() => {
			if (this.canvas) this.canvasElement = this.canvas;
			else this.findCanvasElement();
			if (this.canvasElement) this.startRafLoop();
		});
	}
	disconnectedCallback() {
		super.disconnectedCallback();
		this.stopRafLoop();
	}
	/**
	* React to selection context changes to ensure box selection visual updates.
	* This is called whenever Lit detects a property change, including context updates.
	* Note: We don't call requestUpdate() here to avoid the Lit warning about scheduling
	* updates after an update completes. The RAF loop handles all updates.
	*/
	updated(changedProperties) {
		super.updated?.(changedProperties);
		const currentMode = this.effectiveSelection?.selectionMode ?? null;
		if (currentMode !== this.lastSelectionMode) this.lastSelectionMode = currentMode;
		if (currentMode === "box-selecting" && !this.rafLoopActive) this.startRafLoop();
		if (changedProperties.has("canvas") && this.canvas) {
			this.canvasElement = this.canvas;
			if (!this.rafLoopActive) this.startRafLoop();
		}
		if (this.canvasElement && !this.rafLoopActive) this.startRafLoop();
		if (changedProperties.has("paused") && !this.paused) this.updateOverlayData();
	}
	/**
	* Find the EFCanvas element.
	* Handles both cases:
	* 1. Overlay is inside EFCanvas's shadow DOM (old case)
	* 2. Overlay is a sibling of ef-pan-zoom (new case - outside transform)
	*/
	findCanvasElement() {
		const parent = this.parentElement;
		if (parent) {
			const panZoom$1 = parent.querySelector("ef-pan-zoom");
			if (panZoom$1) {
				const canvas = panZoom$1.querySelector("ef-canvas");
				if (canvas) {
					this.canvasElement = canvas;
					return;
				}
			}
		}
		const panZoom = this.closest("ef-pan-zoom");
		if (panZoom) {
			const canvas = panZoom.querySelector("ef-canvas");
			if (canvas) {
				this.canvasElement = canvas;
				return;
			}
		}
		let current = this;
		while (current) if (current instanceof ShadowRoot) current = current.host;
		else if (current instanceof HTMLElement) {
			if (current.tagName === "EF-CANVAS" || current.tagName.toLowerCase() === "ef-canvas") {
				this.canvasElement = current;
				return;
			}
			const rootNode = current.getRootNode();
			if (rootNode instanceof ShadowRoot) current = rootNode.host;
			else current = current.parentElement;
		} else {
			const rootNode = current.getRootNode();
			if (rootNode instanceof ShadowRoot) current = rootNode.host;
			else current = current.parentElement;
		}
	}
	/**
	* Start continuous RAF loop for smooth overlay updates.
	*/
	startRafLoop() {
		if (this.rafLoopActive) return;
		this.rafLoopActive = true;
		this.rafLoop();
	}
	/**
	* Stop RAF loop.
	*/
	stopRafLoop() {
		this.rafLoopActive = false;
		if (this.animationFrame) {
			cancelAnimationFrame(this.animationFrame);
			this.animationFrame = void 0;
		}
	}
	/**
	* Get the effective selection context (from context or property).
	*/
	get effectiveSelection() {
		return this.selectionFromContext ?? this.selection;
	}
	/**
	* Get the effective pan-zoom transform (from context or property).
	*/
	get effectivePanZoomTransform() {
		return this.panZoomTransformFromContext ?? this.panZoomTransform;
	}
	/**
	* Update overlay data state using the abstraction layer.
	*
	* This method now uses the clean separation of:
	* - SEMANTICS: getOverlayTargets() determines WHAT should be shown
	* - MECHANISM: calculateOverlayState() determines HOW to show it
	*/
	updateOverlayData() {
		if (this.canvas && this.canvas !== this.canvasElement) this.canvasElement = this.canvas;
		const effectiveCanvas = this.canvasElement || this.canvas;
		if (!effectiveCanvas) {
			this.overlayState = {
				selection: null,
				boxSelect: null,
				highlight: null
			};
			return;
		}
		let canvasRect = effectiveCanvas.getBoundingClientRect();
		if (effectiveCanvas.shadowRoot) {
			const canvasContent = effectiveCanvas.shadowRoot.querySelector(".canvas-content");
			if (canvasContent) canvasRect = canvasContent.getBoundingClientRect();
		}
		const panZoomElement = effectiveCanvas.closest("ef-pan-zoom");
		const canvas = effectiveCanvas;
		const highlightedElement = canvas?.highlightedElement;
		const targets = getOverlayTargets(this.effectiveSelection, highlightedElement);
		const canvasWithMetadata = {
			getElementData: (id) => canvas?.getElementData?.(id),
			getElement: (id) => canvas?.elementRegistry?.get(id),
			querySelector: (selector) => effectiveCanvas.querySelector(selector),
			shadowRoot: effectiveCanvas.shadowRoot
		};
		const currentTransform = this.readCurrentTransform(panZoomElement);
		this.overlayState = calculateOverlayState(targets, canvasWithMetadata, canvasRect, panZoomElement, currentTransform);
	}
	/**
	* Read current transform directly from panzoom element.
	* This ensures we always have fresh values instead of stale property/context.
	*/
	readCurrentTransform(panZoomElement) {
		if (panZoomElement) {
			const pz = panZoomElement;
			if (typeof pz.x === "number" && typeof pz.y === "number" && typeof pz.scale === "number") return {
				x: pz.x,
				y: pz.y,
				scale: pz.scale
			};
		}
		return this.effectivePanZoomTransform;
	}
	render() {
		if (!(this.canvasElement || this.canvas)) return html``;
		const { boxSelect, highlight } = this.overlayState;
		return html`
      ${boxSelect ? html`
            <div
              class="box-select"
              style="left: ${boxSelect.x}px; top: ${boxSelect.y}px; width: ${boxSelect.width}px; height: ${boxSelect.height}px; position: absolute; border: 2px dashed rgb(59, 130, 246); background: rgba(59, 130, 246, 0.05); pointer-events: none;"
            ></div>
          ` : html``}
      ${highlight ? html`
            <div
              class="highlight-box"
              style="left: ${highlight.x}px; top: ${highlight.y}px; width: ${highlight.width}px; height: ${highlight.height}px; position: absolute; border: 2px solid rgb(148, 163, 184); background: rgba(148, 163, 184, 0.1); pointer-events: none; box-shadow: 0 0 0 2px rgba(148, 163, 184, 0.3);"
            ></div>
          ` : html``}
    `;
	}
};
__decorate([consume({
	context: selectionContext,
	subscribe: true
})], SelectionOverlay.prototype, "selectionFromContext", void 0);
__decorate([consume({
	context: panZoomTransformContext,
	subscribe: true
})], SelectionOverlay.prototype, "panZoomTransformFromContext", void 0);
__decorate([property({ type: Object })], SelectionOverlay.prototype, "selection", void 0);
__decorate([property({ type: Object })], SelectionOverlay.prototype, "panZoomTransform", void 0);
__decorate([state()], SelectionOverlay.prototype, "canvasElement", void 0);
__decorate([property({ type: Object })], SelectionOverlay.prototype, "canvas", void 0);
__decorate([state()], SelectionOverlay.prototype, "overlayState", void 0);
__decorate([state()], SelectionOverlay.prototype, "lastSelectionMode", void 0);
__decorate([property({ type: Boolean })], SelectionOverlay.prototype, "paused", void 0);
SelectionOverlay = __decorate([customElement("ef-canvas-selection-overlay")], SelectionOverlay);

//#endregion
//# sourceMappingURL=SelectionOverlay.js.map