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: 280px;
		min-height: 160px;
	}

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

	.header.FLIGHT { background: #2563eb; }
	.header.HOTEL { background: #7c3aed; }
	.header.CAR_RENTAL { background: #d97706; }
	.header.TRAIN { background: #059669; }
	.header.BUS { background: #0891b2; }
	.header.FERRY { background: #0284c7; }
	.header.ACTIVITY { background: #0d9488; }
	.header.RESTAURANT { background: #ea580c; }
	.header.OTHER { background: #475569; }

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

	.booking-body {
		padding: 12px;
	}

	.provider {
		font-size: 16px;
		font-weight: 700;
		color: var(--rs-text-primary, #e2e8f0);
		margin-bottom: 4px;
	}

	.details {
		font-size: 12px;
		color: var(--rs-text-secondary, #94a3b8);
		line-height: 1.5;
		margin-bottom: 8px;
	}

	.meta-row {
		display: flex;
		gap: 12px;
		font-size: 11px;
		margin-bottom: 4px;
	}

	.meta-item {
		display: flex;
		align-items: center;
		gap: 4px;
	}

	.meta-label {
		color: var(--rs-text-secondary, #94a3b8);
	}

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

	.confirmation {
		margin-top: 8px;
		padding: 6px 8px;
		background: var(--rs-bg-surface-sunken, #0f172a);
		border-radius: 4px;
		font-size: 11px;
		display: flex;
		justify-content: space-between;
	}

	.confirmation .label {
		color: var(--rs-text-secondary, #94a3b8);
	}

	.confirmation .code {
		font-family: monospace;
		font-weight: 600;
		color: var(--rs-text-primary, #e2e8f0);
	}

	.cost {
		font-size: 18px;
		font-weight: 700;
		color: var(--rs-text-primary, #e2e8f0);
		margin-top: 8px;
	}

	.status-badge {
		display: inline-block;
		font-size: 10px;
		font-weight: 600;
		padding: 2px 8px;
		border-radius: 10px;
		margin-top: 8px;
	}

	.status-badge.PLANNED {
		background: var(--rs-bg-surface-raised, #334155);
		color: var(--rs-text-secondary, #94a3b8);
	}

	.status-badge.BOOKED {
		background: #dbeafe;
		color: #1d4ed8;
	}

	.status-badge.CONFIRMED {
		background: #dcfce7;
		color: #15803d;
	}

	.status-badge.CANCELLED {
		background: #fee2e2;
		color: #dc2626;
	}
`;

const BOOKING_TYPE_ICONS: Record<string, string> = {
	FLIGHT: "✈️",
	HOTEL: "🏨",
	CAR_RENTAL: "🚗",
	TRAIN: "🚄",
	BUS: "🚌",
	FERRY: "⛴️",
	ACTIVITY: "🎯",
	RESTAURANT: "🍽️",
	OTHER: "📌",
};

declare global {
	interface HTMLElementTagNameMap {
		"folk-booking": FolkBooking;
	}
}

export class FolkBooking extends FolkShape {
	static override tagName = "folk-booking";

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

	#bookingType = "OTHER";
	#provider = "";
	#confirmationNumber = "";
	#details = "";
	#cost: number | null = null;
	#currency = "USD";
	#startDate = "";
	#endDate = "";
	#bookingStatus = "PLANNED";

	#headerEl: HTMLElement | null = null;
	#bodyEl: HTMLElement | null = null;

	get bookingType() { return this.#bookingType; }
	set bookingType(v: string) {
		this.#bookingType = v;
		this.#render();
		this.dispatchEvent(new CustomEvent("content-change"));
	}

	get provider() { return this.#provider; }
	set provider(v: string) {
		this.#provider = v;
		this.#render();
		this.dispatchEvent(new CustomEvent("content-change"));
	}

	get confirmationNumber() { return this.#confirmationNumber; }
	set confirmationNumber(v: string) {
		this.#confirmationNumber = v;
		this.#render();
		this.dispatchEvent(new CustomEvent("content-change"));
	}

	get details() { return this.#details; }
	set details(v: string) {
		this.#details = v;
		this.#render();
		this.dispatchEvent(new CustomEvent("content-change"));
	}

	get cost() { return this.#cost; }
	set cost(v: number | null) {
		this.#cost = v;
		this.#render();
		this.dispatchEvent(new CustomEvent("content-change"));
	}

	get currency() { return this.#currency; }
	set currency(v: string) { this.#currency = v; this.#render(); }

	get startDate() { return this.#startDate; }
	set startDate(v: string) { this.#startDate = v; this.#render(); }

	get endDate() { return this.#endDate; }
	set endDate(v: string) { this.#endDate = v; this.#render(); }

	get bookingStatus() { return this.#bookingStatus; }
	set bookingStatus(v: string) {
		this.#bookingStatus = v;
		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 OTHER">
				<span class="header-title">
					<span class="type-icon">📌</span>
					<span class="type-label">Booking</span>
				</span>
				<div class="header-actions">
					<button class="close-btn" title="Close">×</button>
				</div>
			</div>
			<div class="booking-body"></div>
		`;

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

		this.#headerEl = wrapper.querySelector(".header");
		this.#bodyEl = wrapper.querySelector(".booking-body");

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

		this.#render();
		return root;
	}

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

	#formatDate(dateStr: string): string {
		if (!dateStr) return "";
		const d = new Date(dateStr);
		return d.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
	}

	#render() {
		if (!this.#headerEl || !this.#bodyEl) return;

		const icon = BOOKING_TYPE_ICONS[this.#bookingType] || BOOKING_TYPE_ICONS.OTHER;

		// Update header
		this.#headerEl.className = `header ${this.#bookingType}`;
		const iconEl = this.#headerEl.querySelector(".type-icon");
		const labelEl = this.#headerEl.querySelector(".type-label");
		if (iconEl) iconEl.textContent = icon;
		if (labelEl) labelEl.textContent = this.#bookingType.replace("_", " ");

		// Build body
		let bodyHTML = "";

		if (this.#provider) {
			bodyHTML += `<div class="provider">${this.#escapeHtml(this.#provider)}</div>`;
		}

		if (this.#details) {
			bodyHTML += `<div class="details">${this.#escapeHtml(this.#details)}</div>`;
		}

		if (this.#startDate || this.#endDate) {
			bodyHTML += `<div class="meta-row">`;
			if (this.#startDate) {
				bodyHTML += `<div class="meta-item"><span class="meta-label">From:</span><span class="meta-value">${this.#formatDate(this.#startDate)}</span></div>`;
			}
			if (this.#endDate) {
				bodyHTML += `<div class="meta-item"><span class="meta-label">To:</span><span class="meta-value">${this.#formatDate(this.#endDate)}</span></div>`;
			}
			bodyHTML += `</div>`;
		}

		if (this.#confirmationNumber) {
			bodyHTML += `<div class="confirmation"><span class="label">Confirmation</span><span class="code">${this.#escapeHtml(this.#confirmationNumber)}</span></div>`;
		}

		if (this.#cost !== null) {
			bodyHTML += `<div class="cost">${this.#currency} ${this.#cost.toLocaleString()}</div>`;
		}

		bodyHTML += `<span class="status-badge ${this.#bookingStatus}">${this.#bookingStatus}</span>`;

		this.#bodyEl.innerHTML = bodyHTML;
	}

	static override fromData(data: Record<string, any>): FolkBooking {
		const shape = FolkShape.fromData(data) as FolkBooking;
		if (data.bookingType !== undefined) shape.bookingType = data.bookingType;
		if (data.provider !== undefined) shape.provider = data.provider;
		if (data.confirmationNumber !== undefined) shape.confirmationNumber = data.confirmationNumber;
		if (data.details !== undefined) shape.details = data.details;
		if (data.cost !== undefined) shape.cost = data.cost;
		if (data.currency !== undefined) shape.currency = data.currency;
		if (data.startDate !== undefined) shape.startDate = data.startDate;
		if (data.endDate !== undefined) shape.endDate = data.endDate;
		if (data.bookingStatus !== undefined) shape.bookingStatus = data.bookingStatus;
		return shape;
	}

	override applyData(data: Record<string, any>): void {
		super.applyData(data);
		if (data.bookingType !== undefined && data.bookingType !== this.bookingType) this.bookingType = data.bookingType;
		if (data.provider !== undefined && data.provider !== this.provider) this.provider = data.provider;
		if (data.confirmationNumber !== undefined && data.confirmationNumber !== this.confirmationNumber) this.confirmationNumber = data.confirmationNumber;
		if (data.details !== undefined && data.details !== this.details) this.details = data.details;
		if (data.cost !== undefined && data.cost !== this.cost) this.cost = data.cost;
		if (data.currency !== undefined && data.currency !== this.currency) this.currency = data.currency;
		if (data.startDate !== undefined && data.startDate !== this.startDate) this.startDate = data.startDate;
		if (data.endDate !== undefined && data.endDate !== this.endDate) this.endDate = data.endDate;
		if (data.bookingStatus !== undefined && data.bookingStatus !== this.bookingStatus) this.bookingStatus = data.bookingStatus;
	}

	override toJSON() {
		return {
			...super.toJSON(),
			type: "folk-booking",
			bookingType: this.#bookingType,
			provider: this.#provider,
			confirmationNumber: this.#confirmationNumber,
			details: this.#details,
			cost: this.#cost,
			currency: this.#currency,
			startDate: this.#startDate,
			endDate: this.#endDate,
			bookingStatus: this.#bookingStatus,
		};
	}
}
