/**
 * <folk-campaign-wizard> — AI-guided step-by-step campaign creation.
 *
 * Steps: Brief → Structure → Content → Review → Activate
 * Each step has Approve / Edit / Regenerate controls.
 * Commits campaign, threads, newsletters, and workflow DAG on activation.
 */

type WizardStep = 'brief' | 'structure' | 'content' | 'review' | 'activate';

interface ExtractedBrief {
	title: string;
	audience: string;
	startDate: string;
	endDate: string;
	platforms: string[];
	tone: string;
	style: string;
	keyMessages: string[];
}

interface CampaignStructurePhase {
	name: string;
	label: string;
	days: string;
	platforms: string[];
	cadence: Record<string, number>;
}

interface CampaignStructure {
	phases: CampaignStructurePhase[];
	summary: string;
}

interface CampaignPost {
	id: string;
	platform: string;
	postType: string;
	stepNumber: number;
	content: string;
	scheduledAt: string;
	status: string;
	hashtags: string[];
	phase: number;
	phaseLabel: string;
	threadPosts?: string[];
	emailSubject?: string;
	emailHtml?: string;
}

interface Campaign {
	id: string;
	title: string;
	description: string;
	duration: string;
	platforms: string[];
	phases: { name: string; label: string; days: string }[];
	posts: CampaignPost[];
	createdAt: number;
	updatedAt: number;
}

interface WizardState {
	id: string;
	step: WizardStep | 'committed' | 'abandoned';
	rawBrief: string;
	extractedBrief: ExtractedBrief | null;
	structure: CampaignStructure | null;
	campaignDraft: Campaign | null;
	committedCampaignId: string | null;
}

const STEPS: { key: WizardStep; label: string; num: number }[] = [
	{ key: 'brief', label: 'Brief', num: 1 },
	{ key: 'structure', label: 'Structure', num: 2 },
	{ key: 'content', label: 'Content', num: 3 },
	{ key: 'review', label: 'Review', num: 4 },
	{ key: 'activate', label: 'Activate', num: 5 },
];

const STEP_ORDER: Record<string, number> = { brief: 0, structure: 1, content: 2, review: 3, activate: 4, committed: 5, abandoned: -1 };

const PLATFORM_ICONS: Record<string, string> = {
	x: '\uD83D\uDC26', linkedin: '\uD83D\uDCBC', instagram: '\uD83D\uDCF7',
	threads: '\uD83E\uDDF5', bluesky: '\u2601\uFE0F', youtube: '\u25B6\uFE0F',
	newsletter: '\uD83D\uDCE7',
};

export class FolkCampaignWizard extends HTMLElement {
	private _space = 'demo';
	private _wizardId = '';
	private _step: WizardStep = 'brief';
	private _loading = false;
	private _error = '';
	private _rawBrief = '';
	private _extractedBrief: ExtractedBrief | null = null;
	private _structure: CampaignStructure | null = null;
	private _campaignDraft: Campaign | null = null;
	private _committedCampaignId: string | null = null;
	private _commitResult: any = null;
	private _expandedPosts: Set<number> = new Set();
	private _regenIndex = -1;
	private _regenInstructions = '';
	private _selectedPlatforms: Set<string> = new Set(['x', 'linkedin', 'instagram', 'youtube', 'threads', 'bluesky', 'newsletter']);
	private _expandedPhases: Set<number> = new Set();
	private _phaseInstructions: Map<number, string> = new Map();

	static get observedAttributes() { return ['space', 'wizard-id']; }

	connectedCallback() {
		if (!this.shadowRoot) this.attachShadow({ mode: 'open' });
		this._space = this.getAttribute('space') || 'demo';
		this._wizardId = this.getAttribute('wizard-id') || '';

		if (this._wizardId) {
			this.loadWizard();
		} else {
			this.render();
		}
	}

	attributeChangedCallback(name: string, _old: string, val: string) {
		if (name === 'space') this._space = val;
		if (name === 'wizard-id' && val !== this._wizardId) {
			this._wizardId = val;
			if (val) this.loadWizard();
		}
	}

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

