/**
 * Shared guided-tour engine for shadow-DOM rApp components.
 *
 * Designed to survive full innerHTML replacement — call `renderOverlay()`
 * at the end of each render cycle to re-inject the tour UI.
 */

export interface TourStep {
	target: string;          // CSS selector within shadow root
	title: string;
	message: string;
	advanceOnClick?: boolean; // auto-advance when target is clicked
}

export class TourEngine {
	private shadowRoot: ShadowRoot;
	private steps: TourStep[];
	private storageKey: string;
	private getContainer: () => HTMLElement | null;

	private _active = false;
	private _step = 0;
	private _clickHandler: (() => void) | null = null;
	private _clickTarget: HTMLElement | null = null;

	get isActive() { return this._active; }

	constructor(
		shadowRoot: ShadowRoot,
		steps: TourStep[],
		storageKey: string,
		getContainer: () => HTMLElement | null,
	) {
		this.shadowRoot = shadowRoot;
		this.steps = steps;
		this.storageKey = storageKey;
		this.getContainer = getContainer;
	}

	/** Start (or restart) the tour from step 0. Disabled — tours are turned off. */
	start() {
		return;
	}

	/** Advance to next step or finish if at the end. */
	advance() {
		this._detachClickHandler();
		this._step++;
		if (this._step >= this.steps.length) {
			this.end();
		} else {
			this.renderOverlay();
		}
	}

	/** End the tour and remove the overlay. */
	end() {
		this._detachClickHandler();
		this._active = false;
		this._step = 0;
		localStorage.setItem(this.storageKey, "1");
		this.shadowRoot.getElementById("rspace-tour-overlay")?.remove();
	}

	/**
	 * Re-inject / update the tour overlay.
	 * Call this at the end of every host render() so the overlay survives
	 * full innerHTML replacement.  Safe to call when tour is inactive (no-op).
	 */
	renderOverlay() {
		if (!this._active) return;

		// Ensure styles exist
		this._ensureStyles();

		// Skip steps whose target doesn't exist (e.g. mic button when unsupported)
		const step = this.steps[this._step];
		const targetEl = this.shadowRoot.querySelector(step.target) as HTMLElement | null;
		if (!targetEl && this._step < this.steps.length - 1) {
			this._step++;
			this.renderOverlay();
			return;
		}

		// Get or create overlay element
		let overlay = this.shadowRoot.getElementById("rspace-tour-overlay");
		if (!overlay) {
			overlay = document.createElement("div");
			overlay.id = "rspace-tour-overlay";
			overlay.className = "rspace-tour-overlay";
			const container = this.getContainer();
			if (container) container.appendChild(overlay);
			else this.shadowRoot.appendChild(overlay);
		}

		// Compute spotlight position relative to container
		let spotX = 0, spotY = 0, spotW = 120, spotH = 40;
		if (targetEl) {
			const container = this.getContainer() || this.shadowRoot.host as HTMLElement;
			const containerRect = container.getBoundingClientRect();
			const rect = targetEl.getBoundingClientRect();
			spotX = rect.left - containerRect.left - 6;
			spotY = rect.top - containerRect.top - 6;
			spotW = rect.width + 12;
			spotH = rect.height + 12;
		}

		const isLast = this._step >= this.steps.length - 1;
		const stepNum = this._step + 1;
		const totalSteps = this.steps.length;

		// Position tooltip below target, clamped within container
		const tooltipTop = spotY + spotH + 12;
		const tooltipLeft = Math.max(8, spotX);

		overlay.innerHTML = `
			<div class="rspace-tour-backdrop" style="clip-path: polygon(
				0% 0%, 0% 100%, ${spotX}px 100%, ${spotX}px ${spotY}px,
				${spotX + spotW}px ${spotY}px, ${spotX + spotW}px ${spotY + spotH}px,
				${spotX}px ${spotY + spotH}px, ${spotX}px 100%, 100% 100%, 100% 0%
			)"></div>
			<div class="rspace-tour-spotlight" style="left:${spotX}px;top:${spotY}px;width:${spotW}px;height:${spotH}px"></div>
			<div class="rspace-tour-tooltip" style="top:${tooltipTop}px;left:${tooltipLeft}px">
				<div class="rspace-tour-tooltip__step">${stepNum} / ${totalSteps}</div>
				<div class="rspace-tour-tooltip__title">${step.title}</div>
				<div class="rspace-tour-tooltip__msg">${step.message}</div>
				<div class="rspace-tour-tooltip__nav">
					${this._step > 0 ? '<button class="rspace-tour-tooltip__btn rspace-tour-tooltip__btn--prev" data-tour="prev">Back</button>' : ''}
					${step.advanceOnClick
						? `<span class="rspace-tour-tooltip__hint">or click the button above</span>`
						: `<button class="rspace-tour-tooltip__btn rspace-tour-tooltip__btn--next" data-tour="next">${isLast ? 'Finish' : 'Next'}</button>`
					}
					<button class="rspace-tour-tooltip__btn rspace-tour-tooltip__btn--skip" data-tour="skip">Skip</button>
				</div>
			</div>
		`;

		// Wire tour navigation buttons
		overlay.querySelectorAll("[data-tour]").forEach(btn => {
			btn.addEventListener("click", (e) => {
				e.stopPropagation();
				const action = (btn as HTMLElement).dataset.tour;
				if (action === "next") this.advance();
				else if (action === "prev") {
					this._detachClickHandler();
					this._step = Math.max(0, this._step - 1);
					this.renderOverlay();
				}
				else if (action === "skip") this.end();
			});
		});

		// For advanceOnClick steps, attach listener on the target
		this._detachClickHandler();
		if (step.advanceOnClick && targetEl) {
			this._clickHandler = () => {
				this._detachClickHandler();
				setTimeout(() => this.advance(), 300);
			};
			this._clickTarget = targetEl;
			targetEl.addEventListener("click", this._clickHandler);
		}
	}

