/**
 * <folk-vnb-view> — Main rVnb module view.
 *
 * Layout: Search/filter bar, vehicle grid with map toggle (Leaflet),
 * owner dashboard (my vehicles + incoming requests), rental request sidebar.
 */

import { LightTourEngine } from '../../../shared/tour-engine';
import type { TourStep } from '../../../shared/tour-engine';
import './folk-vehicle-card';
import './folk-rental-request';
import { startPresenceHeartbeat } from '../../../shared/collab-presence';
import { getModuleApiBase } from "../../../shared/url-helpers";
import type { DocumentId } from "../../../shared/local-first/document";
import { vnbSchema, vnbDocId } from "../schemas";
import { ViewHistory } from "../../../shared/view-history.js";

const VNB_TOUR_STEPS: TourStep[] = [
	{ target: '.vnb-search', title: 'Search', message: 'Filter by vehicle type, dates, or economy model.' },
	{ target: '#vnb-content', title: 'Browse Vehicles', message: 'Tap a card for details and rental requests.' },
	{ target: '.vnb-view__toggle[data-view="map"]', title: 'Map View', message: 'See vehicles on an interactive map.' },
];

// ── Leaflet CDN Loader ──

let _leafletReady = false;
let _leafletPromise: Promise<void> | null = null;

function ensureLeaflet(): Promise<void> {
	if (_leafletReady && typeof (window as any).L !== 'undefined') return Promise.resolve();
	if (_leafletPromise) return _leafletPromise;
	_leafletPromise = new Promise<void>((resolve, reject) => {
		const s = document.createElement('script');
		s.src = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js';
		s.onload = () => { _leafletReady = true; resolve(); };
		s.onerror = () => reject(new Error('Leaflet load failed'));
		document.head.appendChild(s);
	});
	return _leafletPromise;
}

// ── Economy badges ──

const ECONOMY_BADGE: Record<string, { icon: string; label: string; cls: string }> = {
	gift:          { icon: '\u{1F49A}', label: 'Gift',          cls: 'vnb-badge--gift' },
	exchange:      { icon: '\u{1F91D}', label: 'Exchange',      cls: 'vnb-badge--exchange' },
	sliding_scale: { icon: '\u{2696}',  label: 'Sliding Scale', cls: 'vnb-badge--sliding_scale' },
	suggested:     { icon: '\u{1F4AD}', label: 'Suggested',     cls: 'vnb-badge--suggested' },
	fixed:         { icon: '\u{1F3F7}', label: 'Fixed',         cls: 'vnb-badge--fixed' },
};

const TYPE_ICONS: Record<string, string> = {
	motorhome: '\u{1F690}', camper_van: '\u{1F68C}', travel_trailer: '\u{1F3D5}',
	truck_camper: '\u{1F6FB}', skoolie: '\u{1F68E}', other: '\u{1F3E0}',
};

const MILEAGE_BADGE: Record<string, { icon: string; label: string }> = {
	unlimited:      { icon: '\u{267E}',  label: 'Unlimited' },
	per_mile:       { icon: '\u{1F4CF}', label: 'Per Mile' },
	included_miles: { icon: '\u{2705}',  label: 'Included Miles' },
};

class FolkVnbView extends HTMLElement {
	static observedAttributes = ['space'];

	#space = 'demo';
	#vehicles: any[] = [];
	#rentals: any[] = [];
	#stats: any = null;
	#selectedRental: any = null;
	#view: 'grid' | 'map' = 'grid';
	private _history = new ViewHistory<'grid' | 'map'>('grid', 'rvnb');
	#search = '';
	#typeFilter = '';
	#economyFilter = '';
	#map: any = null;
	#mapContainer: HTMLElement | null = null;
	#tour: LightTourEngine | null = null;
	private _stopPresence: (() => void) | null = null;
	private _offlineUnsub: (() => void) | null = null;
	private _subscribedDocIds: string[] = [];

