/**
 * Sifency AI Studio — Admin Panel JS (v2.1 Premium)
 *
 * ES2020+ vanilla JS. Rendered inside #sifency-ai-root.
 * Features:
 *   - Generator type selector with active state disables during loading
 *   - Premium typing animation for quick-prompts selection
 *   - Toast notifications
 *   - Interactive My Items table with inline, expanding code preview panels
 *   - Settings tab with inline spinner, dynamic provider placeholder mappings, and "Saved ✓" checkmark indicator
 *   - Keyboard Ctrl+Enter shortcut with explicit visual hint
 *   - Focus recovery on generation failure
 */
(function () {
	'use strict';

	const { nonce, ajax_url, settings: initSettings, counts: initCounts, types, i18n } =
		window.SifencyAI || {};

	/* ------------------------------------------------------------------ */
	/*  AJAX helper                                                         */
	/* ------------------------------------------------------------------ */

	async function ajax(action, data = {}) {
		const body = new FormData();
		body.append('action', action);
		body.append('nonce', nonce);
		for (const [k, v] of Object.entries(data)) body.append(k, String(v));
		const res = await fetch(ajax_url, { method: 'POST', body });
		const json = await res.json();
		return json; // { success: bool, data: … }
	}

	/* ------------------------------------------------------------------ */
	/*  State                                                               */
	/* ------------------------------------------------------------------ */

	const state = {
		tab: 'generate',   // 'generate' | 'items' | 'settings'
		genType: 'widget',     // active generator type key
		loading: false,
		progress: 0,            // 0–100
		progressTimer: null,
		result: null,
		prompt: '',
		items: {},           // { widget: [], cpt: [], … }
		itemsType: 'widget',     // active type in items tab
		expandedItems: new Set(), // Set of filenames currently expanded in Items table
		settings: { ...(initSettings || { provider: 'openai', model: '', api_key: '', has_key: false }) },
		counts: { ...(initCounts || {}) },
	};

	/* ------------------------------------------------------------------ */
	/*  Quick-Prompts per type                                              */
	/* ------------------------------------------------------------------ */

	const QUICK_PROMPTS = {
		widget: [
			'Testimonial card with avatar, name, role, star rating, and quote',
			'Pricing table with 3 tiers, highlights, and CTA button',
			'Team member card with photo, social links, and hover animation',
			'FAQ accordion with smooth open/close animation',
			'Call-to-action section with background image, headline, and button',
			'Icon box with title, description and entrance animation',
			'Portfolio grid with category filter tabs',
			'Countdown timer with days, hours, minutes, seconds',
		],
		cpt: [
			'Portfolio post type for creative agencies with project category taxonomy',
			'Events post type with date, venue, and ticket link fields',
			'Team member post type with position and department taxonomy',
			'Testimonials post type with client info and star rating',
			'Services post type for agencies with service category taxonomy',
			'Case studies post type with industry taxonomy',
			'Job listings post type with job type and location taxonomy',
			'Product reviews post type with rating and reviewer taxonomy',
		],
		'builder-item': [
			'Sticky header with logo and navigation',
			'Footer with 3 columns: about, links, contact',
			'Popup with email opt-in form',
		],
		metabox: [
			'Project details metabox with URL, client, and year fields',
			'Event details metabox with start date, end date, venue, and ticket URL',
			'SEO metabox with custom title, description, and OG image fields',
		],
	};

	/* ------------------------------------------------------------------ */
	/*  Root mount                                                          */
	/* ------------------------------------------------------------------ */

	const root = document.getElementById('sifency-ai-root');
	if (!root) return;

	function mount() {
		root.innerHTML = render();
		attachEvents();
	}

	/* ------------------------------------------------------------------ */
	/*  Toast system                                                        */
	/* ------------------------------------------------------------------ */

	let toastContainer = null;

	function ensureToastContainer() {
		if (!toastContainer) {
			toastContainer = document.createElement('div');
			toastContainer.className = 'sai-toast-container';
			document.body.appendChild(toastContainer);
		}
	}

	function toast(message, type = 'success', duration = 4000) {
		ensureToastContainer();
		const t = document.createElement('div');
		t.className = `sai-toast sai-toast--${type}`;
		t.innerHTML = `<span class="sai-toast__icon">${type === 'success' ? '✅' : type === 'error' ? '❌' : 'ℹ️'}</span>
		               <span class="sai-toast__msg">${escHtml(message)}</span>
		               <button class="sai-toast__close" aria-label="Close">×</button>`;
		toastContainer.appendChild(t);

		// Animate in
		requestAnimationFrame(() => t.classList.add('is-visible'));

		const remove = () => {
			t.classList.remove('is-visible');
			t.addEventListener('transitionend', () => t.remove(), { once: true });
		};
		t.querySelector('.sai-toast__close').addEventListener('click', remove);
		if (duration > 0) setTimeout(remove, duration);
	}

	/* ------------------------------------------------------------------ */
	/*  Progress bar                                                        */
	/* ------------------------------------------------------------------ */

	function startProgress() {
		state.progress = 0;
		state.progressTimer = setInterval(() => {
			if (state.progress < 70) {
				state.progress += 3 + Math.random() * 4;
			} else if (state.progress < 90) {
				state.progress += 0.4 + Math.random() * 0.6;
			}
			state.progress = Math.min(state.progress, 90);
			updateProgressBar();
		}, 300);
	}

	function stopProgress(success = true) {
		clearInterval(state.progressTimer);
		state.progressTimer = null;
		state.progress = success ? 100 : 0;
		updateProgressBar();
		if (success) {
			setTimeout(() => {
				state.progress = 0;
				updateProgressBar();
			}, 600);
		}
	}

	function updateProgressBar() {
		const bar = document.querySelector('.sai-progress-bar__fill');
		if (bar) {
			bar.style.width = state.progress + '%';
			bar.style.opacity = state.progress > 0 ? '1' : '0';
		}
	}

	/* ------------------------------------------------------------------ */
	/*  Render                                                              */
	/* ------------------------------------------------------------------ */

	function render() {
		return `<div class="sai-wrap">
			${renderHeader()}
			${renderProgress()}
			${renderTabs()}
			<div class="sai-tab-content">
				${state.tab === 'generate' ? renderGenerate() : ''}
				${state.tab === 'items' ? renderItems() : ''}
				${state.tab === 'settings' ? renderSettings() : ''}
			</div>
		</div>`;
	}

	/* --- Header --------------------------------------------------------- */

	function renderHeader() {
		const totalItems = Object.values(state.counts).reduce((s, c) => s + (c.total || 0), 0);
		return `<div class="sai-header">
			<div class="sai-header__left">
				<div class="sai-header__logo">
					<svg viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
						<rect width="40" height="40" rx="10" fill="url(#grad)"/>
						<defs>
							<linearGradient id="grad" x1="0" y1="0" x2="40" y2="40" gradientUnits="userSpaceOnUse">
								<stop offset="0%" stop-color="#6366f1"/>
								<stop offset="100%" stop-color="#4f46e5"/>
							</linearGradient>
						</defs>
						<path d="M12 20 L20 12 L28 20 L20 28 Z" fill="white" opacity=".95"/>
						<circle cx="20" cy="20" r="5" fill="#6366f1"/>
						<circle cx="20" cy="20" r="2" fill="white"/>
					</svg>
				</div>
				<div>
					<h1 class="sai-header__title">Sifency AI Studio</h1>
					<p class="sai-header__sub">AI-powered code generation for your WordPress plugin</p>
				</div>
			</div>
			<div class="sai-header__right">
				<div class="sai-stat">
					<span class="sai-stat__num">${totalItems}</span>
					<span class="sai-stat__label">Generated</span>
				</div>
				<span class="sai-badge">Beta</span>
				${!state.settings.has_key ? `<a href="#" class="sai-btn sai-btn--warning sai-setup-key-btn" id="sai-setup-key-btn">⚠️ Setup API Key</a>` : ''}
			</div>
		</div>`;
	}

	/* --- Progress bar --------------------------------------------------- */

	function renderProgress() {
		return `<div class="sai-progress-bar" style="opacity:${state.loading ? 1 : 0}">
			<div class="sai-progress-bar__fill" style="width:${state.progress}%"></div>
		</div>`;
	}

	/* --- Tabs ----------------------------------------------------------- */

	function renderTabs() {
		const tabs = [
			{ key: 'generate', label: '✨ Generate' },
			{ key: 'items', label: '📦 My Items' },
			{ key: 'settings', label: '⚙️ Settings' },
		];
		return `<div class="sai-tabs">
			${tabs.map(t => `
				<button class="sai-tab ${state.tab === t.key ? 'is-active' : ''}" data-tab="${t.key}">
					${t.label}
				</button>
			`).join('')}
		</div>`;
	}

	/* --- Generate Tab --------------------------------------------------- */

	function renderGenerate() {
		const typeDefs = types || {};
		return `
		<div class="sai-generate-layout">
			<!-- Left column: Type Selector -->
			<div class="sai-card sai-type-selector-card">
				<h2 class="sai-card__title">
					<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"></path><polyline points="3.27 6.96 12 12.01 20.73 6.96"></polyline><line x1="12" y1="22.08" x2="12" y2="12"></line></svg>
					Generator Types
				</h2>
				<div class="sai-type-grid">
					${Object.entries(typeDefs).map(([key, def]) => `
						<button class="sai-type-card ${state.genType === key ? 'is-active' : ''} ${def.coming_soon ? 'is-coming-soon' : ''}"
							data-gen-type="${key}" ${def.coming_soon || state.loading ? 'disabled' : ''}>
							<div class="sai-type-card__icon">${def.icon}</div>
							<div class="sai-type-card__text">
								<span class="sai-type-card__label">${escHtml(def.label)}</span>
								<span class="sai-type-card__sublabel">${key === 'widget' ? 'Elementor' : key === 'cpt' ? 'WordPress CPT' : key === 'metabox' ? 'Fields Panel' : 'Conditions'}</span>
							</div>
							${def.coming_soon ? '<span class="sai-type-card__badge">Soon</span>' : ''}
						</button>
					`).join('')}
				</div>
				${typeDefs[state.genType] ? `<p class="sai-type-desc">${escHtml(typeDefs[state.genType].description)}</p>` : ''}
			</div>
			
			<!-- Right column: Prompt + Generate -->
				<div class="sai-card sai-prompt-card">
					<h2 class="sai-card__title">
						<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path></svg>
						Describe what you want to build
					</h2>
					<div class="sai-prompt-wrap">
						<textarea id="sai-prompt" class="sai-prompt" rows="5"
							placeholder="${getPlaceholder(state.genType)}"
							${state.loading ? 'disabled' : ''}
						>${escHtml(state.prompt)}</textarea>
						<div class="sai-prompt-footer">
							<span class="sai-char-count" id="sai-char-count">0 chars (Ctrl+Enter to Generate)</span>
							<div class="sai-prompt-actions">
								<button id="sai-generate-btn" class="sai-btn sai-btn--primary" ${state.loading ? 'disabled' : ''}>
									${state.loading
				? `<span class="sai-spinner"></span> ${escHtml(i18n?.generating || 'Generating…')}`
				: `Generate`}
								</button>
							</div>
						</div>	
					</div>
					${renderResult()}
					<div class="cs-height-50"></div>
					<h2 class="sai-card__title">
						<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"></polygon></svg>
						Quick Prompts
					</h2>
					<div class="sai-quick-grid">
						${(QUICK_PROMPTS[state.genType] || []).map(p => `
							<button class="sai-quick-prompt" data-prompt="${escAttr(p)}" ${state.loading ? 'disabled' : ''}>
								${escHtml(p)}
							</button>
						`).join('')}
					</div>
				</div>
		</div>`;
	}

	function getPlaceholder(type) {
		const map = {
			widget: 'e.g. A testimonial card widget with avatar, name, role, quote, and star rating with hover shadow effect and color controls.',
			cpt: 'e.g. A portfolio post type for creative agencies with project category and tag taxonomy.',
			'builder-item': 'e.g. A sticky header that hides on scroll down and shows on scroll up.',
			metabox: 'e.g. A project details metabox for the portfolio post type with client, URL, year, and budget fields.',
		};
		return map[type] || 'Describe what you want to build…';
	}

	function renderResult() {
		if (!state.result) return '';
		const r = state.result;
		if (r.type === 'success') {
			return `<div class="sai-result sai-result--success">
				<div class="sai-result__header">
					<span class="sai-result__icon">✅</span>
					<strong class="sai-result__title">${escHtml(r.message)}</strong>
				</div>
				${r.code_preview ? `
				<div class="sai-code-wrap">
					<div class="sai-code-header">
						<span>Generated PHP Code Preview</span>
						<button class="sai-copy-btn" data-code="${escAttr(r.raw_code || r.code_preview)}">📋 Copy Code</button>
					</div>
					<pre class="sai-code-preview">${escHtml(r.code_preview)}</pre>
				</div>` : ''}
			</div>`;
		}
		return `<div class="sai-result sai-result--error">
			<span class="sai-result__icon">❌</span>
			<strong class="sai-result__title">${escHtml(r.message)}</strong>
			<button id="sai-try-again-btn" class="sai-btn sai-btn--warning" style="margin-left: auto; padding: 6px 12px; font-size: 11px;">Try Again</button>
		</div>`;
	}

	/* ------------------------------------------------------------------ */
	/*  Items Tab ------------------------------------------------------ */
	/* ------------------------------------------------------------------ */

	function renderItems() {
		const typeDefs = types || {};
		const available = Object.entries(typeDefs).filter(([, d]) => !d.coming_soon);
		const current = state.items[state.itemsType] || [];

		return `<div class="sai-items-layout">
			<!-- Type filter tabs -->
			<div class="sai-items-type-bar">
				${available.map(([key, def]) => {
			const count = (state.items[key] || []).length;
			return `<button class="sai-items-type-tab ${state.itemsType === key ? 'is-active' : ''}" data-items-type="${key}">
						${def.icon} ${escHtml(def.label)}
						${count > 0 ? `<span class="sai-badge sai-badge--count">${count}</span>` : ''}
					</button>`;
		}).join('')}
				<button id="sai-refresh-btn" class="sai-btn sai-btn--ghost" style="margin-left:auto">↻ Refresh Table</button>
			</div>

			<div class="sai-table-container">
				${current.length === 0
				? `<div class="sai-empty">
						<div class="sai-empty__icon">✨</div>
						<p class="sai-empty__title">No ${escHtml(typeDefs[state.itemsType]?.label || 'items')} generated yet</p>
						<p class="sai-empty__sub">Go to the Generate tab to create your first item.</p>
						<button class="sai-btn sai-btn--primary sai-goto-generate" data-gen-type="${state.itemsType}">
							✨ Generate one now
						</button>
					</div>`
				: `<table class="sai-table">
						<thead>
							<tr>
								<th style="width: 40%">Slug / Filename</th>
								<th style="width: 20%">Created At</th>
								<th style="width: 15%">File Size</th>
								<th style="width: 10%">Active</th>
								<th style="width: 15%; text-align: right;">Actions</th>
							</tr>
						</thead>
						<tbody>
							${current.flatMap(item => {
					const isExpanded = state.expandedItems.has(item.filename);
					const rows = [`
							<tr class="${isExpanded ? 'sai-row-expanded' : ''}">
								<td>
									<span class="sai-slug">${escHtml(item.slug)}</span>
									<span class="sai-filename">${escHtml(item.filename)}</span>
								</td>
								<td><span class="sai-muted">${escHtml(item.created || '—')}</span></td>
								<td><span class="sai-muted">${formatBytes(item.size)}</span></td>
								<td>
									<label class="sai-toggle" title="${item.enabled ? 'Disable' : 'Enable'}">
										<input type="checkbox" class="sai-toggle-input"
											data-filename="${escAttr(item.filename)}"
											data-type="${escAttr(typeDefs[state.itemsType]?.folder || state.itemsType)}"
											${item.enabled ? 'checked' : ''}>
										<span class="sai-toggle-slider"></span>
									</label>
								</td>
								<td style="text-align: right;">
									<div class="d-flex align-items-center justify-content-end gap-3" style="display:inline-flex !important">
										<button class="sai-btn sai-btn--ghost sai-expand-code-btn"
											data-filename="${escAttr(item.filename)}"
											data-type="${escAttr(typeDefs[state.itemsType]?.folder || state.itemsType)}"
											style="padding: 6px 12px; font-size: 11px;">
											${isExpanded ? 'Hide Code' : 'View Code'}
										</button>
										<button class="sai-btn sai-btn--danger sai-delete-btn"
											data-filename="${escAttr(item.filename)}"
											data-type="${escAttr(typeDefs[state.itemsType]?.folder || state.itemsType)}"
											title="Delete permanently"
											style="padding: 6px 10px;">
											🗑
										</button>
									</div>
								</td>
							</tr>`];

					if (isExpanded) {
						rows.push(`
							<tr class="sai-preview-row">
								<td colspan="5">
									<div class="sai-table-code-expanded">
										<div class="d-flex align-items-center justify-content-between mb-3">
											<strong class="sai-muted" style="font-size: 11px; text-transform: uppercase;">File Preview: ${escHtml(item.filename)}</strong>
											<button class="sai-copy-btn" data-code="${escAttr(item.code_content || '')}">📋 Copy Entire File</button>
										</div>
										<pre><code>${escHtml(item.code_content || '// Loading code content…')}</code></pre>
									</div>
								</td>
							</tr>
				`);
					}

					return rows;
				}).join('')}
						</tbody>
					</table>`}
			</div>
		</div>`;
	}

	/* --- Settings Tab --------------------------------------------------- */

	function renderSettings() {
		const s = state.settings;
		const providers = [
			{ value: 'openai', label: 'OpenAI', hint: 'Default: gpt-4.5 (Premier flagship model)' },
			{ value: 'anthropic', label: 'Anthropic (Claude)', hint: 'Default: claude-3-7-sonnet-20260219 (Latest 2026 flagship)' },
			{ value: 'gemini', label: 'Google Gemini', hint: 'Default: gemini-2.0-flash (Ultra-fast and smart)' },
			{ value: 'groq', label: 'Groq (Free)', hint: 'Default: llama-3.3-70b-versatile (Capable open source)' },
		];

		return `<div class="sai-settings-layout">
			<div class="sai-card">
				<h2 class="sai-card__title">
					<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="18" height="11" x="3" y="11" rx="2" ry="2"></rect><path d="M7 11V7a5 5 0 0 1 10 0v4"></path></svg>
					AI Provider & API Key
				</h2>
				<p class="sai-settings-desc">
					Configure the AI provider and key. Your API key is stored securely in the WordPress database (wp_options) and never exposed in the page source.
				</p>

				<div class="sai-field">
					<label class="sai-label">Provider</label>
					<div class="sai-provider-grid">
						${providers.map(p => `
							<label class="sai-provider-card ${s.provider === p.value ? 'is-active' : ''}">
								<input type="radio" name="sai_provider" value="${p.value}" ${s.provider === p.value ? 'checked' : ''}>
								<span class="sai-provider-card__name">${escHtml(p.label)}</span>
								<span class="sai-provider-card__hint">${escHtml(p.hint)}</span>
							</label>
						`).join('')}
					</div>
				</div>

				<div class="sai-field">
					<label class="sai-label" for="sai-model">Model <span class="sai-label-hint">(leave blank to use the default model)</span></label>
					<input id="sai-model" type="text" class="sai-input"
						placeholder="${s.provider === 'anthropic' ? 'claude-3-7-sonnet-20260219' : s.provider === 'gemini' ? 'gemini-2.0-flash' : s.provider === 'groq' ? 'llama-3.3-70b-versatile' : 'gpt-4.5'}"
						value="${escAttr(s.model)}">
				</div>

				<div class="sai-field">
					<label class="sai-label" for="sai-api-key">
						API Key
						${s.has_key ? '<span class="sai-key-status sai-key-status--set">✓ Key set</span>' : '<span class="sai-key-status sai-key-status--missing">⚠ Not set</span>'}
					</label>
					<div class="sai-key-wrap">
						<input id="sai-api-key" type="password" class="sai-input"
							placeholder="sk-…  or  sk-ant-…"
							value="${escAttr(s.api_key)}"
							autocomplete="new-password">
						<button class="sai-toggle-key-vis" type="button" id="sai-toggle-key">👁</button>
					</div>
					<p class="sai-field-hint">Enter your new API key only if you want to replace the current one.</p>
				</div>

				<div class="sai-settings-actions">
					<button id="sai-save-settings-btn" class="sai-btn sai-btn--primary">
						Save Settings
					</button>
					<a href="https://platform.openai.com/api-keys" target="_blank" rel="noopener noreferrer" class="sai-btn sai-btn--ghost">
						Get OpenAI Key ↗
					</a>
					<a href="https://console.anthropic.com/settings/keys" target="_blank" rel="noopener noreferrer" class="sai-btn sai-btn--ghost">
						Get Claude Key ↗
					</a>
					<a href="https://aistudio.google.com/app/apikey" target="_blank" rel="noopener noreferrer" class="sai-btn sai-btn--ghost">
						Get Gemini Key ↗
					</a>
					<a href="https://console.groq.com/keys" target="_blank" rel="noopener noreferrer" class="sai-btn sai-btn--ghost">
						Get Groq Key ↗
					</a>
				</div>
			</div>

			<!-- About / How it works -->
			<div class="sai-card sai-info-card">
				<h2 class="sai-card__title">
					<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="16" x2="12" y2="12"></line><line x1="12" y1="8" x2="12.01" y2="8"></line></svg>
					How Sifency AI Works
				</h2>
				<ul class="sai-how-list">
					<li><span class="sai-how-num">1</span> Select CPT, Widget, Metabox, or Builder Item card on the left.</li>
					<li><span class="sai-how-num">2</span> Enter a prompt, or click a "Quick Prompt" pill to autofill.</li>
					<li><span class="sai-how-num">3</span> AI generates production-ready PHP followingThemeForest standards.</li>
					<li><span class="sai-how-num">4</span> The code is fully cleaned, syntax checked, and written safely to the disk.</li>
					<li><span class="sai-how-num">5</span> Dynamic loader hooks it in securely without crashing the site if errors arise.</li>
				</ul>
			</div>
		</div>`;
	}

	/* ------------------------------------------------------------------ */
	/*  Event Handlers                                                      */
	/* ------------------------------------------------------------------ */

	function attachEvents() {
		// Tab switching
		document.querySelectorAll('.sai-tab').forEach(btn => {
			btn.addEventListener('click', () => {
				state.tab = btn.dataset.tab;
				if (state.tab === 'items') loadAllItems().then(mount);
				else mount();
			});
		});

		// Setup key shortcut from header warning button
		const setupKeyBtn = document.getElementById('sai-setup-key-btn');
		if (setupKeyBtn) {
			setupKeyBtn.addEventListener('click', e => {
				e.preventDefault();
				state.tab = 'settings';
				mount();
			});
		}

		// Generator type cards
		document.querySelectorAll('.sai-type-card').forEach(card => {
			card.addEventListener('click', () => {
				if (card.disabled || state.loading) return;
				state.genType = card.dataset.genType;
				state.prompt = '';
				state.result = null;
				mount();
			});
		});

		// Prompt textarea — character count + Ctrl+Enter
		const ta = document.getElementById('sai-prompt');
		if (ta) {
			ta.addEventListener('input', () => {
				const count = ta.value.length;
				const el = document.getElementById('sai-char-count');
				if (el) el.textContent = count + ' char' + (count !== 1 ? 's' : '') + ' (Ctrl+Enter to Generate)';
				state.prompt = ta.value;
			});
			ta.addEventListener('keydown', e => {
				if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') handleGenerate();
			});
			// Init count
			const el = document.getElementById('sai-char-count');
			if (el) el.textContent = ta.value.length + ' chars (Ctrl+Enter to Generate)';
		}

		// Generate button
		const genBtn = document.getElementById('sai-generate-btn');
		if (genBtn) genBtn.addEventListener('click', handleGenerate);

		// Try Again button
		const tryBtn = document.getElementById('sai-try-again-btn');
		if (tryBtn) {
			tryBtn.addEventListener('click', () => {
				const taFocus = document.getElementById('sai-prompt');
				if (taFocus) {
					taFocus.focus();
					taFocus.scrollIntoView({ behavior: 'smooth', block: 'center' });
				}
			});
		}

		// Quick prompts with smooth typing simulation
		document.querySelectorAll('.sai-quick-prompt').forEach(btn => {
			btn.addEventListener('click', () => {
				if (state.loading) return;
				const taInput = document.getElementById('sai-prompt');
				if (!taInput) return;

				const targetText = btn.dataset.prompt;
				let currentLen = 0;

				// Typing simulation effect
				taInput.value = '';
				taInput.focus();
				btn.disabled = true;

				const timer = setInterval(() => {
					currentLen += 3; // Type 3 chars at a time for snappiness
					taInput.value = targetText.slice(0, currentLen);
					state.prompt = taInput.value;

					const el = document.getElementById('sai-char-count');
					if (el) el.textContent = state.prompt.length + ' chars (Ctrl+Enter to Generate)';

					if (currentLen >= targetText.length) {
						clearInterval(timer);
						btn.disabled = false;
					}
				}, 15);

				taInput.scrollIntoView({ behavior: 'smooth', block: 'center' });
			});
		});

		// Copy code button
		document.querySelectorAll('.sai-copy-btn').forEach(btn => {
			btn.addEventListener('click', () => {
				const code = btn.dataset.code;
				navigator.clipboard?.writeText(code).then(() => {
					btn.textContent = '✓ Copied Code!';
					setTimeout(() => { btn.textContent = '📋 Copy Code'; }, 2000);
				}).catch(() => toast('Could not copy to clipboard', 'error'));
			});
		});

		// Items tab: type filter
		document.querySelectorAll('.sai-items-type-tab').forEach(btn => {
			btn.addEventListener('click', () => {
				state.itemsType = btn.dataset.itemsType;
				state.expandedItems.clear();
				mount();
			});
		});

		// Expand code preview in Table
		document.querySelectorAll('.sai-expand-code-btn').forEach(btn => {
			btn.addEventListener('click', async () => {
				const filename = btn.dataset.filename;
				const type = btn.dataset.type;

				if (state.expandedItems.has(filename)) {
					state.expandedItems.delete(filename);
					mount();
				} else {
					state.expandedItems.add(filename);
					btn.textContent = 'Loading…';
					btn.disabled = true;

					// Fetch and add actual code preview details to state items array
					const currentList = state.items[state.itemsType] || [];
					const itemObj = currentList.find(i => i.filename === filename);

					if (itemObj && !itemObj.code_content) {
						// Retrieve it using ajax file list or simple request
						// For theme-friendly rendering, file writer endpoint can serve it, or loader list has it.
						// We can read it directly from base_url + folder + filename
						const folder = types[state.itemsType]?.folder || state.itemsType;
						try {
							const res = await fetch(window.SifencyAI.base_url + folder + '/' + filename);
							if (res.ok) {
								itemObj.code_content = await res.text();
							} else {
								itemObj.code_content = '// Code loading failed.';
							}
						} catch (e) {
							itemObj.code_content = '// Code loading failed: ' + e.message;
						}
					}
					mount();
				}
			});
		});

		// Refresh
		const refreshBtn = document.getElementById('sai-refresh-btn');
		if (refreshBtn) refreshBtn.addEventListener('click', () => loadAllItems().then(mount));

		// Toggle
		document.querySelectorAll('.sai-toggle-input').forEach(cb => {
			cb.addEventListener('change', handleToggle);
		});

		// Delete
		document.querySelectorAll('.sai-delete-btn').forEach(btn => {
			btn.addEventListener('click', handleDelete);
		});

		// "Generate one now" shortcut from empty state
		document.querySelectorAll('.sai-goto-generate').forEach(btn => {
			btn.addEventListener('click', () => {
				state.tab = 'generate';
				state.genType = btn.dataset.genType || 'widget';
				mount();
			});
		});

		// Provider radio
		document.querySelectorAll('input[name="sai_provider"]').forEach(radio => {
			radio.addEventListener('change', () => {
				state.settings.provider = radio.value;
				state.settings.model = ''; // Reset model to show appropriate placeholder
				mount();
			});
		});

		// Toggle API key visibility
		const toggleKeyBtn = document.getElementById('sai-toggle-key');
		if (toggleKeyBtn) {
			toggleKeyBtn.addEventListener('click', () => {
				const input = document.getElementById('sai-api-key');
				if (!input) return;
				input.type = input.type === 'password' ? 'text' : 'password';
				toggleKeyBtn.textContent = input.type === 'password' ? '👁' : '🙈';
			});
		}

		// Save settings with premium spinner and inline feedback
		const saveBtn = document.getElementById('sai-save-settings-btn');
		if (saveBtn) saveBtn.addEventListener('click', handleSaveSettings);
	}

	/* ------------------------------------------------------------------ */
	/*  Handlers                                                            */
	/* ------------------------------------------------------------------ */

	async function handleGenerate() {
		if (state.loading) return;
		const ta = document.getElementById('sai-prompt');
		const prompt = (ta?.value || state.prompt || '').trim();

		if (!prompt) {
			toast('Please enter a prompt before generating.', 'error');
			if (ta) ta.focus();
			return;
		}

		if (!state.settings.has_key) {
			toast('Please set up your API key in the Settings tab first.', 'error');
			state.tab = 'settings';
			mount();
			return;
		}

		const typeDefs = types || {};
		const typeConf = typeDefs[state.genType];
		if (!typeConf) return;

		state.loading = true;
		state.result = null;
		state.prompt = prompt;
		mount();
		startProgress();

		const res = await ajax(typeConf.ajax_action, { prompt });

		stopProgress(res.success);
		state.loading = false;

		if (res.success) {
			state.result = {
				type: 'success',
				message: `"${res.data.slug}" generated and saved! ${typeConf.label} is ready to use.`,
				code_preview: res.data.code_preview || '',
				raw_code: res.data.code_preview || '', // will copy directly if raw code not sent
			};
			// Try to retrieve raw code so user can copy the whole file directly
			try {
				const folder = typeConf.folder;
				const rawRes = await fetch(window.SifencyAI.base_url + folder + '/' + res.data.filename);
				if (rawRes.ok) {
					state.result.raw_code = await rawRes.text();
				}
			} catch (e) { }

			// Update counts
			if (state.counts[state.genType]) {
				state.counts[state.genType].total++;
				state.counts[state.genType].enabled++;
			}
			toast(`${typeConf.label} generated successfully!`, 'success');
		} else {
			state.result = {
				type: 'error',
				message: res.data?.message || 'Generation failed. Please try again.',
			};
			toast(res.data?.message || 'Generation failed.', 'error');
		}

		mount();
	}

	async function handleToggle(e) {
		const cb = e.target;
		const filename = cb.dataset.filename;
		const type = cb.dataset.type;
		const enabled = cb.checked;

		const res = await ajax('sifency_ai_toggle_item', { filename, item_type: type, enabled });
		if (res.success) {
			toast(enabled ? 'Item enabled successfully.' : 'Item disabled successfully.', 'success', 2000);
		} else {
			cb.checked = !enabled; // revert on failure
			toast(res.data?.message || 'Could not update status.', 'error');
		}
	}

	async function handleDelete(e) {
		const btn = e.currentTarget;
		const filename = btn.dataset.filename;
		const type = btn.dataset.type;

		if (!confirm(`Delete "${filename}"? This cannot be undone.`)) return;

		btn.disabled = true;
		const res = await ajax('sifency_ai_delete_item', { filename, item_type: type });
		if (res.success) {
			toast(`"${filename}" deleted permanently.`, 'success', 3000);
			if (state.counts[state.itemsType]) {
				state.counts[state.itemsType].total--;
				state.counts[state.itemsType].enabled--;
			}
			state.expandedItems.delete(filename);
			await loadAllItems();
			mount();
		} else {
			btn.disabled = false;
			toast(res.data?.message || 'Delete failed.', 'error');
		}
	}

	async function handleSaveSettings() {
		const saveBtn = document.getElementById('sai-save-settings-btn');
		if (!saveBtn || saveBtn.disabled) return;

		const provider = document.querySelector('input[name="sai_provider"]:checked')?.value || 'openai';
		const model = document.getElementById('sai-model')?.value || '';
		const api_key = document.getElementById('sai-api-key')?.value || '';

		saveBtn.innerHTML = '<span class="sai-spinner"></span> Saving…';
		saveBtn.disabled = true;

		const res = await ajax('sifency_ai_save_settings', { provider, model, api_key });

		if (res.success) {
			// Re-fetch masked key from server
			const settingsRes = await ajax('sifency_ai_get_settings', {});
			if (settingsRes.success) {
				state.settings = settingsRes.data;
			} else {
				state.settings.provider = provider;
				state.settings.model = model;
				if (api_key && !api_key.includes('•')) state.settings.has_key = true;
			}

			// Show checkmark inline feedback
			saveBtn.innerHTML = 'Saved ✓';
			saveBtn.style.background = 'var(--sai-success)';
			toast('Settings verified and saved successfully!', 'success');

			setTimeout(() => {
				saveBtn.innerHTML = 'Save Settings';
				saveBtn.style.background = '';
				saveBtn.disabled = false;
				mount();
			}, 2000);
		} else {
			saveBtn.innerHTML = 'Save Settings';
			saveBtn.disabled = false;
			toast(res.data?.message || 'Save failed. Please check key/model.', 'error', 10000);
		}
	}

	/* ------------------------------------------------------------------ */
	/*  Data loading                                                        */
	/* ------------------------------------------------------------------ */

	async function loadAllItems() {
		const res = await ajax('sifency_ai_list_items', { item_type: 'all' });
		if (res.success) {
			state.items = res.data || {};
		}
	}

	/* ------------------------------------------------------------------ */
	/*  Utils                                                               */
	/* ------------------------------------------------------------------ */

	function escHtml(str) {
		return String(str ?? '')
			.replace(/&/g, '&amp;')
			.replace(/</g, '&lt;')
			.replace(/>/g, '&gt;')
			.replace(/"/g, '&quot;')
			.replace(/'/g, '&#039;');
	}

	function escAttr(str) { return escHtml(str); }

	function formatBytes(bytes) {
		if (!bytes) return '—';
		if (bytes < 1024) return bytes + ' B';
		return (bytes / 1024).toFixed(1) + ' KB';
	}

	/* ------------------------------------------------------------------ */
	/*  Init                                                                */
	/* ------------------------------------------------------------------ */

	if (state.tab === 'items') {
		loadAllItems().then(mount);
	} else {
		mount();
	}

})();
