/**
 * <folk-campaigns-dashboard> — Campaign gallery grid.
 *
 * Lists all campaign flows and renders mini SVG previews. Click a card to
 * open that flow in the planner. Also surfaces the AI wizard (which sets up
 * a new flow) and a blank "+ New" affordance.
 *
 * Attributes:
 *   space — space slug (default "demo")
 */

import { TourEngine } from '../../../shared/tour-engine';
import type { TourStep } from '../../../shared/tour-engine';
import type {
	CampaignFlow,
	CampaignPlannerNode,
	CampaignEdge,
	PhaseNodeData,
} from '../schemas';

// ── Mini SVG constants ──

const NODE_COLORS: Record<string, string> = {
	post: '#3b82f6',
	thread: '#8b5cf6',
	platform: '#10b981',
	audience: '#f59e0b',
	phase: '#64748b',
	goal: '#6366f1',
	message: '#6366f1',
	tone: '#8b5cf6',
	brief: '#ec4899',
};

function nodeSize(n: CampaignPlannerNode): { w: number; h: number } {
	switch (n.type) {
		case 'post': return { w: 240, h: 120 };
		case 'thread': return { w: 240, h: 100 };
		case 'platform': return { w: 180, h: 80 };
		case 'audience': return { w: 180, h: 80 };
		case 'phase': {
			const d = n.data as PhaseNodeData;
			return { w: d.size?.w || 400, h: d.size?.h || 300 };
		}
		case 'goal': return { w: 240, h: 130 };
		case 'message': return { w: 220, h: 100 };
		case 'tone': return { w: 220, h: 110 };
		case 'brief': return { w: 260, h: 150 };
		default: return { w: 200, h: 100 };
	}
}

function esc(s: string): string {
	const d = document.createElement('div');
	d.textContent = s || '';
	return d.innerHTML;
}

// ── Mini SVG renderer ──

function renderMiniFlowSVG(nodes: CampaignPlannerNode[], edges: CampaignEdge[]): string {
	if (nodes.length === 0) {
		return `<svg viewBox="0 0 200 100" preserveAspectRatio="xMidYMid meet" class="cd-card__svg">
			<text x="100" y="55" text-anchor="middle" fill="#666" font-size="14">Empty flow</text>
		</svg>`;
	}

	let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
	for (const n of nodes) {
		const s = nodeSize(n);
		minX = Math.min(minX, n.position.x);
		minY = Math.min(minY, n.position.y);
		maxX = Math.max(maxX, n.position.x + s.w);
		maxY = Math.max(maxY, n.position.y + s.h);
	}
	const pad = 40;
	const vx = minX - pad;
	const vy = minY - pad;
	const vw = (maxX - minX) + pad * 2;
	const vh = (maxY - minY) + pad * 2;

	// Edges (simple line midpoint-to-midpoint; kept light)
	const edgePaths = edges.map(e => {
		const from = nodes.find(n => n.id === e.from);
		const to = nodes.find(n => n.id === e.to);
		if (!from || !to) return '';
		const fs = nodeSize(from);
		const ts = nodeSize(to);
		const x1 = from.position.x + fs.w;
		const y1 = from.position.y + fs.h / 2;
		const x2 = to.position.x;
		const y2 = to.position.y + ts.h / 2;
		const dx = Math.abs(x2 - x1) * 0.5;
		return `<path d="M ${x1} ${y1} C ${x1 + dx} ${y1}, ${x2 - dx} ${y2}, ${x2} ${y2}" fill="none" stroke="#555" stroke-width="4" opacity="0.5"/>`;
	}).join('');

	// Phase rects behind
	const phaseRects = nodes.filter(n => n.type === 'phase').map(n => {
		const s = nodeSize(n);
		const d = n.data as PhaseNodeData;
		return `<rect x="${n.position.x}" y="${n.position.y}" width="${s.w}" height="${s.h}" rx="8" fill="${d.color || '#64748b'}" opacity="0.08" stroke="${d.color || '#64748b'}" stroke-opacity="0.25"/>`;
	}).join('');

	// Content nodes as solid rects
	const contentRects = nodes.filter(n => n.type !== 'phase').map(n => {
		const s = nodeSize(n);
		const color = NODE_COLORS[n.type] || '#666';
		return `<rect x="${n.position.x}" y="${n.position.y}" width="${s.w}" height="${s.h}" rx="10" fill="${color}" opacity="0.85"/>`;
	}).join('');

	return `<svg viewBox="${vx} ${vy} ${vw} ${vh}" preserveAspectRatio="xMidYMid meet" class="cd-card__svg">
		${phaseRects}
		${edgePaths}
		${contentRects}
	</svg>`;
}