	private async apiFetch(path: string, opts: RequestInit & { timeoutMs?: number } = {}): Promise<Response> {
		let token = '';
		try { const s = JSON.parse(localStorage.getItem('encryptid_session') || ''); token = s.accessToken || ''; } catch {}
		const { timeoutMs = 120_000, ...fetchOpts } = opts;
		const controller = new AbortController();
		const timer = setTimeout(() => controller.abort(), timeoutMs);
		try {
			return await fetch(`${this.basePath}${path}`, {
				...fetchOpts,
				signal: controller.signal,
				headers: {
					'Content-Type': 'application/json',
					...(token ? { Authorization: `Bearer ${token}` } : {}),
					...(fetchOpts.headers || {}),
				},
			});
		} catch (e: any) {
			if (e.name === 'AbortError') throw new Error('Request timed out — please try again');
			throw e;
		} finally {
			clearTimeout(timer);
		}
	}

	private async loadWizard(): Promise<void> {
		this._loading = true;
		this.render();

		try {
			const res = await this.apiFetch(`/api/campaign/wizard/${this._wizardId}`);
			if (!res.ok) throw new Error((await res.json().catch(() => ({}))).error || 'Failed to load wizard');
			const data: WizardState = await res.json();

			this._rawBrief = data.rawBrief || '';
			this._extractedBrief = data.extractedBrief;
			this._structure = data.structure;
			this._campaignDraft = data.campaignDraft;
			this._committedCampaignId = data.committedCampaignId;

			// Sync selected platforms from extracted brief
			if (data.extractedBrief?.platforms?.length) {
				this._selectedPlatforms = new Set(data.extractedBrief.platforms);
			}

			if (data.step === 'committed') {
				this._step = 'activate';
			} else if (data.step === 'abandoned') {
				this._step = 'brief';
			} else {
				this._step = data.step as WizardStep;
			}
		} catch (e: any) {
			this._error = e.message;
		}
		this._loading = false;
		this.render();
	}

	private async createWizard(): Promise<string | null> {
		try {
			const res = await this.apiFetch('/api/campaign/wizard', {
				method: 'POST',
				body: JSON.stringify({ rawBrief: this._rawBrief }),
			});
			if (!res.ok) throw new Error((await res.json().catch(() => ({}))).error || 'Failed to create wizard');
			const data = await res.json();
			this._wizardId = data.wizardId;

			// Update URL without reload
			const url = `${this.basePath}/campaign-wizard/${data.wizardId}`;
			history.replaceState(null, '', url);

			return data.wizardId;
		} catch (e: any) {
			this._error = e.message;
			this.render();
			return null;
		}
	}

	// ── Step actions ──

	private async analyzebrief(): Promise<void> {
		if (this._rawBrief.trim().length < 10) {
			this._error = 'Brief must be at least 10 characters';
			this.render();
			return;
		}

		this._loading = true;
		this._error = '';
		this.render();

		if (!this._wizardId) {
			const id = await this.createWizard();
			if (!id) { this._loading = false; this.render(); return; }
		}

		try {
			const res = await this.apiFetch(`/api/campaign/wizard/${this._wizardId}/structure`, {
				method: 'POST',
				body: JSON.stringify({ rawBrief: this._rawBrief, selectedPlatforms: Array.from(this._selectedPlatforms) }),
			});
			if (!res.ok) throw new Error((await res.json().catch(() => ({}))).error || 'Analysis failed');
			const data: WizardState = await res.json();
			this._extractedBrief = data.extractedBrief;
			this._structure = data.structure;
			this._step = 'structure';
		} catch (e: any) {
			this._error = e.message;
		}
		this._loading = false;
		this.render();
	}

	private async generateContent(): Promise<void> {
		this._loading = true;
		this._error = '';
		this.render();

		try {
			const phaseInstructions: Record<number, string> = {};
			this._phaseInstructions.forEach((v, k) => { if (v.trim()) phaseInstructions[k] = v; });
			const res = await this.apiFetch(`/api/campaign/wizard/${this._wizardId}/content`, {
				method: 'POST',
				body: JSON.stringify({ phaseInstructions }),
			});
			if (!res.ok) throw new Error((await res.json().catch(() => ({}))).error || 'Generation failed');
			const data: WizardState = await res.json();
			this._campaignDraft = data.campaignDraft;
			this._step = 'content';
		} catch (e: any) {
			this._error = e.message;
		}
		this._loading = false;
		this.render();
	}

