import { FolkShape } from "./folk-shape";
import { css, html } from "./tags";

export type GoogleService = "gmail" | "drive" | "photos" | "calendar";
export type ItemVisibility = "local" | "shared";

const SERVICE_ICONS: Record<GoogleService, string> = {
	gmail: "📧",
	drive: "📁",
	photos: "📷",
	calendar: "📅",
};

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

	.card {
		width: 100%;
		height: 100%;
		padding: 12px;
		box-sizing: border-box;
		position: relative;
		cursor: move;
	}

	.card.local {
		border: 2px dashed #6366f1;
	}

	.card.shared {
		border: 2px solid #22c55e;
	}

	.visibility-badge {
		position: absolute;
		top: 8px;
		right: 8px;
		font-size: 12px;
		cursor: pointer;
	}

	.visibility-badge:hover {
		transform: scale(1.2);
	}

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

	.service-icon {
		font-size: 20px;
	}

	.title {
		font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
		font-size: 14px;
		font-weight: 600;
		color: var(--rs-text-primary, #e2e8f0);
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
		flex: 1;
	}

	.preview {
		font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
		font-size: 12px;
		color: var(--rs-text-muted, #64748b);
		line-height: 1.4;
		overflow: hidden;
		text-overflow: ellipsis;
		display: -webkit-box;
		-webkit-line-clamp: 2;
		-webkit-box-orient: vertical;
	}

	.date {
		font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
		font-size: 11px;
		color: var(--rs-text-secondary, #94a3b8);
		margin-top: 8px;
	}

	.thumbnail {
		width: 100%;
		height: 80px;
		object-fit: cover;
		border-radius: 4px;
		margin-top: 8px;
	}
`;

declare global {
	interface HTMLElementTagNameMap {
		"folk-google-item": FolkGoogleItem;
	}
}

export class FolkGoogleItem extends FolkShape {
	static override tagName = "folk-google-item";

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

	#itemId = "";
	#service: GoogleService = "drive";
	#title = "Untitled";
	#preview = "";
	#date: number = Date.now();
	#thumbnailUrl = "";
	#visibility: ItemVisibility = "local";

	get itemId() {
		return this.#itemId;
	}
	set itemId(value: string) {
		this.#itemId = value;
		this.requestUpdate("itemId");
	}

	get service() {
		return this.#service;
	}
	set service(value: GoogleService) {
		this.#service = value;
		this.requestUpdate("service");
	}

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

	get preview() {
		return this.#preview;
	}
	set preview(value: string) {
		this.#preview = value;
		this.requestUpdate("preview");
	}

	get date() {
		return this.#date;
	}
	set date(value: number) {
		this.#date = value;
		this.requestUpdate("date");
	}

	get thumbnailUrl() {
		return this.#thumbnailUrl;
	}
	set thumbnailUrl(value: string) {
		this.#thumbnailUrl = value;
		this.requestUpdate("thumbnailUrl");
	}

	get visibility() {
		return this.#visibility;
	}
	set visibility(value: ItemVisibility) {
		this.#visibility = value;
		this.requestUpdate("visibility");
	}

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

		// Read attributes
		this.#itemId = this.getAttribute("item-id") || "";
		this.#service = (this.getAttribute("service") as GoogleService) || "drive";
		this.#title = this.getAttribute("title") || "Untitled";
		this.#preview = this.getAttribute("preview") || "";
		this.#date = parseInt(this.getAttribute("date") || String(Date.now()), 10);
		this.#thumbnailUrl = this.getAttribute("thumbnail-url") || "";
		this.#visibility = (this.getAttribute("visibility") as ItemVisibility) || "local";

		const wrapper = document.createElement("div");
		wrapper.innerHTML = html`
			<div class="card ${this.#visibility}" data-drag>
				<span class="visibility-badge" title="Toggle visibility">
					${this.#visibility === "local" ? "🔒" : "🌐"}
				</span>
				<div class="header">
					<span class="service-icon">${SERVICE_ICONS[this.#service]}</span>
					<span class="title">${this.#escapeHtml(this.#title)}</span>
				</div>
				${this.#preview ? `<div class="preview">${this.#escapeHtml(this.#preview)}</div>` : ""}
				<div class="date">${this.#formatDate(this.#date)}</div>
				${
					this.#thumbnailUrl && this.height > 100
						? `<img class="thumbnail" src="${this.#thumbnailUrl}" alt="" />`
						: ""
				}
			</div>
		`;

		// Replace the container div (slot's parent) with our card
		const slot = root.querySelector("slot");
		const containerDiv = slot?.parentElement as HTMLElement;
		const cardEl = wrapper.querySelector(".card");
		if (containerDiv && cardEl) {
			containerDiv.replaceWith(cardEl);
		}

		// Toggle visibility on badge click
		const badge = root.querySelector(".visibility-badge") as HTMLElement;
		const card = root.querySelector(".card") as HTMLElement;

		badge?.addEventListener("click", (e) => {
			e.stopPropagation();
			this.#visibility = this.#visibility === "local" ? "shared" : "local";

			badge.textContent = this.#visibility === "local" ? "🔒" : "🌐";
			card.classList.remove("local", "shared");
			card.classList.add(this.#visibility);

			this.dispatchEvent(
				new CustomEvent("visibility-change", {
					detail: { visibility: this.#visibility, itemId: this.#itemId },
					bubbles: true,
				})
			);
		});

		return root;
	}

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

	#formatDate(timestamp: number): string {
		const now = new Date();
		const date = new Date(timestamp);
		const diffDays = Math.floor(
			(now.getTime() - date.getTime()) / (1000 * 60 * 60 * 24)
		);

		if (diffDays === 0) return "Today";
		if (diffDays === 1) return "Yesterday";
		if (diffDays < 7) return `${diffDays}d ago`;
		return date.toLocaleDateString();
	}

	static override fromData(data: Record<string, any>): FolkGoogleItem {
		const shape = FolkShape.fromData(data) as FolkGoogleItem;
		if (data.itemId) shape.itemId = data.itemId;
		if (data.service) shape.service = data.service;
		if (data.title) shape.title = data.title;
		if (data.preview) shape.preview = data.preview;
		if (data.date !== undefined) shape.date = data.date;
		if (data.thumbnailUrl) shape.thumbnailUrl = data.thumbnailUrl;
		if (data.visibility) shape.visibility = data.visibility;
		return shape;
	}

	override toJSON() {
		return {
			...super.toJSON(),
			type: "folk-google-item",
			itemId: this.itemId,
			service: this.service,
			title: this.title,
			preview: this.preview,
			date: this.date,
			thumbnailUrl: this.thumbnailUrl,
			visibility: this.visibility,
		};
	}

	override applyData(data: Record<string, any>): void {
		super.applyData(data);
		if (data.itemId !== undefined && this.itemId !== data.itemId) this.itemId = data.itemId;
		if (data.service !== undefined && this.service !== data.service) this.service = data.service;
		if (data.title !== undefined && this.title !== data.title) this.title = data.title;
		if (data.preview !== undefined && this.preview !== data.preview) this.preview = data.preview;
		if (data.date !== undefined && this.date !== data.date) this.date = data.date;
		if (data.thumbnailUrl !== undefined && this.thumbnailUrl !== data.thumbnailUrl) this.thumbnailUrl = data.thumbnailUrl;
		if (data.visibility !== undefined && this.visibility !== data.visibility) this.visibility = data.visibility;
	}
}

/**
 * Helper to create Google item props
 */
export function createGoogleItemProps(
	service: GoogleService,
	title: string,
	options: Partial<{
		itemId: string;
		preview: string;
		date: number;
		thumbnailUrl: string;
		visibility: ItemVisibility;
	}> = {}
) {
	return {
		service,
		title,
		itemId: options.itemId || crypto.randomUUID(),
		preview: options.preview || "",
		date: options.date || Date.now(),
		thumbnailUrl: options.thumbnailUrl || "",
		visibility: options.visibility || "local",
	};
}