	/** Remove the click-to-advance listener from the previous target. */
	private _detachClickHandler() {
		if (this._clickHandler && this._clickTarget) {
			this._clickTarget.removeEventListener("click", this._clickHandler);
		}
		this._clickHandler = null;
		this._clickTarget = null;
	}

	/** Inject the shared tour CSS once into the shadow root. */
	private _ensureStyles() {
		if (this.shadowRoot.querySelector("[data-tour-styles]")) return;
		const style = document.createElement("style");
		style.setAttribute("data-tour-styles", "");
		style.textContent = TOUR_CSS;
		this.shadowRoot.appendChild(style);
	}
}

/**
 * LightTourEngine — tour engine for non-shadow-DOM components.
 * Uses a container element instead of ShadowRoot, injects CSS into document.head.
 */
export class LightTourEngine {
	private container: HTMLElement;
	private steps: TourStep[];
	private storageKey: string;

	private _active = false;
	private _step = 0;
	private _clickHandler: (() => void) | null = null;
	private _clickTarget: HTMLElement | null = null;

	get isActive() { return this._active; }

	constructor(container: HTMLElement, steps: TourStep[], storageKey: string) {
		this.container = container;
		this.steps = steps;
		this.storageKey = storageKey;
	}

	/** Disabled — tours are turned off. */
	start() {
		return;
	}

	advance() {
		this._detachClickHandler();
		this._step++;
		if (this._step >= this.steps.length) {
			this.end();
		} else {
			this.renderOverlay();
		}
	}

	end() {
		this._detachClickHandler();
		this._active = false;
		this._step = 0;
		localStorage.setItem(this.storageKey, "1");
		this.container.querySelector("#rspace-tour-overlay")?.remove();
	}

	renderOverlay() {
		if (!this._active) return;
		this._ensureStyles();

		const step = this.steps[this._step];
		const targetEl = this.container.querySelector(step.target) as HTMLElement | null;
		if (!targetEl && this._step < this.steps.length - 1) {
			this._step++;
			this.renderOverlay();
			return;
		}

		let overlay = this.container.querySelector("#rspace-tour-overlay") as HTMLElement | null;
		if (!overlay) {
			overlay = document.createElement("div");
			overlay.id = "rspace-tour-overlay";
			overlay.className = "rspace-tour-overlay";
			this.container.appendChild(overlay);
		}

		let spotX = 0, spotY = 0, spotW = 120, spotH = 40;
		if (targetEl) {
			const containerRect = this.container.getBoundingClientRect();
			const rect = targetEl.getBoundingClientRect();
			spotX = rect.left - containerRect.left - 6;
			spotY = rect.top - containerRect.top - 6;
			spotW = rect.width + 12;
			spotH = rect.height + 12;
		}

		const isLast = this._step >= this.steps.length - 1;
		const stepNum = this._step + 1;
		const totalSteps = this.steps.length;
		const tooltipTop = spotY + spotH + 12;
		const tooltipLeft = Math.max(8, spotX);

		overlay.innerHTML = `
			<div class="rspace-tour-backdrop" style="clip-path: polygon(
				0% 0%, 0% 100%, ${spotX}px 100%, ${spotX}px ${spotY}px,
				${spotX + spotW}px ${spotY}px, ${spotX + spotW}px ${spotY + spotH}px,
				${spotX}px ${spotY + spotH}px, ${spotX}px 100%, 100% 100%, 100% 0%
			)"></div>
			<div class="rspace-tour-spotlight" style="left:${spotX}px;top:${spotY}px;width:${spotW}px;height:${spotH}px"></div>
			<div class="rspace-tour-tooltip" style="top:${tooltipTop}px;left:${tooltipLeft}px">
				<div class="rspace-tour-tooltip__step">${stepNum} / ${totalSteps}</div>
				<div class="rspace-tour-tooltip__title">${step.title}</div>
				<div class="rspace-tour-tooltip__msg">${step.message}</div>
				<div class="rspace-tour-tooltip__nav">
					${this._step > 0 ? '<button class="rspace-tour-tooltip__btn rspace-tour-tooltip__btn--prev" data-tour="prev">Back</button>' : ''}
					${step.advanceOnClick
						? `<span class="rspace-tour-tooltip__hint">or click the button above</span>`
						: `<button class="rspace-tour-tooltip__btn rspace-tour-tooltip__btn--next" data-tour="next">${isLast ? 'Finish' : 'Next'}</button>`
					}
					<button class="rspace-tour-tooltip__btn rspace-tour-tooltip__btn--skip" data-tour="skip">Skip</button>
				</div>
			</div>
		`;

		overlay.querySelectorAll("[data-tour]").forEach(btn => {
			btn.addEventListener("click", (e) => {
				e.stopPropagation();
				const action = (btn as HTMLElement).dataset.tour;
				if (action === "next") this.advance();
				else if (action === "prev") {
					this._detachClickHandler();
					this._step = Math.max(0, this._step - 1);
					this.renderOverlay();
				}
				else if (action === "skip") this.end();
			});
		});

		this._detachClickHandler();
		if (step.advanceOnClick && targetEl) {
			this._clickHandler = () => {
				this._detachClickHandler();
				setTimeout(() => this.advance(), 300);
			};
			this._clickTarget = targetEl;
			targetEl.addEventListener("click", this._clickHandler);
		}
	}