	private async regenPost(index: number): Promise<void> {
		this._regenIndex = index;
		this._loading = true;
		this._error = '';
		this.render();

		try {
			const res = await this.apiFetch(`/api/campaign/wizard/${this._wizardId}/regen-post`, {
				method: 'POST',
				body: JSON.stringify({ postIndex: index, instructions: this._regenInstructions }),
			});
			if (!res.ok) throw new Error((await res.json().catch(() => ({}))).error || 'Regeneration failed');
			const newPost: CampaignPost = await res.json();
			if (this._campaignDraft) {
				this._campaignDraft.posts[index] = { ...this._campaignDraft.posts[index], ...newPost };
			}
		} catch (e: any) {
			this._error = e.message;
		}
		this._regenIndex = -1;
		this._regenInstructions = '';
		this._loading = false;
		this.render();
	}

	private async commitCampaign(): Promise<void> {
		this._loading = true;
		this._error = '';
		this.render();

		try {
			const res = await this.apiFetch(`/api/campaign/wizard/${this._wizardId}/commit`, {
				method: 'POST',
			});
			if (!res.ok) throw new Error((await res.json().catch(() => ({}))).error || 'Commit failed');
			this._commitResult = await res.json();
			this._committedCampaignId = this._commitResult.campaignId;
			this._step = 'activate';
		} catch (e: any) {
			this._error = e.message;
		}
		this._loading = false;
		this.render();
	}

	private async abandonWizard(): Promise<void> {
		if (!this._wizardId) return;
		await this.apiFetch(`/api/campaign/wizard/${this._wizardId}`, { method: 'DELETE' });
		window.location.href = `${this.basePath}/campaign-wizard`;
	}

	// ── Render ──

	private render(): void {
		if (!this.shadowRoot) return;
		this.shadowRoot.innerHTML = `
			<link rel="stylesheet" href="/modules/rsocials/campaign-wizard.css">
			<div class="cw-container">
				${this.renderHeader()}
				${this.renderStepIndicator()}
				${this._loading && this._step !== 'review' ? this.renderLoading() : this.renderCurrentStep()}
				${this._error ? `<div class="cw-panel" style="border-color:#dc2626;color:#f87171">${this.escHtml(this._error)}</div>` : ''}
			</div>
		`;
		this.bindEvents();
	}

	private renderHeader(): string {
		return `<div class="cw-header">
			<h1>Campaign Wizard</h1>
			<p>AI-guided campaign creation with step-by-step approval</p>
		</div>`;
	}

	private renderStepIndicator(): string {
		const current = STEP_ORDER[this._step] ?? 0;
		const committed = this._committedCampaignId != null;

		const items = STEPS.map((s, i) => {
			const isDone = committed || current > i;
			const isActive = !committed && current === i;
			const cls = isDone ? 'done' : isActive ? 'active' : '';
			const icon = isDone ? '\u2713' : String(s.num);
			return `
				<li class="cw-step ${cls}">
					<span class="cw-step__num">${icon}</span>
					<span>${s.label}</span>
				</li>
				${i < STEPS.length - 1 ? `<li class="cw-step__line" style="background:${isDone ? 'var(--rs-accent,#14b8a6)' : 'var(--rs-border,#333)'}"></li>` : ''}
			`;
		}).join('');

		return `<ul class="cw-steps">${items}</ul>`;
	}

	private renderLoading(): string {
		const labels: Record<string, string> = {
			brief: 'Analyzing your brief...',
			structure: 'Generating campaign structure...',
			content: 'Generating posts for each platform...',
			review: 'Regenerating post...',
			activate: 'Committing campaign...',
		};
		return `<div class="cw-loading"><div class="cw-spinner"></div><span>${labels[this._step] || 'Working...'}</span></div>`;
	}

	private renderCurrentStep(): string {
		if (this._committedCampaignId) return this.renderActivateStep();

		switch (this._step) {
			case 'brief': return this.renderBriefStep();
			case 'structure': return this.renderStructureStep();
			case 'content': return this.renderContentStep();
			case 'review': return this.renderReviewStep();
			case 'activate': return this.renderActivateStep();
			default: return this.renderBriefStep();
		}
	}

