import { FolkShape } from "./folk-shape";
import { css, html } from "./tags";

const PIANO_URL = "https://musiclab.chromeexperiments.com/Shared-Piano/";

const styles = css`
	:host {
		background: var(--rs-bg-surface, #1e1e2e);
		color: var(--rs-text-primary, #e2e8f0);
		border-radius: 8px;
		box-shadow: var(--rs-shadow-md, 0 2px 8px rgba(0, 0, 0, 0.2));
		min-width: 400px;
		min-height: 300px;
		overflow: hidden;
	}

	.piano-container {
		width: 100%;
		height: 100%;
		position: relative;
	}

	.piano-iframe {
		width: 100%;
		height: 100%;
		border: none;
	}

	.loading {
		position: absolute;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		display: flex;
		align-items: center;
		justify-content: center;
		background: linear-gradient(135deg, #1e1e2e 0%, #2d2d44 100%);
		color: white;
		font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
		font-size: 18px;
		gap: 12px;
	}

	.loading.hidden {
		display: none;
	}

	.error {
		position: absolute;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		background: linear-gradient(135deg, #1e1e2e 0%, #2d2d44 100%);
		color: white;
		font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
		gap: 12px;
	}

	.error.hidden {
		display: none;
	}

	.error-message {
		font-size: 14px;
		color: #f87171;
	}

	.retry-btn {
		background: #6366f1;
		color: white;
		border: none;
		border-radius: 6px;
		padding: 8px 16px;
		cursor: pointer;
		font-size: 14px;
	}

	.retry-btn:hover {
		background: #4f46e5;
	}

	.controls {
		position: absolute;
		top: 8px;
		right: 8px;
		display: flex;
		gap: 4px;
	}

	.control-btn {
		background: rgba(0, 0, 0, 0.5);
		color: white;
		border: none;
		border-radius: 4px;
		padding: 4px 8px;
		cursor: pointer;
		font-size: 14px;
	}

	.control-btn:hover {
		background: rgba(0, 0, 0, 0.7);
	}

	.minimized {
		width: 100%;
		height: 100%;
		display: flex;
		align-items: center;
		justify-content: center;
		background: linear-gradient(135deg, #1e1e2e 0%, #2d2d44 100%);
		color: white;
		font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
		font-size: 24px;
		cursor: pointer;
	}

	.minimized.hidden {
		display: none;
	}
`;

declare global {
	interface HTMLElementTagNameMap {
		"folk-piano": FolkPiano;
	}
}

export class FolkPiano extends FolkShape {
	static override tagName = "folk-piano";

	static {
		const sheet = new CSSStyleSheet();
		const parentRules = Array.from(FolkShape.styles.cssRules)
			.map((r) => r.cssText)
			.join("\n");
		const childRules = Array.from(styles.cssRules)
			.map((r) => r.cssText)
			.join("\n");
		sheet.replaceSync(`${parentRules}\n${childRules}`);
		this.styles = sheet;
	}

	#isMinimized = false;
	#isLoading = true;
	#hasError = false;
	#iframe: HTMLIFrameElement | null = null;
	#loadingEl: HTMLElement | null = null;
	#errorEl: HTMLElement | null = null;
	#minimizedEl: HTMLElement | null = null;
	#containerEl: HTMLElement | null = null;
	#onWindowError: ((e: ErrorEvent) => void) | null = null;

	get isMinimized() {
		return this.#isMinimized;
	}

	set isMinimized(value: boolean) {
		this.#isMinimized = value;
		this.#updateVisibility();
		this.requestUpdate("isMinimized");
	}

