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: 260px;
		min-height: 200px;
	}

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

	.progress-info {
		padding: 8px 12px;
		font-size: 11px;
		color: var(--rs-text-muted, #64748b);
		display: flex;
		justify-content: space-between;
		align-items: center;
		border-bottom: 1px solid var(--rs-border, rgba(255, 255, 255, 0.1));
	}

	.progress-bar {
		width: 80px;
		height: 6px;
		background: var(--rs-bg-surface-raised, #334155);
		border-radius: 3px;
		overflow: hidden;
	}

	.progress-fill {
		height: 100%;
		background: #7c3aed;
		border-radius: 3px;
		transition: width 0.3s ease;
	}

	.packing-list {
		padding: 8px 12px;
		max-height: 300px;
		overflow-y: auto;
	}

	.category-label {
		font-size: 10px;
		font-weight: 600;
		color: #7c3aed;
		text-transform: uppercase;
		letter-spacing: 0.5px;
		padding: 6px 0 3px;
	}

	.item {
		display: flex;
		align-items: center;
		gap: 8px;
		padding: 4px 0;
		font-size: 12px;
		cursor: pointer;
	}

	.item:hover {
		background: var(--rs-bg-hover, rgba(255, 255, 255, 0.05));
		border-radius: 4px;
		padding: 4px 6px;
		margin: 0 -6px;
	}

	.checkbox {
		width: 16px;
		height: 16px;
		border: 2px solid var(--rs-border-strong, rgba(255, 255, 255, 0.2));
		border-radius: 4px;
		display: flex;
		align-items: center;
		justify-content: center;
		flex-shrink: 0;
		cursor: pointer;
	}

	.checkbox.checked {
		background: #7c3aed;
		border-color: #7c3aed;
	}

	.checkbox.checked::after {
		content: "✓";
		color: white;
		font-size: 10px;
		font-weight: 700;
	}

	.item-name {
		color: var(--rs-text-primary, #e2e8f0);
	}

	.item-name.packed {
		text-decoration: line-through;
		color: var(--rs-text-muted, #64748b);
	}

	.item-qty {
		font-size: 10px;
		color: #94a3b8;
		margin-left: auto;
	}

	.add-form {
		padding: 8px 12px;
		border-top: 1px solid #e2e8f0;
	}

	.add-form input {
		width: 100%;
		padding: 6px 8px;
		border: 1px solid #e2e8f0;
		border-radius: 4px;
		font-size: 12px;
		outline: none;
	}

	.add-form input:focus {
		border-color: #7c3aed;
	}
`;

export interface PackingEntry {
	id: string;
	name: string;
	category?: string;
	packed: boolean;
	quantity: number;
}

declare global {
	interface HTMLElementTagNameMap {
		"folk-packing-list": FolkPackingList;
	}
}

export class FolkPackingList extends FolkShape {
	static override tagName = "folk-packing-list";

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

	#items: PackingEntry[] = [];
	#listEl: HTMLElement | null = null;
	#progressTextEl: HTMLElement | null = null;
	#progressFillEl: HTMLElement | null = null;

	get items() { return this.#items; }
	set items(v: PackingEntry[]) {
		this.#items = v;
		this.#render();
		this.dispatchEvent(new CustomEvent("content-change"));
	}

	get packedCount() {
		return this.#items.filter((i) => i.packed).length;
	}

	addItem(item: PackingEntry) {
		this.#items.push(item);
		this.#render();
		this.dispatchEvent(new CustomEvent("content-change"));
	}

	toggleItem(id: string) {
		const item = this.#items.find((i) => i.id === id);
		if (item) {
			item.packed = !item.packed;
			this.#render();
			this.dispatchEvent(new CustomEvent("content-change"));
		}
	}

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

		const wrapper = document.createElement("div");
		wrapper.innerHTML = html`
			<div class="header">
				<span class="header-title">
					<span>🎒</span>
					<span>Packing List</span>
				</span>
				<div class="header-actions">
					<button class="close-btn" title="Close">×</button>
				</div>
			</div>
			<div class="progress-info">
				<span class="progress-text"></span>
				<div class="progress-bar"><div class="progress-fill"></div></div>
			</div>
			<div class="packing-list"></div>
			<div class="add-form">
				<input type="text" placeholder="Add item..." class="add-input" />
			</div>
		`;

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

		this.#listEl = wrapper.querySelector(".packing-list");
		this.#progressTextEl = wrapper.querySelector(".progress-text");
		this.#progressFillEl = wrapper.querySelector(".progress-fill");

		const closeBtn = wrapper.querySelector(".close-btn") as HTMLButtonElement;
		const addInput = wrapper.querySelector(".add-input") as HTMLInputElement;

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

		addInput.addEventListener("keydown", (e) => {
			if (e.key === "Enter" && addInput.value.trim()) {
				e.stopPropagation();
				this.addItem({
					id: `pack-${Date.now()}`,
					name: addInput.value.trim(),
					packed: false,
					quantity: 1,
				});
				addInput.value = "";
			}
		});
		addInput.addEventListener("click", (e) => e.stopPropagation());

		this.#render();
		return root;
	}

	#escapeHtml(text: string): string {
		const div = document.createElement("div");
		div.textContent = text;
		return div.innerHTML;
	}

	#render() {
		if (!this.#listEl || !this.#progressTextEl || !this.#progressFillEl) return;

		const total = this.#items.length;
		const packed = this.packedCount;
		const pct = total > 0 ? (packed / total) * 100 : 0;

		this.#progressTextEl.textContent = `${packed}/${total} packed`;
		this.#progressFillEl.style.width = `${pct}%`;

		if (total === 0) {
			this.#listEl.innerHTML = '<div style="text-align:center;padding:16px;color:#94a3b8;font-size:12px">No items yet</div>';
			return;
		}

		// Group by category
		const groups = new Map<string, PackingEntry[]>();
		for (const item of this.#items) {
			const cat = item.category || "Other";
			if (!groups.has(cat)) groups.set(cat, []);
			groups.get(cat)!.push(item);
		}

		let result = "";
		for (const [cat, items] of groups) {
			result += `<div class="category-label">${this.#escapeHtml(cat)}</div>`;
			for (const item of items) {
				result += `
					<div class="item" data-id="${item.id}">
						<div class="checkbox ${item.packed ? "checked" : ""}"></div>
						<span class="item-name ${item.packed ? "packed" : ""}">${this.#escapeHtml(item.name)}</span>
						${item.quantity > 1 ? `<span class="item-qty">x${item.quantity}</span>` : ""}
					</div>
				`;
			}
		}

		this.#listEl.innerHTML = result;

		// Add click handlers for checkboxes
		this.#listEl.querySelectorAll(".item").forEach((el) => {
			el.addEventListener("click", (e) => {
				e.stopPropagation();
				const id = (el as HTMLElement).dataset.id;
				if (id) this.toggleItem(id);
			});
		});
	}

	static override fromData(data: Record<string, any>): FolkPackingList {
		const shape = FolkShape.fromData(data) as FolkPackingList;
		if (Array.isArray(data.items)) shape.items = data.items;
		return shape;
	}

	override applyData(data: Record<string, any>): void {
		super.applyData(data);
		if (Array.isArray(data.items) && JSON.stringify(data.items) !== JSON.stringify(this.items)) this.items = data.items;
	}

	override toJSON() {
		return {
			...super.toJSON(),
			type: "folk-packing-list",
			items: this.#items,
		};
	}
}