	private renderBriefStep(): string {
		const allPlatforms = ['x', 'linkedin', 'instagram', 'youtube', 'threads', 'bluesky', 'newsletter'];
		const platformChips = allPlatforms.map(p => {
			const active = this._selectedPlatforms.has(p);
			return `<label class="cw-platform-chip ${active ? 'cw-platform-chip--active' : ''}">
				<input type="checkbox" data-platform="${p}" ${active ? 'checked' : ''}>
				<span>${PLATFORM_ICONS[p] || ''} ${p}</span>
			</label>`;
		}).join('');

		return `<div class="cw-panel">
			<h2>Step 1: Paste Your Campaign Brief</h2>
			<p class="cw-hint">Paste raw text describing your event, product launch, or campaign goals. The AI will extract key details and propose a structure.</p>
			<textarea class="cw-textarea" id="brief-input" placeholder="Example: We're launching MycoFi at ETHDenver on March 25, 2026. Target audience is web3 developers and DeFi enthusiasts. We want to build hype for 2 weeks before, have a strong presence during the 3-day event, and follow up for a week after...">${this.escHtml(this._rawBrief)}</textarea>
			<div class="cw-platform-selector">
				<span class="cw-platform-selector__label">Include platforms:</span>
				<div class="cw-platform-selector__chips">${platformChips}</div>
			</div>
			<div class="cw-actions">
				<button class="cw-btn cw-btn--primary" id="analyze-btn" ${this._rawBrief.trim().length < 10 ? 'disabled' : ''}>Analyze Brief</button>
				<button class="cw-btn cw-btn--ghost" id="mi-btn">Refine with MI</button>
			</div>
		</div>`;
	}

	private renderStructureStep(): string {
		const brief = this._extractedBrief;
		const structure = this._structure;
		if (!brief || !structure) return '<div class="cw-panel">No structure data. Go back to Step 1.</div>';

		const briefFields = `
			<div class="cw-brief-summary">
				<div class="cw-brief-field"><div class="cw-brief-field__label">Title</div><div class="cw-brief-field__value">${this.escHtml(brief.title)}</div></div>
				<div class="cw-brief-field"><div class="cw-brief-field__label">Audience</div><div class="cw-brief-field__value">${this.escHtml(brief.audience)}</div></div>
				<div class="cw-brief-field"><div class="cw-brief-field__label">Dates</div><div class="cw-brief-field__value">${this.escHtml(brief.startDate)} to ${this.escHtml(brief.endDate)}</div></div>
				<div class="cw-brief-field"><div class="cw-brief-field__label">Tone / Style</div><div class="cw-brief-field__value">${this.escHtml(brief.tone)} / ${this.escHtml(brief.style)}</div></div>
				<div class="cw-brief-field"><div class="cw-brief-field__label">Platforms</div><div class="cw-brief-field__value">${brief.platforms.map(p => `${PLATFORM_ICONS[p] || ''} ${p}`).join(', ')}</div></div>
				<div class="cw-brief-field cw-brief-field--wide"><div class="cw-brief-field__label">Key Messages</div><div class="cw-brief-field__value">${brief.keyMessages.map(m => `<div>- ${this.escHtml(m)}</div>`).join('')}</div></div>
			</div>
		`;

		const phases = structure.phases.map((p, pi) => {
			const isExpanded = this._expandedPhases.has(pi);
			const chevronCls = isExpanded ? 'cw-phase-chevron cw-phase-chevron--open' : 'cw-phase-chevron';
			const instructions = this._phaseInstructions.get(pi) || '';

			// Infer post type per platform
			const postTypeMap: Record<string, string> = {
				x: 'thread', linkedin: 'text', instagram: 'carousel',
				youtube: 'video', threads: 'thread', bluesky: 'text', newsletter: 'email',
			};

			const postStubs = Object.entries(p.cadence || {}).map(([plat, count]) =>
				`<div class="cw-phase-preview-post">
					<span class="cw-cadence-badge">${PLATFORM_ICONS[plat] || ''} ${plat}</span>
					<span>${count} ${postTypeMap[plat] || 'text'} post${count !== 1 ? 's' : ''}</span>
					<span class="cw-phase-preview-post__spread">spread over ${this.escHtml(p.days)}</span>
				</div>`
			).join('');

			return `
			<div class="cw-phase-card">
				<div class="cw-phase-card__header cw-phase-card__header--clickable" data-phase-toggle="${pi}">
					<span class="cw-phase-card__name">${this.escHtml(p.label)}</span>
					<span style="display:flex;align-items:center;gap:0.5rem">
						<span class="cw-phase-card__days">${this.escHtml(p.days)}</span>
						<span class="${chevronCls}">\u25B6</span>
					</span>
				</div>
				<div class="cw-phase-card__cadence">
					${Object.entries(p.cadence || {}).map(([plat, count]) =>
						`<span class="cw-cadence-badge">${PLATFORM_ICONS[plat] || ''} ${plat}: ${count} post${count !== 1 ? 's' : ''}</span>`
					).join('')}
				</div>
				${isExpanded ? `
				<div class="cw-phase-card__preview">
					${postStubs}
					<textarea class="cw-phase-instructions" data-phase-instructions="${pi}" placeholder="Optional: guide the AI for this phase (e.g. 'focus on countdown energy')">${this.escHtml(instructions)}</textarea>
				</div>
				` : ''}
			</div>
			`;
		}).join('');

		return `
			<div class="cw-panel">
				<h2>Step 2: Review Campaign Structure</h2>
				<p class="cw-hint">${this.escHtml(structure.summary)}</p>
				${briefFields}
			</div>
			<div class="cw-panel">
				<h2>Proposed Phases</h2>
				<div class="cw-phases">${phases}</div>
				<div class="cw-actions">
					<button class="cw-btn cw-btn--primary" id="approve-structure-btn">Approve & Generate Content</button>
					<button class="cw-btn" id="regen-structure-btn">Regenerate Structure</button>
					<button class="cw-btn cw-btn--ghost" id="back-to-brief-btn">Back to Brief</button>
				</div>
			</div>
		`;
	}