	private _detachClickHandler() {
		if (this._clickHandler && this._clickTarget) {
			this._clickTarget.removeEventListener("click", this._clickHandler);
		}
		this._clickHandler = null;
		this._clickTarget = null;
	}

	private _ensureStyles() {
		if (document.head.querySelector("[data-light-tour-styles]")) return;
		const style = document.createElement("style");
		style.setAttribute("data-light-tour-styles", "");
		style.textContent = TOUR_CSS;
		document.head.appendChild(style);
	}
}

const TOUR_CSS = `
.rspace-tour-overlay {
	position: absolute; inset: 0; z-index: 10000;
	pointer-events: none;
}
.rspace-tour-backdrop {
	position: absolute; inset: 0;
	background: rgba(0, 0, 0, 0.55);
	pointer-events: auto;
	transition: clip-path 0.3s ease;
}
.rspace-tour-spotlight {
	position: absolute;
	border: 2px solid var(--rs-primary, #06b6d4);
	border-radius: 8px;
	box-shadow: 0 0 0 4px rgba(6, 182, 212, 0.25);
	pointer-events: none;
	transition: all 0.3s ease;
}
.rspace-tour-tooltip {
	position: absolute;
	width: min(320px, calc(100% - 24px));
	background: var(--rs-bg-surface, #1e293b);
	border: 1px solid var(--rs-border, #334155);
	border-radius: 12px;
	padding: 16px;
	box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
	color: var(--rs-text-primary, #f1f5f9);
	pointer-events: auto;
	animation: rspace-tour-pop 0.25s ease-out;
}
@keyframes rspace-tour-pop {
	from { opacity: 0; transform: translateY(8px); }
	to { opacity: 1; transform: translateY(0); }
}
.rspace-tour-tooltip__step {
	font-size: 0.7rem;
	color: var(--rs-text-muted, #64748b);
	margin-bottom: 4px;
	text-transform: uppercase;
	letter-spacing: 0.05em;
}
.rspace-tour-tooltip__title {
	font-size: 1rem;
	font-weight: 600;
	margin-bottom: 6px;
	background: linear-gradient(135deg, #06b6d4, #7c3aed);
	-webkit-background-clip: text;
	-webkit-text-fill-color: transparent;
	background-clip: text;
}
.rspace-tour-tooltip__msg {
	font-size: 0.85rem;
	color: var(--rs-text-secondary, #94a3b8);
	line-height: 1.5;
	margin-bottom: 12px;
}
.rspace-tour-tooltip__nav {
	display: flex;
	align-items: center;
	gap: 8px;
}
.rspace-tour-tooltip__btn {
	padding: 6px 14px;
	border-radius: 6px;
	font-size: 0.78rem;
	font-weight: 600;
	cursor: pointer;
	border: none;
	transition: background 0.15s, transform 0.1s;
}
.rspace-tour-tooltip__btn:hover { transform: translateY(-1px); }
.rspace-tour-tooltip__btn--next {
	background: linear-gradient(135deg, #06b6d4, #7c3aed);
	color: white;
}
.rspace-tour-tooltip__btn--prev {
	background: var(--rs-btn-secondary-bg, #334155);
	color: var(--rs-text-secondary, #94a3b8);
}
.rspace-tour-tooltip__btn--skip {
	background: none;
	color: var(--rs-text-muted, #64748b);
	margin-left: auto;
}
.rspace-tour-tooltip__btn--skip:hover { color: var(--rs-text-primary, #f1f5f9); }
.rspace-tour-tooltip__hint {
	font-size: 0.72rem;
	color: var(--rs-text-muted, #64748b);
	font-style: italic;
}
`;