// ── Component ──

const DASHBOARD_TOUR_STEPS: TourStep[] = [
	{ target: '#btn-wizard', title: 'Campaign Wizard', message: 'AI-guided campaign setup — answer a few questions and the wizard builds the flow for you.' },
	{ target: '#btn-new', title: 'New Campaign', message: 'Start a blank campaign flow and lay out your own posts, platforms, and audiences.' },
	{ target: '.cd-card', title: 'Campaign Cards', message: 'Click any card to open its flow in the planner.' },
];

class FolkCampaignsDashboard extends HTMLElement {
	private shadow: ShadowRoot;
	private space = '';
	private flows: CampaignFlow[] = [];
	private loading = true;
	private _tour!: TourEngine;

	private get basePath() {
		const host = window.location.hostname;
		if (host.endsWith('.rspace.online') || host.endsWith('.rsocials.online')) return '/rsocials/';
		return `/${this.space}/rsocials/`;
	}

	constructor() {
		super();
		this.shadow = this.attachShadow({ mode: 'open' });
		this._tour = new TourEngine(
			this.shadow,
			DASHBOARD_TOUR_STEPS,
			'rsocials_dashboard_tour_done',
			() => this.shadow.querySelector('.cd-root') as HTMLElement,
		);
	}

	connectedCallback() {
		this.space = this.getAttribute('space') || 'demo';
		this.render();
		this.loadFlows();
	}

	private async loadFlows() {
		try {
			const res = await fetch(`${this.basePath}api/campaign/flows`);
			if (res.ok) {
				const data = await res.json();
				this.flows = data.results || [];
			}
		} catch {
			console.warn('[CampaignsDashboard] Failed to load flows');
		}
		this.loading = false;
		this.render();
		if (!localStorage.getItem('rsocials_dashboard_tour_done')) {
			setTimeout(() => this._tour.start(), 800);
		}
	}

	startTour() { this._tour.start(); }

	private async createFlow() {
		try {
			const res = await fetch(`${this.basePath}api/campaign/flows`, {
				method: 'POST',
				headers: { 'Content-Type': 'application/json' },
				body: JSON.stringify({ name: 'New Campaign' }),
			});
			if (res.ok) {
				const flow = await res.json();
				this.navigateToFlow(flow.id);
			}
		} catch {
			console.error('[CampaignsDashboard] Failed to create flow');
		}
	}

	private navigateToFlow(id: string) {
		window.location.href = `${this.basePath}campaign-flow?id=${encodeURIComponent(id)}`;
	}

	private formatDate(ts: number | null): string {
		if (!ts) return '—';
		const d = new Date(ts);
		const now = Date.now();
		const diff = now - ts;
		if (diff < 60000) return 'just now';
		if (diff < 3600000) return `${Math.floor(diff / 60000)}m ago`;
		if (diff < 86400000) return `${Math.floor(diff / 3600000)}h ago`;
		return d.toLocaleDateString(undefined, { month: 'short', day: 'numeric' });
	}

