/**
 * folk-video-player — Video library browser + player.
 *
 * Lists videos from the API, plays them with native <video>,
 * and provides HLS live stream viewing.
 */

class FolkVideoPlayer extends HTMLElement {
	private shadow: ShadowRoot;
	private space = "demo";
	private videos: Array<{ name: string; size: number; duration?: string; date?: string }> = [];
	private currentVideo: string | null = null;
	private mode: "library" | "live" = "library";
	private streamKey = "";
	private searchTerm = "";
	private isDemo = false;

	constructor() {
		super();
		this.shadow = this.attachShadow({ mode: "open" });
	}

	connectedCallback() {
		this.space = this.getAttribute("space") || "demo";
		if (this.space === "demo") { this.loadDemoData(); return; }
		this.loadVideos();
	}

	private loadDemoData() {
		this.isDemo = true;
		this.videos = [
			{ name: "community-meeting-2026-02-15.mp4", size: 524288000, duration: "1:23:45", date: "Feb 15, 2026" },
			{ name: "rspace-demo-walkthrough.mp4", size: 157286400, duration: "18:32", date: "Feb 12, 2026" },
			{ name: "design-sprint-day1.webm", size: 892108800, duration: "2:45:10", date: "Feb 10, 2026" },
			{ name: "interview-cosmolocal-founders.mp4", size: 1073741824, duration: "52:18", date: "Feb 7, 2026" },
			{ name: "workshop-local-first-data.mp4", size: 734003200, duration: "1:35:42", date: "Feb 3, 2026" },
			{ name: "lightning-talks-feb2026.webm", size: 445644800, duration: "42:15", date: "Jan 28, 2026" },
		];
		this.currentVideo = this.videos[0].name;
		this.render();
	}

	private async loadVideos() {
		try {
			const base = window.location.pathname.replace(/\/$/, "");
			const resp = await fetch(`${base}/api/videos`);
			if (resp.ok) {
				const data = await resp.json();
				this.videos = data.videos || [];
			}
		} catch { /* ignore */ }
		this.render();
	}