	connectedCallback() {
		this.#space = this.getAttribute('space') || 'demo';
		this.#render();
		this.#loadData();
		this._stopPresence = startPresenceHeartbeat(() => ({ module: 'rvnb', context: 'Venues' }));
		if (this.#space !== 'demo') this.subscribeOffline();
		window.addEventListener('rspace-view-restored', this._onViewRestored as EventListener);
	}

	disconnectedCallback() {
		this._history.destroy();
		window.removeEventListener('rspace-view-restored', this._onViewRestored as EventListener);
		this._stopPresence?.();
		this._offlineUnsub?.(); this._offlineUnsub = null;
		const runtime = (window as any).__rspaceOfflineRuntime;
		if (runtime) {
			for (const id of this._subscribedDocIds) runtime.unsubscribe(id);
		}
		this._subscribedDocIds = [];
	}

	private _onViewRestored = (e: CustomEvent) => {
		if (e.detail?.moduleId !== 'rvnb') return;
		this.#view = e.detail.view;
		this.#render();
		this.#renderContent();
	};

	private async subscribeOffline() {
		const runtime = (window as any).__rspaceOfflineRuntime;
		if (!runtime?.isInitialized) return;
		try {
			const docId = vnbDocId(this.#space) as DocumentId;
			await runtime.subscribe(docId, vnbSchema);
			this._subscribedDocIds.push(docId);
		} catch { /* runtime unavailable */ }
	}

	attributeChangedCallback(name: string, _old: string, val: string) {
		if (name === 'space') {
			this.#space = val || 'demo';
			this.#loadData();
		}
	}

	async #loadData() {
		try {
			const [vehiclesRes, rentalsRes, statsRes] = await Promise.all([
				fetch(`${getModuleApiBase("rvnb")}/api/vehicles`),
				fetch(`${getModuleApiBase("rvnb")}/api/rentals`),
				fetch(`${getModuleApiBase("rvnb")}/api/stats`),
			]);

			if (vehiclesRes.ok) {
				const data = await vehiclesRes.json();
				this.#vehicles = data.results || [];
			}
			if (rentalsRes.ok) {
				const data = await rentalsRes.json();
				this.#rentals = data.results || [];
			}
			if (statsRes.ok) {
				this.#stats = await statsRes.json();
			}

			this.#renderContent();
		} catch (err) {
			console.warn('[rVnb] Failed to load data:', err);
		}
	}

	get #filteredVehicles() {
		let list = this.#vehicles;

		if (this.#search) {
			const term = this.#search.toLowerCase();
			list = list.filter((v: any) =>
				v.title.toLowerCase().includes(term) ||
				v.description?.toLowerCase().includes(term) ||
				v.pickup_location_name?.toLowerCase().includes(term) ||
				v.owner_name?.toLowerCase().includes(term) ||
				v.make?.toLowerCase().includes(term) ||
				v.model?.toLowerCase().includes(term)
			);
		}
		if (this.#typeFilter) list = list.filter((v: any) => v.type === this.#typeFilter);
		if (this.#economyFilter) list = list.filter((v: any) => v.economy === this.#economyFilter);

		return list;
	}

	#render() {
		this.innerHTML = `
			<div class="vnb-view">
				<div class="vnb-view__header" style="display:flex;justify-content:space-between;align-items:center;margin-bottom:1rem">
					<h2 style="margin:0;font-size:1.25rem;color:var(--rs-text,#e2e8f0);display:flex;align-items:center;gap:0.5rem">
						\u{1F690} Community RV Sharing
						${this.#stats ? `<span style="font-size:0.75rem;color:var(--rs-text-muted,#94a3b8);font-weight:400">${this.#stats.active_vehicles || 0} vehicles</span>` : ''}
					</h2>
					<div style="display:flex;gap:0.5rem">
						<button class="vnb-view__toggle" data-view="grid" style="padding:0.4rem 0.75rem;border-radius:0.375rem;border:1px solid var(--rs-border,#334155);background:${this.#view === 'grid' ? 'rgba(16,185,129,0.15)' : 'transparent'};color:var(--rs-text,#e2e8f0);cursor:pointer;font-size:0.82rem">
								\u{25A6} Grid
							</button>
						<button class="vnb-view__toggle" data-view="map" style="padding:0.4rem 0.75rem;border-radius:0.375rem;border:1px solid var(--rs-border,#334155);background:${this.#view === 'map' ? 'rgba(16,185,129,0.15)' : 'transparent'};color:var(--rs-text,#e2e8f0);cursor:pointer;font-size:0.82rem">
								\u{1F5FA} Map
							</button>
						<button id="btn-tour" style="padding:0.4rem 0.75rem;border-radius:0.375rem;border:1px solid var(--rs-border,#334155);background:transparent;color:var(--rs-text-muted,#94a3b8);cursor:pointer;font-size:0.78rem">Tour</button>
					</div>
				</div>

				<div class="vnb-search">
					<input class="vnb-search__input" type="text" placeholder="Search vehicles..." value="${this.#esc(this.#search)}">
					<select class="vnb-search__select" id="type-filter">
						<option value="">All Types</option>
						<option value="motorhome" ${this.#typeFilter === 'motorhome' ? 'selected' : ''}>Motorhome</option>
						<option value="camper_van" ${this.#typeFilter === 'camper_van' ? 'selected' : ''}>Camper Van</option>
						<option value="travel_trailer" ${this.#typeFilter === 'travel_trailer' ? 'selected' : ''}>Travel Trailer</option>
						<option value="truck_camper" ${this.#typeFilter === 'truck_camper' ? 'selected' : ''}>Truck Camper</option>
						<option value="skoolie" ${this.#typeFilter === 'skoolie' ? 'selected' : ''}>Skoolie</option>
						<option value="other" ${this.#typeFilter === 'other' ? 'selected' : ''}>Other</option>
					</select>
					<select class="vnb-search__select" id="economy-filter">
						<option value="">All Economies</option>
						<option value="gift" ${this.#economyFilter === 'gift' ? 'selected' : ''}>\u{1F49A} Gift</option>
						<option value="exchange" ${this.#economyFilter === 'exchange' ? 'selected' : ''}>\u{1F91D} Exchange</option>
						<option value="sliding_scale" ${this.#economyFilter === 'sliding_scale' ? 'selected' : ''}>\u{2696} Sliding Scale</option>
						<option value="suggested" ${this.#economyFilter === 'suggested' ? 'selected' : ''}>\u{1F4AD} Suggested</option>
						<option value="fixed" ${this.#economyFilter === 'fixed' ? 'selected' : ''}>\u{1F3F7} Fixed</option>
					</select>
				</div>

				<div class="vnb-view__content" id="vnb-content"></div>

				<div class="vnb-view__sidebar" id="vnb-sidebar" style="display:none;position:fixed;top:0;right:0;width:420px;height:100vh;background:var(--rs-bg,#0f172a);border-left:1px solid var(--rs-border,#334155);z-index:100;overflow-y:auto;padding:1rem">
					<button id="close-sidebar" style="position:absolute;top:0.75rem;right:0.75rem;background:none;border:none;color:var(--rs-text-muted,#94a3b8);font-size:1.25rem;cursor:pointer">\u{2715}</button>
					<div id="sidebar-content"></div>
				</div>
			</div>
		`;

		this.#wireEvents();

		// Tour
		this.#tour = new LightTourEngine(this.querySelector('.vnb-view') as HTMLElement || this, VNB_TOUR_STEPS, 'rvnb_tour_done');
		if (!localStorage.getItem('rvnb_tour_done')) {
			setTimeout(() => this.#tour?.start(), 800);
		}
		this.querySelector('#btn-tour')?.addEventListener('click', () => this.#tour?.start());
	}

	#wireEvents() {
		// Search input
		const searchInput = this.querySelector('.vnb-search__input') as HTMLInputElement;
		searchInput?.addEventListener('input', (e) => {
			this.#search = (e.target as HTMLInputElement).value;
			this.#renderContent();
		});

		// Type filter
		this.querySelector('#type-filter')?.addEventListener('change', (e) => {
			this.#typeFilter = (e.target as HTMLSelectElement).value;
			this.#renderContent();
		});

		// Economy filter
		this.querySelector('#economy-filter')?.addEventListener('change', (e) => {
			this.#economyFilter = (e.target as HTMLSelectElement).value;
			this.#renderContent();
		});

		// View toggles
		for (const btn of this.querySelectorAll('.vnb-view__toggle')) {
			btn.addEventListener('click', () => {
				const v = (btn as HTMLElement).dataset.view as 'grid' | 'map';
				this._history.push(v);
				this.#view = v;
				this.#render();
				this.#renderContent();
			});
		}

		// Close sidebar
		this.querySelector('#close-sidebar')?.addEventListener('click', () => {
			this.#closeSidebar();
		});

		// Rental action events (bubbled from folk-rental-request)
		this.addEventListener('rental-action', ((e: CustomEvent) => {
			this.#handleRentalAction(e.detail.rentalId, e.detail.action);
		}) as EventListener);

		this.addEventListener('rental-message', ((e: CustomEvent) => {
			this.#handleRentalMessage(e.detail.rentalId, e.detail.body);
		}) as EventListener);
	}

	#renderContent() {
		const container = this.querySelector('#vnb-content');
		if (!container) return;

		const vehicles = this.#filteredVehicles;

		if (this.#view === 'map') {
			container.innerHTML = `<div id="vnb-map" style="width:100%;height:500px;border-radius:0.75rem;border:1px solid var(--rs-border,#334155)"></div>`;
			this.#initMap(vehicles);
			return;
		}

		// Grid view
		if (vehicles.length === 0) {
			container.innerHTML = `
				<div style="text-align:center;padding:3rem;color:var(--rs-text-muted,#94a3b8)">
					<div style="font-size:2.5rem;margin-bottom:1rem">\u{1F690}</div>
					<p>No vehicles found. Try adjusting your search or filters.</p>
				</div>
			`;
			return;
		}

		container.innerHTML = `<div class="vnb-grid">${vehicles.map((v: any) => this.#renderVehicleCard(v)).join('')}</div>`;

		// Wire card clicks
		for (const card of container.querySelectorAll('.vnb-card')) {
			card.addEventListener('click', () => {
				const vehicleId = (card as HTMLElement).dataset.vehicleId;
				if (vehicleId) this.#showVehicleRentals(vehicleId);
			});
		}
	}

	#renderVehicleCard(v: any): string {
		const eco = ECONOMY_BADGE[v.economy] || ECONOMY_BADGE.suggested;
		const typeIcon = TYPE_ICONS[v.type] || '\u{1F690}';
		const typeLabel = (v.type || 'camper_van').replace(/_/g, ' ');
		const mileage = MILEAGE_BADGE[v.mileage_policy] || MILEAGE_BADGE.unlimited;
		const specsLine = [
			v.year,
			v.make,
			v.model,
		].filter(Boolean).join(' ');

		return `
			<div class="vnb-card" data-vehicle-id="${v.id}" data-collab-id="vehicle:${v.id}">
				<div class="vnb-card__cover">${typeIcon}</div>
				<div class="vnb-card__body">
					<div class="vnb-card__title">${this.#esc(v.title)}</div>
					${specsLine ? `<div class="vnb-card__specs">${this.#esc(specsLine)}</div>` : ''}
					<div class="vnb-card__owner">
						<span>${this.#esc(v.owner_name)}</span>
						${v.instant_accept ? '<span style="font-size:0.7rem;padding:0.1rem 0.3rem;border-radius:9999px;background:rgba(52,211,153,0.12);color:#34d399">\u{26A1} Auto</span>' : ''}
					</div>
					<div class="vnb-card__meta">
						<span class="vnb-badge ${eco.cls}">${eco.icon} ${eco.label}</span>
						<span class="vnb-badge vnb-badge--type">${typeIcon} ${typeLabel}</span>
						<span class="vnb-badge" style="background:rgba(148,163,184,0.08);color:#94a3b8;border:1px solid rgba(148,163,184,0.15)">\u{1F6CF} Sleeps ${v.sleeps}</span>
						<span class="vnb-badge vnb-badge--mileage">${mileage.icon} ${mileage.label}</span>
					</div>
					<div class="vnb-card__location">\u{1F4CD} ${this.#esc(v.pickup_location_name)}</div>
				</div>
			</div>
		`;
	}

	async #initMap(vehicles: any[]) {
		try {
			await ensureLeaflet();
		} catch { return; }

		const L = (window as any).L;
		const mapEl = this.querySelector('#vnb-map');
		if (!mapEl) return;

		// Destroy previous map if any
		if (this.#map) { this.#map.remove(); this.#map = null; }

		this.#map = L.map(mapEl).setView([50, 10], 4);
		L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
			attribution: '&copy; OpenStreetMap',
			maxZoom: 18,
		}).addTo(this.#map);

		const bounds: [number, number][] = [];

		// Green pickup icon, teal dropoff icon
		const pickupIcon = L.divIcon({
			html: '<div style="background:#10b981;width:12px;height:12px;border-radius:50%;border:2px solid #fff;box-shadow:0 1px 4px rgba(0,0,0,0.3)"></div>',
			iconSize: [16, 16],
			iconAnchor: [8, 8],
			className: '',
		});
		const dropoffIcon = L.divIcon({
			html: '<div style="background:#06b6d4;width:12px;height:12px;border-radius:50%;border:2px solid #fff;box-shadow:0 1px 4px rgba(0,0,0,0.3)"></div>',
			iconSize: [16, 16],
			iconAnchor: [8, 8],
			className: '',
		});

		for (const v of vehicles) {
			const typeIcon = TYPE_ICONS[v.type] || '\u{1F690}';
			const eco = ECONOMY_BADGE[v.economy] || ECONOMY_BADGE.suggested;

			// Pickup marker
			if (v.pickup_location_lat && v.pickup_location_lng) {
				const latlng: [number, number] = [v.pickup_location_lat, v.pickup_location_lng];
				bounds.push(latlng);
				const marker = L.marker(latlng, { icon: pickupIcon }).addTo(this.#map);
				marker.bindPopup(`
					<div style="min-width:180px">
						<strong>${typeIcon} ${this.#esc(v.title)}</strong><br>
						<span style="font-size:0.85em;color:#666">${this.#esc(v.owner_name)}</span><br>
						<span style="font-size:0.82em">${eco.icon} ${eco.label} &middot; Sleeps ${v.sleeps}</span><br>
						<span style="font-size:0.8em;color:#10b981">\u{1F4CD} Pickup: ${this.#esc(v.pickup_location_name)}</span>
					</div>
				`);
				marker.on('click', () => this.#showVehicleRentals(v.id));
			}

			// Dropoff marker (only if different from pickup)
			if (!v.dropoff_same_as_pickup && v.dropoff_location_lat && v.dropoff_location_lng) {
				const dropLatlng: [number, number] = [v.dropoff_location_lat, v.dropoff_location_lng];
				bounds.push(dropLatlng);
				const dropMarker = L.marker(dropLatlng, { icon: dropoffIcon }).addTo(this.#map);
				dropMarker.bindPopup(`
					<div style="min-width:160px">
						<strong>${typeIcon} ${this.#esc(v.title)}</strong><br>
						<span style="font-size:0.8em;color:#06b6d4">\u{1F3C1} Dropoff: ${this.#esc(v.dropoff_location_name || '')}</span>
					</div>
				`);
			}
		}

		if (bounds.length > 0) {
			this.#map.fitBounds(bounds, { padding: [30, 30], maxZoom: 10 });
		}
	}

	#showVehicleRentals(vehicleId: string) {
		const vehicle = this.#vehicles.find((v: any) => v.id === vehicleId);
		const vehicleRentals = this.#rentals.filter((r: any) => r.vehicle_id === vehicleId);

		const sidebar = this.querySelector('#vnb-sidebar') as HTMLElement;
		const content = this.querySelector('#sidebar-content') as HTMLElement;
		if (!sidebar || !content) return;

		sidebar.style.display = 'block';

		const eco = ECONOMY_BADGE[vehicle?.economy] || ECONOMY_BADGE.suggested;
		const specsLine = [vehicle?.year, vehicle?.make, vehicle?.model].filter(Boolean).join(' ');

		content.innerHTML = `
			<h3 style="margin:0 0 0.25rem;font-size:1rem;color:var(--rs-text,#e2e8f0)">${this.#esc(vehicle?.title || '')}</h3>
			${specsLine ? `<p style="font-size:0.8rem;color:var(--rs-text-muted,#94a3b8);margin:0 0 0.5rem">${this.#esc(specsLine)}</p>` : ''}
			<p style="font-size:0.82rem;color:var(--rs-text-muted,#94a3b8);margin:0 0 0.5rem">${this.#esc(vehicle?.description || '')}</p>
			<div style="display:flex;gap:0.5rem;flex-wrap:wrap;margin-bottom:0.75rem">
				<span class="vnb-badge ${eco.cls}">${eco.icon} ${eco.label}</span>
				<span class="vnb-badge" style="background:rgba(148,163,184,0.08);color:#94a3b8;border:1px solid rgba(148,163,184,0.15)">\u{1F6CF} Sleeps ${vehicle?.sleeps || 0}</span>
				${vehicle?.length_feet ? `<span class="vnb-badge" style="background:rgba(148,163,184,0.08);color:#94a3b8;border:1px solid rgba(148,163,184,0.15)">\u{1F4CF} ${vehicle.length_feet}'</span>` : ''}
			</div>

			<div style="font-size:0.78rem;color:var(--rs-text-muted,#64748b);margin-bottom:1rem;display:flex;flex-wrap:wrap;gap:0.4rem">
				${vehicle?.has_generator ? '<span style="padding:0.1rem 0.35rem;background:rgba(16,185,129,0.08);border:1px solid rgba(16,185,129,0.15);border-radius:0.25rem;color:#34d399">Generator</span>' : ''}
				${vehicle?.has_solar ? '<span style="padding:0.1rem 0.35rem;background:rgba(245,158,11,0.08);border:1px solid rgba(245,158,11,0.15);border-radius:0.25rem;color:#f59e0b">Solar</span>' : ''}
				${vehicle?.has_ac ? '<span style="padding:0.1rem 0.35rem;background:rgba(96,165,250,0.08);border:1px solid rgba(96,165,250,0.15);border-radius:0.25rem;color:#60a5fa">A/C</span>' : ''}
				${vehicle?.has_heating ? '<span style="padding:0.1rem 0.35rem;background:rgba(239,68,68,0.08);border:1px solid rgba(239,68,68,0.15);border-radius:0.25rem;color:#ef4444">Heating</span>' : ''}
				${vehicle?.has_shower ? '<span style="padding:0.1rem 0.35rem;background:rgba(96,165,250,0.08);border:1px solid rgba(96,165,250,0.15);border-radius:0.25rem;color:#60a5fa">Shower</span>' : ''}
				${vehicle?.has_toilet ? '<span style="padding:0.1rem 0.35rem;background:rgba(148,163,184,0.08);border:1px solid rgba(148,163,184,0.15);border-radius:0.25rem;color:#94a3b8">Toilet</span>' : ''}
				${vehicle?.has_kitchen ? '<span style="padding:0.1rem 0.35rem;background:rgba(245,158,11,0.08);border:1px solid rgba(245,158,11,0.15);border-radius:0.25rem;color:#f59e0b">Kitchen</span>' : ''}
				${vehicle?.pet_friendly ? '<span style="padding:0.1rem 0.35rem;background:rgba(167,139,250,0.08);border:1px solid rgba(167,139,250,0.15);border-radius:0.25rem;color:#a78bfa">Pet Friendly</span>' : ''}
			</div>

			<h4 style="font-size:0.88rem;color:var(--rs-text,#e2e8f0);margin:1rem 0 0.75rem;border-top:1px solid var(--rs-border,#334155);padding-top:1rem">
				Rental Requests (${vehicleRentals.length})
			</h4>
			${vehicleRentals.length === 0
				? '<p style="font-size:0.82rem;color:var(--rs-text-muted,#64748b)">No rental requests yet.</p>'
				: vehicleRentals.map((r: any) => `
					<div class="rental-item" data-rental-id="${r.id}" style="padding:0.75rem;margin-bottom:0.5rem;border:1px solid var(--rs-border,#334155);border-radius:0.5rem;cursor:pointer;transition:background 0.15s">
						<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:0.25rem">
							<span style="font-size:0.85rem;font-weight:600;color:var(--rs-text,#e2e8f0)">${this.#esc(r.renter_name)}</span>
							<span class="vnb-status vnb-status--${r.status}">${r.status}</span>
						</div>
						<div style="font-size:0.75rem;color:var(--rs-text-muted,#94a3b8)">
							${r.pickup_date ? new Date(r.pickup_date).toLocaleDateString() : ''} \u{2192} ${r.dropoff_date ? new Date(r.dropoff_date).toLocaleDateString() : ''}
							${r.estimated_miles ? `&middot; ~${r.estimated_miles} mi` : ''}
							&middot; ${r.messages?.length || 0} msg${(r.messages?.length || 0) !== 1 ? 's' : ''}
						</div>
					</div>
				`).join('')}
		`;

		// Wire rental item clicks to show detail
		for (const item of content.querySelectorAll('.rental-item')) {
			item.addEventListener('click', () => {
				const rentalId = (item as HTMLElement).dataset.rentalId;
				const rental = this.#rentals.find((r: any) => r.id === rentalId);
				if (rental) this.#showRentalDetail(rental);
			});
		}
	}

	#showRentalDetail(rental: any) {
		const content = this.querySelector('#sidebar-content') as HTMLElement;
		if (!content) return;

		content.innerHTML = `
			<button id="back-to-vehicle" style="background:none;border:none;color:var(--rs-text-muted,#94a3b8);cursor:pointer;font-size:0.82rem;margin-bottom:0.75rem;padding:0">
				\u{2190} Back to vehicle
			</button>
			<folk-rental-request rental-id="${rental.id}" space="${this.#space}"></folk-rental-request>
		`;

		content.querySelector('#back-to-vehicle')?.addEventListener('click', () => {
			this.#showVehicleRentals(rental.vehicle_id);
		});
	}

	#closeSidebar() {
		const sidebar = this.querySelector('#vnb-sidebar') as HTMLElement;
		if (sidebar) sidebar.style.display = 'none';
	}

	async #handleRentalAction(rentalId: string, action: string) {
		try {
			const res = await fetch(`${getModuleApiBase("rvnb")}/api/rentals/${rentalId}/${action}`, {
				method: 'POST',
				headers: { 'Content-Type': 'application/json' },
			});
			if (res.ok) {
				await this.#loadData();
				const rental = this.#rentals.find((r: any) => r.id === rentalId);
				if (rental) this.#showRentalDetail(rental);
			}
		} catch (err) {
			console.warn('[rVnb] Action failed:', err);
		}
	}

	async #handleRentalMessage(rentalId: string, body: string) {
		try {
			const res = await fetch(`${getModuleApiBase("rvnb")}/api/rentals/${rentalId}/messages`, {
				method: 'POST',
				headers: { 'Content-Type': 'application/json' },
				body: JSON.stringify({ body, sender_name: 'You' }),
			});
			if (res.ok) {
				await this.#loadData();
				const rental = this.#rentals.find((r: any) => r.id === rentalId);
				if (rental) this.#showRentalDetail(rental);
			}
		} catch (err) {
			console.warn('[rVnb] Message failed:', err);
		}
	}

	#esc(s: string): string {
		const el = document.createElement('span');
		el.textContent = s || '';
		return el.innerHTML;
	}

	startTour() { this.#tour?.start(); }
}

if (!customElements.get('folk-vnb-view')) {
	customElements.define('folk-vnb-view', FolkVnbView);
}

export { FolkVnbView };