	private render() {
		const cards = this.flows.map(flow => {
			const nodeCount = flow.nodes.length;
			const postCount = flow.nodes.filter(n => n.type === 'post').length;
			const platformCount = flow.nodes.filter(n => n.type === 'platform').length;

			return `
				<div class="cd-card" data-flow-id="${flow.id}">
					<div class="cd-card__preview">
						${renderMiniFlowSVG(flow.nodes, flow.edges)}
					</div>
					<div class="cd-card__info">
						<div class="cd-card__name">${esc(flow.name)}</div>
						<div class="cd-card__badges">
							<span class="cd-badge cd-badge--nodes">${nodeCount} node${nodeCount !== 1 ? 's' : ''}</span>
							${postCount > 0 ? `<span class="cd-badge cd-badge--posts">${postCount} post${postCount !== 1 ? 's' : ''}</span>` : ''}
							${platformCount > 0 ? `<span class="cd-badge cd-badge--platforms">${platformCount} platform${platformCount !== 1 ? 's' : ''}</span>` : ''}
						</div>
						<div class="cd-card__date">Updated ${this.formatDate(flow.updatedAt)}</div>
					</div>
				</div>
			`;
		}).join('');

		const emptyState = !this.loading && this.flows.length === 0 ? `
			<div class="cd-empty">
				<div class="cd-empty__icon">📢</div>
				<div class="cd-empty__title">No campaigns yet</div>
				<div class="cd-empty__subtitle">Use the AI wizard to set up a flow from a brief, or start a blank canvas</div>
				<div class="cd-header__actions" style="justify-content:center">
					<button class="cd-btn cd-btn--wizard cd-btn--new-empty" id="btn-wizard-empty">\uD83E\uDDD9 Campaign Wizard</button>
					<button class="cd-btn cd-btn--primary cd-btn--new-empty">+ New Campaign</button>
				</div>
			</div>
		` : '';

		const loadingState = this.loading ? `
			<div class="cd-loading">Loading campaigns…</div>
		` : '';

		this.shadow.innerHTML = `
			<style>
				:host { display: block; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; color: var(--rs-text-primary, #e1e1e1); }

				.cd-root { padding: 1.5rem; max-width: 1400px; margin: 0 auto; }

				.cd-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 1.5rem; }
				.cd-header h2 { margin: 0; font-size: 1.4rem; font-weight: 600; }
				.cd-header__subtitle { font-size: 0.85rem; color: var(--rs-text-muted, #888); margin-top: 0.25rem; }

				.cd-btn {
					border: none; border-radius: 6px; padding: 0.5rem 1rem; cursor: pointer;
					font-size: 0.85rem; font-weight: 500; transition: background 0.15s;
				}
				.cd-btn--primary { background: var(--rs-primary, #3b82f6); color: #fff; }
				.cd-btn--primary:hover { background: var(--rs-primary-hover, #2563eb); }
				.cd-btn--wizard {
					background: linear-gradient(135deg, var(--rs-accent, #14b8a6), #0d9488);
					color: #fff; font-weight: 600;
				}
				.cd-btn--wizard:hover { opacity: 0.9; }
				.cd-header__actions { display: flex; gap: 0.5rem; align-items: center; }

				.cd-grid {
					display: grid;
					grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
					gap: 1rem;
				}

				.cd-card {
					background: var(--rs-bg-surface, #1e1e2e); border: 1px solid var(--rs-border, #333); border-radius: 10px;
					overflow: hidden; cursor: pointer; transition: border-color 0.15s, transform 0.15s;
				}
				.cd-card:hover { border-color: var(--rs-primary, #3b82f6); transform: translateY(-2px); }

				.cd-card__preview {
					height: 160px; background: var(--rs-bg-surface-sunken, #14141e); display: flex; align-items: center; justify-content: center;
					border-bottom: 1px solid var(--rs-border, #333); padding: 0.5rem;
				}
				.cd-card__svg { width: 100%; height: 100%; }

				.cd-card__info { padding: 0.75rem 1rem; }
				.cd-card__name { font-weight: 600; font-size: 0.95rem; margin-bottom: 0.4rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

				.cd-card__badges { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-bottom: 0.35rem; }
				.cd-badge {
					font-size: 0.7rem; padding: 0.15rem 0.5rem; border-radius: 99px;
					font-weight: 500; text-transform: capitalize;
				}
				.cd-badge--nodes { background: rgba(59, 130, 246, 0.15); color: var(--rs-primary, #93c5fd); }
				.cd-badge--posts { background: rgba(59, 130, 246, 0.15); color: #93c5fd; }
				.cd-badge--platforms { background: rgba(16, 185, 129, 0.15); color: #6ee7b7; }

				.cd-card__date { font-size: 0.75rem; color: var(--rs-text-muted, #888); }

				.cd-empty {
					text-align: center; padding: 4rem 2rem;
					background: var(--rs-bg-surface, #1e1e2e); border: 1px dashed var(--rs-border, #444); border-radius: 10px;
				}
				.cd-empty__icon { font-size: 2.5rem; margin-bottom: 0.75rem; }
				.cd-empty__title { font-size: 1.2rem; font-weight: 600; margin-bottom: 0.35rem; }
				.cd-empty__subtitle { color: var(--rs-text-muted, #888); margin-bottom: 1.25rem; }
				.cd-btn--new-empty { font-size: 0.95rem; padding: 0.6rem 1.5rem; }

				.cd-loading { text-align: center; padding: 4rem; color: var(--rs-text-muted, #888); }
			</style>

			<div class="cd-root">
				<div class="cd-header">
					<div>
						<h2>Campaigns</h2>
						<div class="cd-header__subtitle">Plan, wire up, and schedule multi-platform campaigns</div>
					</div>
					<div class="cd-header__actions">
						<button class="cd-btn cd-btn--wizard" id="btn-wizard">\uD83E\uDDD9 Campaign Wizard</button>
						${!this.loading && this.flows.length > 0 ? '<button class="cd-btn cd-btn--primary" id="btn-new">+ New Campaign</button>' : ''}
						<button style="padding:4px 10px;border-radius:6px;border:1px solid var(--rs-border);background:var(--rs-bg-surface);color:var(--rs-text-secondary);cursor:pointer;font-size:0.78rem;" id="btn-tour">Tour</button>
					</div>
				</div>
				${loadingState}
				${emptyState}
				${!this.loading && this.flows.length > 0 ? `<div class="cd-grid">${cards}</div>` : ''}
			</div>
		`;

		this._tour.renderOverlay();
		this.attachListeners();
	}

	private attachListeners() {
		this.shadow.querySelectorAll('.cd-card').forEach(card => {
			card.addEventListener('click', () => {
				const id = (card as HTMLElement).dataset.flowId;
				if (id) this.navigateToFlow(id);
			});
		});

		const btnNew = this.shadow.getElementById('btn-new');
		if (btnNew) btnNew.addEventListener('click', () => this.createFlow());

		const btnNewEmpty = this.shadow.querySelector('.cd-btn--new-empty:not(#btn-wizard-empty)');
		if (btnNewEmpty) btnNewEmpty.addEventListener('click', () => this.createFlow());

		const wizardUrl = `${this.basePath}campaign-wizard`;
		const btnWizard = this.shadow.getElementById('btn-wizard');
		if (btnWizard) btnWizard.addEventListener('click', () => { window.location.href = wizardUrl; });
		const btnWizardEmpty = this.shadow.getElementById('btn-wizard-empty');
		if (btnWizardEmpty) btnWizardEmpty.addEventListener('click', () => { window.location.href = wizardUrl; });

		this.shadow.getElementById('btn-tour')?.addEventListener('click', () => this.startTour());
	}
}

customElements.define('folk-campaigns-dashboard', FolkCampaignsDashboard);
