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: 420px;
		min-height: 500px;
	}

	.header {
		display: flex;
		align-items: center;
		justify-content: space-between;
		padding: 8px 12px;
		background: linear-gradient(135deg, #7c3aed, #a78bfa);
		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;
		align-items: center;
	}

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

	.state-badge {
		font-size: 9px;
		padding: 2px 6px;
		border-radius: 10px;
		text-transform: uppercase;
		letter-spacing: 0.5px;
		background: rgba(255,255,255,0.2);
	}

	.wrapper {
		height: 100%;
		overflow: hidden;
		display: flex;
		flex-direction: column;
	}

	.content {
		display: flex;
		flex-direction: column;
		flex: 1;
		min-height: 0;
		overflow: hidden;
	}

	.prompt-area {
		padding: 12px;
		border-bottom: 1px solid var(--rs-border, #e2e8f0);
	}

	.prompt-input {
		width: 100%;
		padding: 10px 12px;
		border: 2px solid var(--rs-input-border, #e2e8f0);
		border-radius: 8px;
		font-size: 13px;
		resize: none;
		outline: none;
		font-family: inherit;
		background: var(--rs-input-bg, #fff);
		color: var(--rs-input-text, inherit);
		box-sizing: border-box;
	}

	.prompt-input:focus {
		border-color: #7c3aed;
	}

	.btn-row {
		display: flex;
		gap: 6px;
		margin-top: 8px;
	}

	.btn {
		padding: 6px 14px;
		border-radius: 6px;
		border: none;
		font-size: 12px;
		font-weight: 600;
		cursor: pointer;
		transition: background 0.15s;
	}

	.btn-primary {
		background: linear-gradient(135deg, #7c3aed, #a78bfa);
		color: white;
	}
	.btn-primary:hover { background: linear-gradient(135deg, #6d28d9, #8b5cf6); }
	.btn-primary:disabled { opacity: 0.5; cursor: default; }

	.btn-secondary {
		background: var(--rs-bg-elevated, #f1f5f9);
		color: var(--rs-text-primary, #475569);
	}
	.btn-secondary:hover { background: var(--rs-bg-hover, #e2e8f0); }

	.status-area {
		flex: 1;
		overflow-y: auto;
		padding: 12px;
		font-size: 12px;
		min-height: 0;
	}

	.step {
		padding: 6px 0;
		border-bottom: 1px solid var(--rs-border, #f1f5f9);
		display: flex;
		align-items: flex-start;
		gap: 8px;
	}

	.step-icon {
		flex-shrink: 0;
		width: 18px;
		height: 18px;
		border-radius: 50%;
		display: flex;
		align-items: center;
		justify-content: center;
		font-size: 10px;
		margin-top: 1px;
	}

	.step-icon.thinking { background: #dbeafe; color: #2563eb; }
	.step-icon.executing { background: #fef3c7; color: #d97706; }
	.step-icon.done { background: #d1fae5; color: #059669; }
	.step-icon.error { background: #fee2e2; color: #dc2626; }

	.step-content {
		flex: 1;
		line-height: 1.4;
	}

	.step-tool {
		font-family: monospace;
		background: var(--rs-bg-elevated, #f1f5f9);
		padding: 1px 4px;
		border-radius: 3px;
		font-size: 11px;
	}

	.export-row {
		display: flex;
		gap: 6px;
		padding: 8px 12px;
		border-top: 1px solid var(--rs-border, #e2e8f0);
		justify-content: center;
	}

	.placeholder {
		display: flex;
		flex-direction: column;
		align-items: center;
		gap: 8px;
		padding: 2rem;
		color: #94a3b8;
		text-align: center;
	}

	.placeholder-icon { font-size: 2rem; }

	.spinner {
		display: inline-block;
		width: 12px;
		height: 12px;
		border: 2px solid rgba(255,255,255,0.3);
		border-top-color: #fff;
		border-radius: 50%;
		animation: spin 0.8s linear infinite;
		vertical-align: middle;
		margin-right: 4px;
	}

	@keyframes spin { to { transform: rotate(360deg); } }
`;

declare global {
	interface HTMLElementTagNameMap {
		"folk-design-agent": FolkDesignAgent;
	}
}

type AgentState = "idle" | "planning" | "executing" | "verifying" | "done" | "error";

export class FolkDesignAgent extends FolkShape {
	static override tagName = "folk-design-agent";

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

	#state: AgentState = "idle";
	#abortController: AbortController | null = null;
	#promptInput: HTMLTextAreaElement | null = null;
	#statusArea: HTMLElement | null = null;
	#generateBtn: HTMLButtonElement | null = null;
	#stopBtn: HTMLButtonElement | null = null;
	#exportRow: HTMLElement | null = null;
	#stateBadge: HTMLElement | null = null;

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

		const wrapper = document.createElement("div");
		wrapper.className = "wrapper";
		wrapper.innerHTML = html`
			<div class="header">
				<span class="header-title">
					<span>&#x1f3af;</span>
					<span>rDesign Agent</span>
				</span>
				<div class="header-actions">
					<span class="state-badge" data-ref="state-badge">Idle</span>
					<button class="close-btn" title="Close">&times;</button>
				</div>
			</div>
			<div class="content">
				<div class="prompt-area">
					<textarea class="prompt-input" placeholder="Describe the design you want to create..." rows="3"></textarea>
					<div class="btn-row">
						<button class="btn btn-primary" data-ref="generate-btn">Generate Design</button>
						<button class="btn btn-secondary" data-ref="stop-btn" style="display:none">Stop</button>
					</div>
				</div>
				<div class="status-area" data-ref="status-area">
					<div class="placeholder">
						<span class="placeholder-icon">&#x1f4d0;</span>
						<span>Enter a design brief to get started.<br>The agent will create a Scribus document step by step.</span>
					</div>
				</div>
				<div class="export-row" data-ref="export-row" style="display:none">
					<a class="btn btn-secondary" href="https://design.rspace.online" target="_blank" rel="noopener">Open in Scribus</a>
				</div>
			</div>
		`;

		// Replace slot container with our wrapper
		const slot = root.querySelector("slot");
		const containerDiv = slot?.parentElement as HTMLElement;
		if (containerDiv) containerDiv.replaceWith(wrapper);

		this.#promptInput = wrapper.querySelector(".prompt-input");
		this.#statusArea = wrapper.querySelector('[data-ref="status-area"]');
		this.#generateBtn = wrapper.querySelector('[data-ref="generate-btn"]');
		this.#stopBtn = wrapper.querySelector('[data-ref="stop-btn"]');
		this.#exportRow = wrapper.querySelector('[data-ref="export-row"]');
		this.#stateBadge = wrapper.querySelector('[data-ref="state-badge"]');

		// Set initial brief from attribute
		const brief = this.getAttribute("brief");
		if (brief && this.#promptInput) this.#promptInput.value = brief;

		// Generate button
		this.#generateBtn?.addEventListener("click", (e) => {
			e.stopPropagation();
			this.#generate();
		});

		// Stop button
		this.#stopBtn?.addEventListener("click", (e) => {
			e.stopPropagation();
			this.#stop();
		});

		// Enter key
		this.#promptInput?.addEventListener("keydown", (e) => {
			if (e.key === "Enter" && !e.shiftKey) {
				e.preventDefault();
				this.#generate();
			}
		});

		// Prevent canvas drag
		this.#promptInput?.addEventListener("pointerdown", (e) => e.stopPropagation());
		this.#statusArea?.addEventListener("pointerdown", (e) => e.stopPropagation());

		// Close button
		const closeBtn = wrapper.querySelector(".close-btn") as HTMLButtonElement;
		closeBtn?.addEventListener("click", (e) => {
			e.stopPropagation();
			this.dispatchEvent(new CustomEvent("close"));
		});

		return root;
	}

	#setState(state: AgentState) {
		this.#state = state;
		if (this.#stateBadge) this.#stateBadge.textContent = state.charAt(0).toUpperCase() + state.slice(1);

		const isWorking = state !== "idle" && state !== "done" && state !== "error";
		if (this.#generateBtn) {
			this.#generateBtn.disabled = isWorking;
			this.#generateBtn.innerHTML = isWorking
				? '<span class="spinner"></span> Working...'
				: "Generate Design";
		}
		if (this.#stopBtn) this.#stopBtn.style.display = isWorking ? "" : "none";
		if (this.#exportRow) this.#exportRow.style.display = state === "done" ? "" : "none";
		if (this.#promptInput) this.#promptInput.disabled = isWorking;
	}

	#addStep(icon: string, cls: string, text: string) {
		if (!this.#statusArea) return;
		// Remove placeholder on first step
		const placeholder = this.#statusArea.querySelector(".placeholder");
		if (placeholder) placeholder.remove();

		const step = document.createElement("div");
		step.className = "step";
		step.innerHTML = `<div class="step-icon ${cls}">${icon}</div><div class="step-content">${text}</div>`;
		this.#statusArea.appendChild(step);
		this.#statusArea.scrollTop = this.#statusArea.scrollHeight;
	}

	async #generate() {
		const brief = this.#promptInput?.value.trim();
		if (!brief || (this.#state !== "idle" && this.#state !== "done" && this.#state !== "error")) return;

		// Clear previous steps
		if (this.#statusArea) this.#statusArea.innerHTML = "";
		this.#setState("planning");
		this.#abortController = new AbortController();

		try {
			const space = this.closest("[data-space]")?.getAttribute("data-space") || "demo";
			const res = await fetch("/api/design-agent", {
				method: "POST",
				headers: { "Content-Type": "application/json" },
				body: JSON.stringify({ brief, space }),
				signal: this.#abortController.signal,
			});

			if (!res.ok || !res.body) {
				this.#addStep("!", "error", `Request failed: ${res.status}`);
				this.#setState("error");
				return;
			}

			const reader = res.body.getReader();
			const decoder = new TextDecoder();
			let buffer = "";

			while (true) {
				const { done, value } = await reader.read();
				if (done) break;

				buffer += decoder.decode(value, { stream: true });
				const lines = buffer.split("\n");
				buffer = lines.pop() || "";

				for (const line of lines) {
					if (line.startsWith("data:")) {
						try {
							const data = JSON.parse(line.slice(5).trim());
							this.#processEvent(data);
						} catch {}
					}
				}
			}

			if (this.#state !== "error") this.#setState("done");
		} catch (e: any) {
			if (e.name !== "AbortError") {
				this.#addStep("!", "error", `Error: ${e.message}`);
				this.#setState("error");
			}
		}

		this.#abortController = null;
	}

	#processEvent(data: any) {
		switch (data.action) {
			case "starting_scribus":
				this.#addStep("~", "thinking", data.status || "Starting Scribus...");
				break;
			case "scribus_ready":
				this.#addStep("&#x2713;", "done", "Scribus ready");
				break;
			case "thinking":
				this.#setState("planning");
				this.#addStep("~", "thinking", data.status || "Thinking...");
				break;
			case "executing":
				this.#setState("executing");
				this.#addStep("&#x25B6;", "executing",
					`${data.status || "Executing"}: <span class="step-tool">${data.tool}</span>`);
				break;
			case "tool_result":
				if (data.result?.error) {
					this.#addStep("!", "error", `${data.tool} failed: ${data.result.error}`);
				} else {
					this.#addStep("&#x2713;", "done", `${data.tool} completed`);
				}
				break;
			case "verifying":
				this.#setState("verifying");
				this.#addStep("~", "thinking", data.status || "Verifying...");
				break;
			case "complete":
				this.#addStep("&#x2713;", "done", data.message || "Design complete");
				break;
			case "done":
				this.#addStep("&#x2713;", "done", data.status || "Done!");
				if (data.state?.frames) {
					this.#addStep("&#x2713;", "done", `${data.state.frames.length} frame(s) in document`);
				}
				break;
			case "error":
				this.#addStep("!", "error", data.error || "Unknown error");
				this.#setState("error");
				break;
		}
	}

	#stop() {
		this.#abortController?.abort();
		this.#setState("idle");
		this.#addStep("!", "error", "Stopped by user");
	}

	override disconnectedCallback() {
		super.disconnectedCallback?.();
		this.#abortController?.abort();
		this.#abortController = null;
	}
}

if (!customElements.get(FolkDesignAgent.tagName)) {
	customElements.define(FolkDesignAgent.tagName, FolkDesignAgent);
}