	private renderContentStep(): string {
		if (!this._campaignDraft) return '<div class="cw-panel">No content generated yet.</div>';

		const campaign = this._campaignDraft;
		const postsByPhase = new Map<number, CampaignPost[]>();
		for (const post of campaign.posts) {
			const arr = postsByPhase.get(post.phase) || [];
			arr.push(post);
			postsByPhase.set(post.phase, arr);
		}

		const phaseSections = campaign.phases.map((phase, pi) => {
			const posts = postsByPhase.get(pi + 1) || [];
			const postCards = posts.map(p => `
				<div class="cw-phase-card" style="margin-bottom:0.5rem">
					<div class="cw-phase-card__header">
						<span><span class="cw-platform-badge cw-platform-badge--${p.platform}">${PLATFORM_ICONS[p.platform] || ''} ${p.platform}</span> ${this.escHtml(p.postType)}</span>
						<span class="cw-phase-card__days">${p.scheduledAt?.split('T')[0] || ''}</span>
					</div>
					<div class="cw-post-content cw-post-content--truncated">${this.escHtml(p.content)}</div>
					${p.threadPosts?.length ? `<div style="font-size:0.75rem;color:var(--rs-text-muted,#64748b);margin-top:0.25rem">${p.threadPosts.length} tweets in thread</div>` : ''}
					${p.hashtags?.length ? `<div style="font-size:0.75rem;color:var(--rs-accent,#14b8a6);margin-top:0.25rem">#${p.hashtags.join(' #')}</div>` : ''}
				</div>
			`).join('');

			return `
				<div class="cw-panel">
					<h2>${this.escHtml(phase.label)} <span style="font-weight:400;font-size:0.85rem;color:var(--rs-text-muted,#64748b)">(${this.escHtml(phase.days)})</span></h2>
					<div class="cw-phases">${postCards}</div>
				</div>
			`;
		}).join('');

		return `
			<div class="cw-panel">
				<h2>Step 3: Generated Content</h2>
				<p class="cw-hint">${campaign.posts.length} posts across ${campaign.platforms.length} platforms in ${campaign.phases.length} phases</p>
			</div>
			${phaseSections}
			<div class="cw-actions" style="margin-bottom:1.5rem">
				<button class="cw-btn cw-btn--primary" id="approve-content-btn">Proceed to Review</button>
				<button class="cw-btn" id="regen-content-btn">Regenerate All Content</button>
				<button class="cw-btn cw-btn--ghost" id="back-to-structure-btn">Back to Structure</button>
			</div>
		`;
	}

	private renderReviewStep(): string {
		if (!this._campaignDraft) return '<div class="cw-panel">No campaign to review.</div>';

		const campaign = this._campaignDraft;
		const rows = campaign.posts.map((p, i) => {
			const isExpanded = this._expandedPosts.has(i);
			const isRegening = this._regenIndex === i && this._loading;
			const contentCls = isExpanded ? 'cw-post-content' : 'cw-post-content cw-post-content--truncated';

			return `<tr>
				<td>${p.stepNumber}</td>
				<td><span class="cw-platform-badge cw-platform-badge--${p.platform}">${PLATFORM_ICONS[p.platform] || ''} ${p.platform}</span></td>
				<td>${this.escHtml(p.phaseLabel)}</td>
				<td>
					<div class="${contentCls}" data-expand="${i}" style="cursor:pointer">${this.escHtml(p.content)}</div>
					${p.threadPosts?.length ? `<div style="font-size:0.7rem;color:var(--rs-text-muted)">${p.threadPosts.length} tweets</div>` : ''}
					${p.emailSubject ? `<div style="font-size:0.7rem;color:var(--rs-text-muted)">Subject: ${this.escHtml(p.emailSubject)}</div>` : ''}
				</td>
				<td>${p.scheduledAt?.split('T')[0] || '-'}</td>
				<td>
					${isRegening
						? '<div class="cw-spinner" style="width:16px;height:16px"></div>'
						: `<button class="cw-btn" style="padding:0.3rem 0.6rem;font-size:0.75rem" data-regen="${i}">Regen</button>`
					}
				</td>
			</tr>`;
		}).join('');

		return `
			<div class="cw-panel">
				<h2>Step 4: Review All Posts</h2>
				<p class="cw-hint">Click any post content to expand. Use Regen to regenerate individual posts.</p>
				<div style="overflow-x:auto">
					<table class="cw-posts-table">
						<thead><tr>
							<th>#</th><th>Platform</th><th>Phase</th><th>Content</th><th>Scheduled</th><th></th>
						</tr></thead>
						<tbody>${rows}</tbody>
					</table>
				</div>
				<div class="cw-actions">
					<button class="cw-btn cw-btn--primary" id="commit-btn">Activate Campaign</button>
					<button class="cw-btn cw-btn--ghost" id="back-to-content-btn">Back to Content</button>
					<button class="cw-btn cw-btn--danger" id="abandon-btn">Abandon Wizard</button>
				</div>
			</div>
		`;
	}

	private renderActivateStep(): string {
		if (this._committedCampaignId) {
			const result = this._commitResult || {};
			return `<div class="cw-panel">
				<div class="cw-success">
					<div class="cw-success__icon">\u2705</div>
					<h2>Campaign Activated!</h2>
					<p style="color:var(--rs-text-secondary,#94a3b8)">Your campaign has been committed successfully.</p>
					${result.threads?.length ? `<div style="margin:0.5rem 0">
						<p style="font-size:0.85rem;color:var(--rs-text-muted,#64748b);margin:0 0 0.4rem">${result.threads.length} thread(s) created:</p>
						<div style="display:flex;flex-direction:column;gap:0.3rem">
							${result.threads.map((t: any) => `<a href="${this.basePath}/thread-editor/${t.id}/edit" style="font-size:0.8rem;color:#60a5fa;text-decoration:none">\u270F\uFE0F ${t.title || t.id}</a>`).join('')}
						</div>
					</div>` : result.threadIds?.length ? `<p style="font-size:0.85rem;color:var(--rs-text-muted,#64748b)">${result.threadIds.length} thread(s) created</p>` : ''}
					${result.newsletters?.length ? `<p style="font-size:0.85rem;color:var(--rs-text-muted,#64748b)">${result.newsletters.length} newsletter draft(s)</p>` : ''}
					<div class="cw-success__links">
						${result.flowId ? `<a href="${this.basePath}/campaign-flow?id=${result.flowId}">Open in Planner</a>` : ''}
						<a href="${this.basePath}/campaigns">All Campaigns</a>
						<a href="${this.basePath}/threads">View Threads</a>
						<a href="${this.basePath}/campaign-wizard">New Wizard</a>
					</div>
				</div>
			</div>`;
		}

		return `<div class="cw-panel">
			<h2>Step 5: Activate</h2>
			<p class="cw-hint">Click Activate to commit the campaign, create threads, draft newsletters, and build the workflow.</p>
			<div class="cw-actions">
				<button class="cw-btn cw-btn--primary" id="commit-btn">Activate Campaign</button>
				<button class="cw-btn cw-btn--ghost" id="back-to-review-btn">Back to Review</button>
			</div>
		</div>`;
	}

	// ── Event binding ──

	private bindEvents(): void {
		const sr = this.shadowRoot!;

		// Brief step
		const briefInput = sr.querySelector('#brief-input') as HTMLTextAreaElement | null;
		if (briefInput) {
			briefInput.addEventListener('input', () => {
				this._rawBrief = briefInput.value;
				const btn = sr.querySelector('#analyze-btn') as HTMLButtonElement | null;
				if (btn) btn.disabled = this._rawBrief.trim().length < 10;
			});
		}

		// Platform checkbox toggles
		sr.querySelectorAll('input[data-platform]').forEach(el => {
			el.addEventListener('change', () => {
				const cb = el as HTMLInputElement;
				const plat = cb.getAttribute('data-platform')!;
				if (cb.checked) {
					this._selectedPlatforms.add(plat);
				} else if (this._selectedPlatforms.size > 1) {
					this._selectedPlatforms.delete(plat);
				} else {
					cb.checked = true; // prevent unchecking the last one
					return;
				}
				this.render();
			});
		});

		sr.querySelector('#analyze-btn')?.addEventListener('click', () => this.analyzebrief());
		sr.querySelector('#mi-btn')?.addEventListener('click', () => {
			this.dispatchEvent(new CustomEvent('mi-prompt', {
				bubbles: true, composed: true,
				detail: { prompt: `Help me refine this campaign brief:\n\n${this._rawBrief}` },
			}));
		});

		// Structure step — phase card expand/collapse
		sr.querySelectorAll('[data-phase-toggle]').forEach(el => {
			el.addEventListener('click', () => {
				const pi = parseInt(el.getAttribute('data-phase-toggle')!);
				if (this._expandedPhases.has(pi)) this._expandedPhases.delete(pi);
				else this._expandedPhases.add(pi);
				this.render();
			});
		});
		sr.querySelectorAll('[data-phase-instructions]').forEach(el => {
			const ta = el as HTMLTextAreaElement;
			ta.addEventListener('click', (e) => e.stopPropagation());
			ta.addEventListener('input', () => {
				const pi = parseInt(ta.getAttribute('data-phase-instructions')!);
				this._phaseInstructions.set(pi, ta.value);
			});
		});

		sr.querySelector('#approve-structure-btn')?.addEventListener('click', () => this.generateContent());
		sr.querySelector('#regen-structure-btn')?.addEventListener('click', () => this.analyzebrief());
		sr.querySelector('#back-to-brief-btn')?.addEventListener('click', () => { this._step = 'brief'; this.render(); });

		// Content step
		sr.querySelector('#approve-content-btn')?.addEventListener('click', () => { this._step = 'review'; this.render(); });
		sr.querySelector('#regen-content-btn')?.addEventListener('click', () => this.generateContent());
		sr.querySelector('#back-to-structure-btn')?.addEventListener('click', () => { this._step = 'structure'; this.render(); });

		// Review step — expand and regen
		sr.querySelectorAll('[data-expand]').forEach(el => {
			el.addEventListener('click', () => {
				const idx = parseInt(el.getAttribute('data-expand')!);
				if (this._expandedPosts.has(idx)) this._expandedPosts.delete(idx);
				else this._expandedPosts.add(idx);
				this.render();
			});
		});
		sr.querySelectorAll('[data-regen]').forEach(el => {
			el.addEventListener('click', () => {
				const idx = parseInt(el.getAttribute('data-regen')!);
				this.regenPost(idx);
			});
		});

		// Commit / back / abandon
		sr.querySelector('#commit-btn')?.addEventListener('click', () => this.commitCampaign());
		sr.querySelector('#back-to-content-btn')?.addEventListener('click', () => { this._step = 'content'; this.render(); });
		sr.querySelector('#back-to-review-btn')?.addEventListener('click', () => { this._step = 'review'; this.render(); });
		sr.querySelector('#abandon-btn')?.addEventListener('click', () => {
			if (confirm('Are you sure you want to abandon this wizard? All progress will be lost.')) {
				this.abandonWizard();
			}
		});
	}

	private escHtml(s: string): string {
		const d = document.createElement('div');
		d.textContent = s;
		return d.innerHTML;
	}
}

customElements.define('folk-campaign-wizard', FolkCampaignWizard);