	private formatSize(bytes: number): string {
		if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)} KB`;
		if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
		return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`;
	}

	private getExtension(name: string): string {
		return name.substring(name.lastIndexOf(".") + 1).toLowerCase();
	}

	private isPlayable(name: string): boolean {
		const ext = this.getExtension(name);
		return ["mp4", "webm", "m4v"].includes(ext);
	}

	private render() {
		this.shadow.innerHTML = `
			<style>
				:host { display: block; min-height: 60vh; font-family: system-ui, sans-serif; color: #e2e8f0; }
				.container { max-width: 1200px; margin: 0 auto; }
				.rapp-nav { display: flex; align-items: center; gap: 8px; margin-bottom: 16px; min-height: 36px; }
			.rapp-nav__title { font-size: 13px; font-weight: 500; color: #64748b; flex: 1; text-align: right; }
				.tab { padding: 0.5rem 1.25rem; border-radius: 8px; border: 1px solid #334155; background: transparent; color: #94a3b8; cursor: pointer; font-size: 0.875rem; }
				.tab.active { background: #ef4444; color: white; border-color: #ef4444; }
				.layout { display: grid; grid-template-columns: 300px 1fr; gap: 1.5rem; }
				.sidebar { background: rgba(15,23,42,0.5); border: 1px solid #1e293b; border-radius: 12px; padding: 1rem; max-height: 70vh; overflow-y: auto; }
				.video-item { padding: 0.75rem; border-radius: 8px; cursor: pointer; border: 1px solid transparent; margin-bottom: 0.25rem; }
				.video-item:hover { background: rgba(51,65,85,0.5); }
				.video-item.active { background: rgba(239,68,68,0.1); border-color: #ef4444; }
				.video-name { font-size: 0.875rem; font-weight: 500; word-break: break-all; }
				.video-meta { font-size: 0.75rem; color: #64748b; margin-top: 0.25rem; }
				.player-area { background: #000; border-radius: 12px; overflow: hidden; aspect-ratio: 16/9; display: flex; align-items: center; justify-content: center; }
				video { width: 100%; height: 100%; }
				.placeholder { text-align: center; color: #64748b; }
				.placeholder-icon { font-size: 3rem; margin-bottom: 1rem; }
				.info-bar { margin-top: 1rem; display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 0.75rem; }
				.info-name { font-weight: 500; }
				.actions { display: flex; gap: 0.5rem; }
				.btn { padding: 0.5rem 1rem; border-radius: 8px; border: 1px solid #334155; background: rgba(51,65,85,0.5); color: #e2e8f0; cursor: pointer; font-size: 0.8rem; text-decoration: none; }
				.btn:hover { background: rgba(51,65,85,0.8); }
				.live-section { max-width: 640px; margin: 0 auto; }
				.live-card { background: rgba(15,23,42,0.5); border: 1px solid #1e293b; border-radius: 12px; padding: 2rem; }
				input { width: 100%; padding: 0.75rem; background: rgba(0,0,0,0.3); border: 1px solid #334155; border-radius: 8px; color: white; font-size: 0.875rem; margin-bottom: 1rem; box-sizing: border-box; }
				.btn-primary { padding: 0.75rem 1.5rem; background: #ef4444; color: white; border: none; border-radius: 8px; cursor: pointer; font-weight: 500; width: 100%; font-size: 0.875rem; }
				.btn-primary:disabled { background: #334155; color: #64748b; cursor: not-allowed; }
				.live-badge { display: inline-flex; align-items: center; gap: 0.5rem; }
				.live-dot { width: 10px; height: 10px; background: #ef4444; border-radius: 50%; animation: pulse 2s infinite; }
				@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }
				.empty { text-align: center; padding: 3rem; color: #64748b; }
				.setup { margin-top: 1.5rem; padding: 1.5rem; background: rgba(15,23,42,0.3); border: 1px solid #1e293b; border-radius: 12px; }
				.setup h3 { font-size: 0.875rem; color: #ef4444; margin-bottom: 0.5rem; }
				.setup code { display: block; background: rgba(0,0,0,0.3); padding: 0.5rem 0.75rem; border-radius: 6px; font-size: 0.75rem; color: #94a3b8; margin-top: 0.5rem; overflow-x: auto; }
				.setup ol { padding-left: 1.25rem; color: #94a3b8; font-size: 0.8rem; line-height: 1.8; }
				@media (max-width: 768px) { .layout { grid-template-columns: 1fr; } }
			</style>
			<div class="container">
				<div class="rapp-nav">
					<button class="tab ${this.mode === "library" ? "active" : ""}" data-mode="library">Video Library</button>
					${!this.isDemo ? `<button class="tab ${this.mode === "live" ? "active" : ""}" data-mode="live">Live Stream</button>` : ""}
					<span class="rapp-nav__title">${this.isDemo ? `${this.videos.length} recordings` : ""}</span>
				</div>
				${this.mode === "library" ? this.renderLibrary() : this.renderLive()}
			</div>
		`;
		this.bindEvents();
	}

	private renderLibrary(): string {
		const filteredVideos = this.searchTerm
			? this.videos.filter(v => v.name.toLowerCase().includes(this.searchTerm.toLowerCase()))
			: this.videos;

		const searchInput = `<input type="text" placeholder="Search videos..." data-input="search" value="${this.searchTerm}" style="margin-bottom:0.75rem" />`;

		const videoList = filteredVideos.length === 0
			? `<div class="empty">${this.videos.length === 0 ? "No videos yet" : "No matches"}</div>`
			: filteredVideos.map((v) => `
				<div class="video-item ${this.currentVideo === v.name ? "active" : ""}" data-name="${v.name}">
					<div class="video-name">${v.name}</div>
					<div class="video-meta">${this.getExtension(v.name).toUpperCase()} &middot; ${this.formatSize(v.size)}${v.duration ? ` &middot; ${v.duration}` : ""}${v.date ? `<br>${v.date}` : ""}</div>
				</div>
			`).join("");

		const sidebar = searchInput + videoList;

		let player: string;
		if (!this.currentVideo) {
			player = `<div class="placeholder"><div class="placeholder-icon">&#127916;</div><p>Select a video to play</p></div>`;
		} else if (this.isDemo) {
			const selectedVideo = this.videos.find(v => v.name === this.currentVideo);
			const sizeStr = selectedVideo ? this.formatSize(selectedVideo.size) : "";
			const durStr = selectedVideo?.duration || "";
			player = `<div class="placeholder" style="padding:2rem">
				<div style="width:80px;height:80px;border-radius:50%;background:rgba(239,68,68,0.15);display:flex;align-items:center;justify-content:center;margin:0 auto 1.5rem">
					<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="#ef4444" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"/></svg>
				</div>
				<p style="font-size:1.1rem;font-weight:600;margin-bottom:0.5rem;color:#e2e8f0">${this.currentVideo}</p>
				<p style="font-size:0.85rem;color:#94a3b8">${this.getExtension(this.currentVideo).toUpperCase()} &middot; ${sizeStr}${durStr ? ` &middot; ${durStr}` : ""}</p>
				${selectedVideo?.date ? `<p style="font-size:0.8rem;color:#64748b;margin-top:0.5rem">Recorded ${selectedVideo.date}</p>` : ""}
				<p style="font-size:0.7rem;color:#475569;margin-top:1.5rem;opacity:0.7">Demo preview &mdash; connect rTube to stream real video</p>
			</div>`;
		} else if (!this.isPlayable(this.currentVideo)) {
			player = `<div class="placeholder"><div class="placeholder-icon">&#9888;&#65039;</div><p><strong>${this.getExtension(this.currentVideo).toUpperCase()}</strong> files cannot play in browsers</p><p style="font-size:0.8rem;color:#475569;margin-top:0.5rem">Download to play locally</p></div>`;
		} else {
			const base = window.location.pathname.replace(/\/$/, "");
			player = `<video controls autoplay><source src="${base}/api/v/${encodeURIComponent(this.currentVideo)}" type="${this.getExtension(this.currentVideo) === "webm" ? "video/webm" : "video/mp4"}"></video>`;
		}

		const infoBar = this.currentVideo ? `
			<div class="info-bar">
				<span class="info-name">${this.currentVideo}</span>
				${!this.isDemo ? `<div class="actions"><button class="btn" data-action="copy">Copy Link</button></div>` : ""}
			</div>
		` : "";

		return `
			<div class="layout">
				<div class="sidebar">${sidebar}</div>
				<div>
					<div class="player-area">${player}</div>
					${infoBar}
				</div>
			</div>
		`;
	}

	private renderLive(): string {
		return `
			<div class="live-section">
				<div class="live-card">
					<h3 style="font-size:1rem;margin:0 0 0.5rem;color:#e2e8f0">Watch a Live Stream</h3>
					<p style="font-size:0.85rem;color:#94a3b8;margin-bottom:1.5rem">Enter the stream key to watch a live broadcast.</p>
					<input type="text" placeholder="Stream key (e.g. community-meeting)" data-input="streamkey" />
					<button class="btn-primary" data-action="watch">Watch Stream</button>
				</div>
				<div class="setup">
					<h3>Broadcaster Setup (OBS Studio)</h3>
					<ol>
						<li>Open Settings &rarr; Stream</li>
						<li>Set Service to <strong>Custom</strong></li>
						<li>Server: <code>rtmp://rtube.online:1936/live</code></li>
						<li>Stream Key: any key (e.g. <code>community-meeting</code>)</li>
						<li>Click <strong>Start Streaming</strong></li>
					</ol>
				</div>
			</div>
		`;
	}

	private bindEvents() {
		this.shadow.querySelectorAll(".tab").forEach((btn) => {
			btn.addEventListener("click", () => {
				this.mode = (btn as HTMLElement).dataset.mode as "library" | "live";
				this.render();
			});
		});

		const searchInput = this.shadow.querySelector('[data-input="search"]') as HTMLInputElement;
		if (searchInput) {
			searchInput.addEventListener("input", () => {
				this.searchTerm = searchInput.value;
				this.render();
				// Restore focus and cursor position after re-render
				const newInput = this.shadow.querySelector('[data-input="search"]') as HTMLInputElement;
				if (newInput) { newInput.focus(); newInput.selectionStart = newInput.selectionEnd = newInput.value.length; }
			});
		}

		this.shadow.querySelectorAll(".video-item").forEach((item) => {
			item.addEventListener("click", () => {
				this.currentVideo = (item as HTMLElement).dataset.name || null;
				this.render();
			});
		});

		const copyBtn = this.shadow.querySelector('[data-action="copy"]');
		if (copyBtn) {
			copyBtn.addEventListener("click", () => {
				if (this.currentVideo) {
					const base = window.location.pathname.replace(/\/$/, "");
					const url = `${window.location.origin}${base}/api/v/${encodeURIComponent(this.currentVideo)}`;
					navigator.clipboard.writeText(url);
				}
			});
		}
	}
}

customElements.define("folk-video-player", FolkVideoPlayer);
