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

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

	.itinerary-container {
		padding: 12px;
		max-height: 400px;
		overflow-y: auto;
	}

	.day-group {
		margin-bottom: 12px;
	}

	.day-label {
		font-size: 11px;
		font-weight: 600;
		color: #0d9488;
		padding: 4px 0;
		border-bottom: 1px solid var(--rs-border, rgba(255, 255, 255, 0.1));
		margin-bottom: 6px;
	}

	.item {
		display: flex;
		align-items: flex-start;
		gap: 8px;
		padding: 6px 8px;
		font-size: 12px;
		border-radius: 4px;
		margin-bottom: 4px;
		background: var(--rs-bg-surface-sunken, #0f172a);
	}

	.item:hover {
		background: var(--rs-bg-hover, rgba(255, 255, 255, 0.05));
	}

	.item-icon {
		font-size: 14px;
		flex-shrink: 0;
		margin-top: 1px;
	}

	.item-content {
		flex: 1;
		min-width: 0;
	}

	.item-title {
		font-weight: 500;
		color: var(--rs-text-primary, #e2e8f0);
	}

	.item-time {
		font-size: 10px;
		color: var(--rs-text-muted, #64748b);
		margin-top: 1px;
	}

	.item-desc {
		font-size: 11px;
		color: #94a3b8;
		margin-top: 2px;
	}

	.category-badge {
		font-size: 9px;
		padding: 1px 5px;
		border-radius: 3px;
		background: var(--rs-bg-surface-raised, #334155);
		color: var(--rs-text-secondary, #94a3b8);
		white-space: nowrap;
	}

	.add-form {
		padding: 8px 12px;
		border-top: 1px solid var(--rs-border, rgba(255, 255, 255, 0.1));
	}

	.add-form input {
		width: 100%;
		padding: 6px 8px;
		border: 1px solid var(--rs-input-border, #e2e8f0);
		border-radius: 4px;
		font-size: 12px;
		outline: none;
		background: var(--rs-input-bg, #fff);
		color: var(--rs-input-text, inherit);
	}

	.add-form input:focus {
		border-color: #0d9488;
	}

	.empty-state {
		text-align: center;
		padding: 20px;
		color: #94a3b8;
		font-size: 12px;
	}
`;

export interface ItineraryEntry {
	id: string;
	title: string;
	date?: string;
	startTime?: string;
	endTime?: string;
	category: string;
	description?: string;
}

const CATEGORY_ICONS: Record<string, string> = {
	FLIGHT: "✈️",
	TRANSPORT: "🚌",
	ACCOMMODATION: "🏨",
	ACTIVITY: "🎯",
	MEAL: "🍽️",
	FREE_TIME: "☀️",
	OTHER: "📌",
};

declare global {
	interface HTMLElementTagNameMap {
		"folk-itinerary": FolkItinerary;
	}
}

export class FolkItinerary extends FolkShape {
	static override tagName = "folk-itinerary";

	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: ItineraryEntry[] = [];
	#tripTitle = "Trip Itinerary";
	#listEl: HTMLElement | null = null;

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

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

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

	set tripTitle(title: string) {
		this.#tripTitle = title;
		this.#render();
	}

	addItem(item: ItineraryEntry) {
		this.#items.push(item);
		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 class="title-text">Itinerary</span>
				</span>
				<div class="header-actions">
					<button class="close-btn" title="Close">×</button>
				</div>
			</div>
			<div class="itinerary-container">
				<div class="item-list"></div>
			</div>
			<div class="add-form">
				<input type="text" placeholder="Add itinerary 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(".item-list");
		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: `item-${Date.now()}`,
					title: addInput.value.trim(),
					category: "ACTIVITY",
				});
				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) return;

		if (this.#items.length === 0) {
			this.#listEl.innerHTML = '<div class="empty-state">No items yet. Type below to add one.</div>';
			return;
		}

		// Group by date
		const groups = new Map<string, ItineraryEntry[]>();
		const noDate: ItineraryEntry[] = [];

		for (const item of this.#items) {
			if (item.date) {
				const key = item.date.split("T")[0];
				if (!groups.has(key)) groups.set(key, []);
				groups.get(key)!.push(item);
			} else {
				noDate.push(item);
			}
		}

		let result = "";

		// Sorted date groups
		const sortedDates = Array.from(groups.keys()).sort();
		for (const dateStr of sortedDates) {
			const items = groups.get(dateStr)!;
			const date = new Date(dateStr);
			const label = date.toLocaleDateString("en-US", { weekday: "short", month: "short", day: "numeric" });
			result += `<div class="day-group">`;
			result += `<div class="day-label">${this.#escapeHtml(label)}</div>`;
			for (const item of items) {
				result += this.#renderItem(item);
			}
			result += `</div>`;
		}

		// Items without dates
		if (noDate.length > 0) {
			result += `<div class="day-group">`;
			result += `<div class="day-label">Unscheduled</div>`;
			for (const item of noDate) {
				result += this.#renderItem(item);
			}
			result += `</div>`;
		}

		this.#listEl.innerHTML = result;
	}

	#renderItem(item: ItineraryEntry): string {
		const icon = CATEGORY_ICONS[item.category] || CATEGORY_ICONS.OTHER;
		let timeStr = "";
		if (item.startTime) {
			timeStr = item.startTime;
			if (item.endTime) timeStr += ` - ${item.endTime}`;
		}

		return `
			<div class="item">
				<span class="item-icon">${icon}</span>
				<div class="item-content">
					<div class="item-title">${this.#escapeHtml(item.title)}</div>
					${timeStr ? `<div class="item-time">${this.#escapeHtml(timeStr)}</div>` : ""}
					${item.description ? `<div class="item-desc">${this.#escapeHtml(item.description)}</div>` : ""}
				</div>
				<span class="category-badge">${this.#escapeHtml(item.category)}</span>
			</div>
		`;
	}

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

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

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