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 4px rgba(0, 0, 0, 0.1);
		min-width: 80px;
		min-height: 40px;
		display: flex;
		flex-direction: column;
		overflow: hidden;
	}

	:host([selected]) {
		box-shadow: 0 0 0 2px var(--primary-color, #14b8a6), 0 4px 8px rgba(0, 0, 0, 0.15);
	}

	.header {
		height: 40px;
		display: flex;
		align-items: center;
		justify-content: space-between;
		padding: 0 12px;
		cursor: move;
		user-select: none;
		flex-shrink: 0;
		transition: background-color 0.2s ease;
		background: var(--header-bg, rgba(20, 184, 166, 0.1));
		border-bottom: 1px solid var(--header-border, rgba(20, 184, 166, 0.2));
	}

	:host([selected]) .header {
		background: var(--primary-color, #14b8a6);
		color: white;
	}

	.header-title {
		font-size: 13px;
		font-weight: 600;
		color: var(--primary-color, #14b8a6);
		display: flex;
		align-items: center;
		gap: 6px;
	}

	:host([selected]) .header-title {
		color: white;
	}

	.header-icon {
		font-size: 14px;
	}

	.header-actions {
		display: flex;
		gap: 8px;
		align-items: center;
	}

	.header-actions button {
		width: 24px;
		height: 24px;
		border-radius: 4px;
		border: none;
		cursor: pointer;
		display: flex;
		align-items: center;
		justify-content: center;
		font-size: 12px;
		font-weight: 600;
		transition: background-color 0.15s ease;
		background: var(--button-bg, rgba(20, 184, 166, 0.2));
		color: var(--primary-color, #14b8a6);
	}

	:host([selected]) .header-actions button {
		background: rgba(255, 255, 255, 0.2);
		color: white;
	}

	.header-actions button:hover {
		background: var(--button-hover-bg, rgba(20, 184, 166, 0.3));
	}

	:host([selected]) .header-actions button:hover {
		background: rgba(255, 255, 255, 0.3);
	}

	.header-actions button.active {
		background: var(--primary-color, #14b8a6);
		color: white;
	}

	:host([selected]) .header-actions button.active {
		background: rgba(255, 255, 255, 0.4);
	}

	.content {
		flex: 1;
		overflow: auto;
		position: relative;
	}

	:host([minimized]) .content {
		display: none;
	}

	.tags {
		padding: 8px 12px;
		border-top: 1px solid var(--rs-border, #e0e0e0);
		display: flex;
		flex-wrap: wrap;
		gap: 4px;
		align-items: center;
		min-height: 32px;
		background: var(--rs-bg-surface-sunken, #f8f9fa);
		flex-shrink: 0;
	}

	:host([minimized]) .tags {
		display: none;
	}

	.tag {
		background: #6b7280;
		color: white;
		padding: 4px 8px;
		border-radius: 12px;
		font-size: 10px;
		font-weight: 500;
		display: inline-flex;
		align-items: center;
		gap: 4px;
		cursor: pointer;
	}

	.tag:hover {
		background: #4b5563;
	}

	.tag .remove {
		font-size: 8px;
		opacity: 0.7;
	}

	.tag .remove:hover {
		opacity: 1;
	}

	.add-tag {
		background: #9ca3af;
		color: white;
		border: none;
		border-radius: 12px;
		padding: 4px 10px;
		font-size: 10px;
		font-weight: 500;
		cursor: pointer;
		display: flex;
		align-items: center;
		gap: 4px;
	}

	.add-tag:hover {
		background: #6b7280;
	}

	.tag-input {
		border: 1px solid var(--rs-input-border, #9ca3af);
		border-radius: 12px;
		padding: 2px 6px;
		font-size: 10px;
		outline: none;
		min-width: 60px;
		flex: 1;
		background: var(--rs-input-bg, #fff);
		color: var(--rs-input-text, inherit);
	}
`;

declare global {
	interface HTMLElementTagNameMap {
		"folk-wrapper": FolkWrapper;
	}
}

export class FolkWrapper extends FolkShape {
	static override tagName = "folk-wrapper";

	// Merge parent and child styles
	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;
	}

	#title = "Untitled";
	#icon = "";
	#primaryColor = "#14b8a6";
	#isMinimized = false;
	#isPinned = false;
	#tags: string[] = [];
	#isEditingTags = false;
	#tagInput: HTMLInputElement | null = null;

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

	set title(value: string) {
		this.#title = value;
		this.requestUpdate("title");
	}

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

	set icon(value: string) {
		this.#icon = value;
		this.requestUpdate("icon");
	}

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

	set primaryColor(value: string) {
		this.#primaryColor = value;
		this.style.setProperty("--primary-color", value);
		this.style.setProperty("--header-bg", `${value}10`);
		this.style.setProperty("--header-border", `${value}30`);
		this.style.setProperty("--button-bg", `${value}20`);
		this.style.setProperty("--button-hover-bg", `${value}30`);
		this.requestUpdate("primaryColor");
	}

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

	set isMinimized(value: boolean) {
		this.#isMinimized = value;
		this.toggleAttribute("minimized", value);
	}

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

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

	get tags() {
		return [...this.#tags];
	}

	set tags(value: string[]) {
		this.#tags = [...value];
		this.requestUpdate("tags");
	}

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

		// Add wrapper UI
		const wrapper = document.createElement("div");
		wrapper.innerHTML = html`
			<div class="header">
				<div class="header-title">
					<span class="header-icon"></span>
					<span class="title-text"></span>
				</div>
				<div class="header-actions">
					<button class="pin-btn" title="Pin to view">📌</button>
					<button class="minimize-btn" title="Minimize">_</button>
					<button class="close-btn" title="Close">×</button>
				</div>
			</div>
			<div class="content">
				<slot></slot>
			</div>
			<div class="tags"></div>
		`;

		// Replace existing content structure — save parent ref before clearing
		const existingSlot = root.querySelector("slot");
		const slotParent = existingSlot?.parentElement;
		if (slotParent) {
			slotParent.innerHTML = "";
			slotParent.appendChild(wrapper);
		}

		// Get references
		const header = wrapper.querySelector(".header") as HTMLElement;
		const titleIcon = wrapper.querySelector(".header-icon") as HTMLElement;
		const titleText = wrapper.querySelector(".title-text") as HTMLElement;
		const pinBtn = wrapper.querySelector(".pin-btn") as HTMLButtonElement;
		const minimizeBtn = wrapper.querySelector(".minimize-btn") as HTMLButtonElement;
		const closeBtn = wrapper.querySelector(".close-btn") as HTMLButtonElement;
		const tagsContainer = wrapper.querySelector(".tags") as HTMLElement;

		// Initialize
		titleIcon.textContent = this.#icon;
		titleText.textContent = this.#title;
		this.primaryColor = this.getAttribute("color") || this.#primaryColor;
		this.title = this.getAttribute("title") || this.#title;
		this.icon = this.getAttribute("icon") || this.#icon;

		// Parse tags from attribute
		const tagsAttr = this.getAttribute("tags");
		if (tagsAttr) {
			this.#tags = tagsAttr.split(",").map((t) => t.trim()).filter(Boolean);
		}

		// Event handlers
		pinBtn.addEventListener("click", (e) => {
			e.stopPropagation();
			this.#isPinned = !this.#isPinned;
			pinBtn.classList.toggle("active", this.#isPinned);
			this.dispatchEvent(new CustomEvent("pin-toggle", { detail: { pinned: this.#isPinned } }));
		});

		minimizeBtn.addEventListener("click", (e) => {
			e.stopPropagation();
			this.isMinimized = !this.isMinimized;
			this.dispatchEvent(new CustomEvent("minimize-toggle", { detail: { minimized: this.#isMinimized } }));
		});

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

		// Render tags
		this.#renderTags(tagsContainer);

		// Watch for attribute changes
		const observer = new MutationObserver((mutations) => {
			for (const mutation of mutations) {
				if (mutation.type === "attributes") {
					switch (mutation.attributeName) {
						case "title":
							titleText.textContent = this.getAttribute("title") || "";
							break;
						case "icon":
							titleIcon.textContent = this.getAttribute("icon") || "";
							break;
						case "color":
							this.primaryColor = this.getAttribute("color") || "#14b8a6";
							break;
						case "tags":
							const tagsAttr = this.getAttribute("tags");
							if (tagsAttr) {
								this.#tags = tagsAttr.split(",").map((t) => t.trim()).filter(Boolean);
								this.#renderTags(tagsContainer);
							}
							break;
					}
				}
			}
		});

		observer.observe(this, { attributes: true });

		return root;
	}

	#renderTags(container: HTMLElement) {
		container.innerHTML = "";

		for (const tag of this.#tags.slice(0, 5)) {
			const tagEl = document.createElement("span");
			tagEl.className = "tag";
			tagEl.innerHTML = `${tag.replace("#", "")} <span class="remove">×</span>`;

			tagEl.querySelector(".remove")?.addEventListener("click", (e) => {
				e.stopPropagation();
				this.#tags = this.#tags.filter((t) => t !== tag);
				this.#renderTags(container);
				this.dispatchEvent(new CustomEvent("tags-change", { detail: { tags: this.#tags } }));
			});

			container.appendChild(tagEl);
		}

		if (this.#tags.length > 5) {
			const moreTag = document.createElement("span");
			moreTag.className = "tag";
			moreTag.textContent = `+${this.#tags.length - 5}`;
			container.appendChild(moreTag);
		}

		// Add tag button
		if (this.#tags.length < 10) {
			if (this.#isEditingTags) {
				const input = document.createElement("input");
				input.className = "tag-input";
				input.placeholder = "Add tag...";
				input.addEventListener("keydown", (e) => {
					if (e.key === "Enter") {
						e.preventDefault();
						const value = input.value.trim().replace("#", "");
						if (value && !this.#tags.includes(value)) {
							this.#tags.push(value);
							this.#renderTags(container);
							this.dispatchEvent(new CustomEvent("tags-change", { detail: { tags: this.#tags } }));
						}
						this.#isEditingTags = false;
						this.#renderTags(container);
					} else if (e.key === "Escape") {
						this.#isEditingTags = false;
						this.#renderTags(container);
					}
				});
				input.addEventListener("blur", () => {
					const value = input.value.trim().replace("#", "");
					if (value && !this.#tags.includes(value)) {
						this.#tags.push(value);
						this.dispatchEvent(new CustomEvent("tags-change", { detail: { tags: this.#tags } }));
					}
					this.#isEditingTags = false;
					this.#renderTags(container);
				});
				container.appendChild(input);
				setTimeout(() => input.focus(), 0);
			} else {
				const addBtn = document.createElement("button");
				addBtn.className = "add-tag";
				addBtn.textContent = "+ Add";
				addBtn.addEventListener("click", (e) => {
					e.stopPropagation();
					this.#isEditingTags = true;
					this.#renderTags(container);
				});
				container.appendChild(addBtn);
			}
		}
	}

	addTag(tag: string) {
		const cleanTag = tag.trim().replace("#", "");
		if (cleanTag && !this.#tags.includes(cleanTag)) {
			this.#tags.push(cleanTag);
			const tagsContainer = this.shadowRoot?.querySelector(".tags") as HTMLElement;
			if (tagsContainer) {
				this.#renderTags(tagsContainer);
			}
			this.dispatchEvent(new CustomEvent("tags-change", { detail: { tags: this.#tags } }));
		}
	}

	removeTag(tag: string) {
		const cleanTag = tag.trim().replace("#", "");
		this.#tags = this.#tags.filter((t) => t !== cleanTag);
		const tagsContainer = this.shadowRoot?.querySelector(".tags") as HTMLElement;
		if (tagsContainer) {
			this.#renderTags(tagsContainer);
		}
		this.dispatchEvent(new CustomEvent("tags-change", { detail: { tags: this.#tags } }));
	}

	static override fromData(data: Record<string, any>): FolkWrapper {
		const shape = FolkShape.fromData(data) as FolkWrapper;
		if (data.title) shape.title = data.title;
		if (data.icon) shape.icon = data.icon;
		if (data.primaryColor) shape.primaryColor = data.primaryColor;
		if (data.isMinimized) shape.isMinimized = data.isMinimized;
		if (data.isPinned) shape.isPinned = data.isPinned;
		if (data.tags) shape.tags = data.tags;
		return shape;
	}

	toJSON() {
		return {
			type: "folk-wrapper",
			id: this.id,
			x: this.x,
			y: this.y,
			width: this.width,
			height: this.height,
			rotation: this.rotation,
			title: this.#title,
			icon: this.#icon,
			primaryColor: this.#primaryColor,
			isMinimized: this.#isMinimized,
			isPinned: this.#isPinned,
			tags: this.#tags,
		};
	}

	override applyData(data: Record<string, any>): void {
		super.applyData(data);
		if (data.title !== undefined && this.title !== data.title) this.title = data.title;
		if (data.icon !== undefined && this.icon !== data.icon) this.icon = data.icon;
		if (data.primaryColor !== undefined && this.primaryColor !== data.primaryColor) this.primaryColor = data.primaryColor;
		if (data.isMinimized !== undefined && this.isMinimized !== data.isMinimized) this.isMinimized = data.isMinimized;
		if (data.isPinned !== undefined && this.isPinned !== data.isPinned) this.isPinned = data.isPinned;
		if (data.tags !== undefined) this.tags = data.tags;
	}
}
