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

const styles = css`
	:host {
		background: var(--rs-bg-surface, #fff);
		color: var(--rs-text-primary, #1e293b);
		border-radius: 8px;
		box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
		min-width: 200px;
		min-height: 150px;
	}

	.header {
		display: flex;
		align-items: center;
		justify-content: space-between;
		padding: 8px 12px;
		background: #22c55e;
		color: white;
		border-radius: 8px 8px 0 0;
		font-size: 12px;
		font-weight: 600;
		cursor: move;
	}

	.header-title {
		display: flex;
		align-items: center;
		gap: 6px;
	}

	.header-actions {
		display: flex;
		gap: 4px;
	}

	.header-actions button {
		background: transparent;
		border: none;
		color: white;
		cursor: pointer;
		padding: 2px 6px;
		border-radius: 4px;
		font-size: 14px;
	}

	.header-actions button:hover {
		background: rgba(255, 255, 255, 0.2);
	}

	.content {
		width: 100%;
		height: calc(100% - 36px);
		position: relative;
		border-radius: 0 0 8px 8px;
		overflow: hidden;
	}

	.drop-zone {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		height: 100%;
		padding: 24px;
		gap: 12px;
		border: 2px dashed var(--rs-input-border, #e2e8f0);
		border-radius: 0 0 8px 8px;
		margin: 8px;
		text-align: center;
		color: #94a3b8;
		font-size: 13px;
		transition: border-color 0.2s, background 0.2s;
	}

	.drop-zone.dragover {
		border-color: #22c55e;
		background: rgba(34, 197, 94, 0.05);
	}

	.drop-zone-icon {
		font-size: 32px;
	}

	.url-input {
		width: 100%;
		max-width: 300px;
		padding: 10px 14px;
		border: 2px solid var(--rs-input-border, #e2e8f0);
		border-radius: 8px;
		font-size: 13px;
		outline: none;
		background: var(--rs-input-bg, #fff);
		color: var(--rs-input-text, inherit);
	}

	.url-input:focus {
		border-color: #22c55e;
	}

	.image-display {
		width: 100%;
		height: 100%;
		object-fit: contain;
		display: block;
	}
`;

declare global {
	interface HTMLElementTagNameMap {
		"folk-image": FolkImage;
	}
}

export class FolkImage extends FolkShape {
	static override tagName = "folk-image";

	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;
	}

	#src: string | null = null;
	#alt: string = "";

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

	set src(value: string | null) {
		this.#src = value;
		this.requestUpdate("src");
		this.dispatchEvent(new CustomEvent("src-change", { detail: { src: value } }));
	}

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

	set alt(value: string) {
		this.#alt = value;
	}

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

		this.#src = this.getAttribute("src") || null;
		this.#alt = this.getAttribute("alt") || "";

		const wrapper = document.createElement("div");
		wrapper.innerHTML = html`
			<div class="header">
				<span class="header-title">
					<span>🖼️</span>
					<span class="title-text">Image</span>
				</span>
				<div class="header-actions">
					<button class="close-btn" title="Close">×</button>
				</div>
			</div>
			<div class="content">
				<div class="drop-zone">
					<span class="drop-zone-icon">🖼️</span>
					<span>Paste, drop, or enter image URL…</span>
					<input
						type="text"
						class="url-input"
						placeholder="https://example.com/image.png"
					/>
				</div>
			</div>
		`;

		const slot = root.querySelector("slot");
		const containerDiv = slot?.parentElement as HTMLElement;
		if (containerDiv) {
			containerDiv.replaceWith(wrapper);
		}

		const content = wrapper.querySelector(".content") as HTMLElement;
		const dropZone = wrapper.querySelector(".drop-zone") as HTMLElement;
		const urlInput = wrapper.querySelector(".url-input") as HTMLInputElement;
		const closeBtn = wrapper.querySelector(".close-btn") as HTMLButtonElement;

		// URL input
		const handleUrlSubmit = () => {
			let inputUrl = urlInput.value.trim();
			if (!inputUrl) return;
			if (!inputUrl.startsWith("http://") && !inputUrl.startsWith("https://")) {
				inputUrl = `https://${inputUrl}`;
			}
			this.src = inputUrl;
			this.#renderImage(content, dropZone);
		};

		urlInput.addEventListener("keydown", (e) => {
			if (e.key === "Enter") {
				e.preventDefault();
				handleUrlSubmit();
			}
		});

		urlInput.addEventListener("blur", () => {
			if (urlInput.value.trim()) handleUrlSubmit();
		});

		// Drop image files directly onto shape
		dropZone.addEventListener("dragover", (e) => {
			e.preventDefault();
			e.stopPropagation();
			dropZone.classList.add("dragover");
		});

		dropZone.addEventListener("dragleave", () => {
			dropZone.classList.remove("dragover");
		});

		dropZone.addEventListener("drop", (e) => {
			e.preventDefault();
			e.stopPropagation();
			dropZone.classList.remove("dragover");

			const file = Array.from(e.dataTransfer?.files || []).find((f) =>
				f.type.startsWith("image/")
			);
			if (file) {
				this.#uploadFile(file, content, dropZone);
				return;
			}

			const url = e.dataTransfer?.getData("text/plain") || "";
			if (url.trim()) {
				this.src = url.trim();
				this.#renderImage(content, dropZone);
			}
		});

		// Close button
		closeBtn.addEventListener("click", (e) => {
			e.stopPropagation();
			this.dispatchEvent(new CustomEvent("close"));
		});

		// If src already set, render image
		if (this.#src) {
			this.#renderImage(content, dropZone);
		}

		return root;
	}

	async #uploadFile(
		file: File,
		content: HTMLElement,
		dropZone: HTMLElement
	) {
		const reader = new FileReader();
		reader.onload = async () => {
			try {
				const res = await fetch("/api/image-upload", {
					method: "POST",
					headers: { "Content-Type": "application/json" },
					body: JSON.stringify({ image: reader.result }),
				});
				const data = await res.json();
				if (data.url) {
					this.src = data.url;
					this.alt = file.name;
					this.#renderImage(content, dropZone);
				}
			} catch (err) {
				console.error("[folk-image] upload failed:", err);
			}
		};
		reader.readAsDataURL(file);
	}

	#renderImage(content: HTMLElement, dropZone: HTMLElement) {
		if (!this.#src) return;
		dropZone.style.display = "none";

		// Remove existing image if any
		const existing = content.querySelector(".image-display");
		if (existing) existing.remove();

		const img = document.createElement("img");
		img.className = "image-display";
		img.src = this.#src;
		img.alt = this.#alt || "Image";
		img.draggable = false;
		content.appendChild(img);

		// Update header title
		const titleText = this.renderRoot.querySelector(".title-text");
		if (titleText) {
			titleText.textContent = this.#alt || "Image";
		}
	}

	static override fromData(data: Record<string, any>): FolkImage {
		const shape = FolkShape.fromData(data) as FolkImage;
		if (data.src) shape.src = data.src;
		if (data.alt) shape.alt = data.alt;
		return shape;
	}

	override toJSON() {
		return {
			...super.toJSON(),
			type: "folk-image",
			src: this.src,
			alt: this.alt,
		};
	}

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