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: 180px;
	}

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

	.dest-body {
		padding: 12px;
	}

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

	.dest-country {
		font-size: 12px;
		color: var(--rs-text-muted, #64748b);
		margin-bottom: 8px;
	}

	.dest-dates {
		display: flex;
		gap: 12px;
		font-size: 11px;
		color: var(--rs-text-secondary, #94a3b8);
		margin-bottom: 10px;
		padding: 6px 8px;
		background: var(--rs-bg-surface-sunken, #0f172a);
		border-radius: 4px;
	}

	.dest-dates span {
		display: flex;
		align-items: center;
		gap: 4px;
	}

	.dest-dates .label {
		color: #94a3b8;
		font-weight: 500;
	}

	.dest-notes {
		font-size: 12px;
		color: var(--rs-text-secondary, #94a3b8);
		line-height: 1.5;
		padding: 8px;
		background: var(--rs-bg-surface-sunken, #0f172a);
		border-radius: 4px;
		border: 1px solid var(--rs-border, rgba(255, 255, 255, 0.1));
		min-height: 40px;
		white-space: pre-wrap;
	}

	.dest-notes[contenteditable]:focus {
		outline: none;
		border-color: #059669;
	}

	.coords {
		font-size: 10px;
		color: #94a3b8;
		margin-top: 6px;
	}

	.empty-name {
		color: #94a3b8;
		font-style: italic;
	}
`;

declare global {
	interface HTMLElementTagNameMap {
		"folk-destination": FolkDestination;
	}
}

export class FolkDestination extends FolkShape {
	static override tagName = "folk-destination";

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

	#destName = "";
	#country = "";
	#lat: number | null = null;
	#lng: number | null = null;
	#arrivalDate = "";
	#departureDate = "";
	#notes = "";
	#nameEl: HTMLElement | null = null;
	#countryEl: HTMLElement | null = null;
	#notesEl: HTMLElement | null = null;
	#datesEl: HTMLElement | null = null;

	get destName() { return this.#destName; }
	set destName(v: string) {
		this.#destName = v;
		if (this.#nameEl) this.#nameEl.textContent = v || "Unnamed destination";
		this.dispatchEvent(new CustomEvent("content-change"));
	}

	get country() { return this.#country; }
	set country(v: string) {
		this.#country = v;
		if (this.#countryEl) this.#countryEl.textContent = v;
		this.dispatchEvent(new CustomEvent("content-change"));
	}

	get lat() { return this.#lat; }
	set lat(v: number | null) { this.#lat = v; }

	get lng() { return this.#lng; }
	set lng(v: number | null) { this.#lng = v; }

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

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

	get notes() { return this.#notes; }
	set notes(v: string) {
		this.#notes = v;
		if (this.#notesEl && this.#notesEl.textContent !== v) {
			this.#notesEl.textContent = v;
		}
		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>Destination</span>
				</span>
				<div class="header-actions">
					<button class="close-btn" title="Close">×</button>
				</div>
			</div>
			<div class="dest-body">
				<div class="dest-name"></div>
				<div class="dest-country"></div>
				<div class="dest-dates"></div>
				<div class="dest-notes" contenteditable="true"></div>
			</div>
		`;

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

		this.#nameEl = wrapper.querySelector(".dest-name");
		this.#countryEl = wrapper.querySelector(".dest-country");
		this.#datesEl = wrapper.querySelector(".dest-dates");
		this.#notesEl = wrapper.querySelector(".dest-notes");

		if (this.#nameEl) {
			this.#nameEl.textContent = this.#destName || "Unnamed destination";
			if (!this.#destName) this.#nameEl.classList.add("empty-name");
		}
		if (this.#countryEl) this.#countryEl.textContent = this.#country;

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

		if (this.#notesEl) {
			this.#notesEl.textContent = this.#notes;
			this.#notesEl.addEventListener("input", () => {
				this.#notes = this.#notesEl!.textContent || "";
				this.dispatchEvent(new CustomEvent("content-change"));
			});
			this.#notesEl.addEventListener("click", (e) => e.stopPropagation());
		}

		this.#renderDates();
		return root;
	}

	#renderDates() {
		if (!this.#datesEl) return;
		if (!this.#arrivalDate && !this.#departureDate) {
			this.#datesEl.style.display = "none";
			return;
		}
		this.#datesEl.style.display = "flex";
		let result = "";
		if (this.#arrivalDate) {
			const d = new Date(this.#arrivalDate);
			result += `<span><span class="label">Arrive:</span> ${d.toLocaleDateString("en-US", { month: "short", day: "numeric" })}</span>`;
		}
		if (this.#departureDate) {
			const d = new Date(this.#departureDate);
			result += `<span><span class="label">Depart:</span> ${d.toLocaleDateString("en-US", { month: "short", day: "numeric" })}</span>`;
		}
		this.#datesEl.innerHTML = result;
	}

	static override fromData(data: Record<string, any>): FolkDestination {
		const shape = FolkShape.fromData(data) as FolkDestination;
		if (data.destName !== undefined) shape.destName = data.destName;
		if (data.country !== undefined) shape.country = data.country;
		if (data.lat != null) shape.lat = data.lat;
		if (data.lng != null) shape.lng = data.lng;
		if (data.arrivalDate !== undefined) shape.arrivalDate = data.arrivalDate;
		if (data.departureDate !== undefined) shape.departureDate = data.departureDate;
		if (data.notes !== undefined) shape.notes = data.notes;
		return shape;
	}

	override applyData(data: Record<string, any>): void {
		super.applyData(data);
		if (data.destName !== undefined && data.destName !== this.destName) this.destName = data.destName;
		if (data.country !== undefined && data.country !== this.country) this.country = data.country;
		if (data.lat != null && data.lat !== this.lat) this.lat = data.lat;
		if (data.lng != null && data.lng !== this.lng) this.lng = data.lng;
		if (data.arrivalDate !== undefined && data.arrivalDate !== this.arrivalDate) this.arrivalDate = data.arrivalDate;
		if (data.departureDate !== undefined && data.departureDate !== this.departureDate) this.departureDate = data.departureDate;
		if (data.notes !== undefined && data.notes !== this.notes) this.notes = data.notes;
	}

	override toJSON() {
		return {
			...super.toJSON(),
			type: "folk-destination",
			destName: this.#destName,
			country: this.#country,
			lat: this.#lat,
			lng: this.#lng,
			arrivalDate: this.#arrivalDate,
			departureDate: this.#departureDate,
			notes: this.#notes,
		};
	}
}