	override createRenderRoot() {
		const root = super.createRenderRoot();

		const wrapper = document.createElement("div");
		wrapper.innerHTML = html`
			<div class="piano-container" data-drag>
				<div class="loading">
					<span>🎹</span>
					<span>Loading Shared Piano...</span>
				</div>
				<div class="error hidden">
					<span>🎹</span>
					<span class="error-message">Failed to load piano</span>
					<button class="retry-btn">Retry</button>
				</div>
				<div class="minimized hidden">
					<span>🎹 Shared Piano</span>
				</div>
				<iframe
					class="piano-iframe"
					src="${PIANO_URL}"
					allow="microphone; camera; midi; autoplay; encrypted-media; fullscreen"
					sandbox="allow-scripts allow-forms allow-popups allow-modals allow-same-origin"
					style="opacity: 0;"
				></iframe>
				<div class="controls">
					<button class="control-btn minimize-btn" title="Minimize">🔼</button>
				</div>
			</div>
		`;

		// Replace the container div (slot's parent) with our piano container
		const slot = root.querySelector("slot");
		const containerDiv = slot?.parentElement as HTMLElement;
		const pianoContainer = wrapper.querySelector(".piano-container");
		if (containerDiv && pianoContainer) {
			containerDiv.replaceWith(pianoContainer);
		}

		// Get references
		this.#containerEl = root.querySelector(".piano-container");
		this.#loadingEl = root.querySelector(".loading");
		this.#errorEl = root.querySelector(".error");
		this.#minimizedEl = root.querySelector(".minimized");
		this.#iframe = root.querySelector(".piano-iframe");
		const minimizeBtn = root.querySelector(".minimize-btn") as HTMLButtonElement;
		const retryBtn = root.querySelector(".retry-btn") as HTMLButtonElement;

		// Iframe load handling
		this.#iframe?.addEventListener("load", () => {
			this.#isLoading = false;
			this.#hasError = false;
			if (this.#loadingEl) this.#loadingEl.classList.add("hidden");
			if (this.#iframe) this.#iframe.style.opacity = "1";
		});

		this.#iframe?.addEventListener("error", () => {
			this.#isLoading = false;
			this.#hasError = true;
			if (this.#loadingEl) this.#loadingEl.classList.add("hidden");
			if (this.#errorEl) this.#errorEl.classList.remove("hidden");
		});

		// Minimize toggle
		minimizeBtn?.addEventListener("click", (e) => {
			e.stopPropagation();
			this.isMinimized = !this.#isMinimized;
			minimizeBtn.textContent = this.#isMinimized ? "🔽" : "🔼";
		});

		// Click minimized view to expand
		this.#minimizedEl?.addEventListener("click", (e) => {
			e.stopPropagation();
			this.isMinimized = false;
			if (minimizeBtn) minimizeBtn.textContent = "🔼";
		});

		// Retry button
		retryBtn?.addEventListener("click", (e) => {
			e.stopPropagation();
			this.#retry();
		});

		// Suppress Chrome Music Lab console errors
		this.#onWindowError = (e: ErrorEvent) => {
			if (e.message?.includes("musiclab") || e.filename?.includes("musiclab")) {
				e.preventDefault();
			}
		};
		window.addEventListener("error", this.#onWindowError);

		return root;
	}

	#updateVisibility() {
		if (!this.#iframe || !this.#minimizedEl) return;

		if (this.#isMinimized) {
			this.#iframe.style.display = "none";
			this.#minimizedEl.classList.remove("hidden");
		} else {
			this.#iframe.style.display = "block";
			this.#minimizedEl.classList.add("hidden");
		}
	}

	#retry() {
		if (!this.#iframe || !this.#errorEl || !this.#loadingEl) return;

		this.#hasError = false;
		this.#isLoading = true;
		this.#errorEl.classList.add("hidden");
		this.#loadingEl.classList.remove("hidden");
		this.#iframe.style.opacity = "0";
		this.#iframe.src = PIANO_URL;
	}

	override disconnectedCallback() {
		super.disconnectedCallback?.();
		if (this.#onWindowError) {
			window.removeEventListener("error", this.#onWindowError);
			this.#onWindowError = null;
		}
	}

	static override fromData(data: Record<string, any>): FolkPiano {
		const shape = FolkShape.fromData(data) as FolkPiano;
		if (data.isMinimized != null) shape.isMinimized = data.isMinimized;
		return shape;
	}

	override toJSON() {
		return {
			...super.toJSON(),
			type: "folk-piano",
			isMinimized: this.isMinimized,
		};
	}

	override applyData(data: Record<string, any>): void {
		super.applyData(data);
		if ("isMinimized" in data && this.isMinimized !== data.isMinimized) {
			this.isMinimized = data.isMinimized;
		}
	}
}
