/* ── TheNicheQuiz.com – Frontend Logic ─────────────────────────────────── */

let adCount = 1;
let previewAdIndex = 0;
let lastCSVData = null;
let lastExportCSVData = null;

// Quiz state
let quizState = {
    step: 1,
    industry: '',
    subNiche: '',
    microNiche: ''
};

// Parallel campaigns state
let parallelCampaigns = [];
let galleryMode = false;

// ── Save Campaign Set ───────────────────────────────────────────────────────

async function saveCampaignSet() {
    if (parallelCampaigns.length === 0) {
        showToast('No campaigns to save', 'error');
        return;
    }

    const name = quizState.microNiche || quizState.subNiche || quizState.industry || 'Untitled Campaign';

    try {
        const res = await fetch('/api/save-campaign', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                name: name + ' — ' + new Date().toLocaleDateString(),
                industry: quizState.industry,
                sub_niche: quizState.subNiche,
                micro_niche: quizState.microNiche,
                campaign_data: { campaigns: parallelCampaigns }
            })
        });
        const data = await res.json();
        if (data.error) throw new Error(data.error);
        showToast('Campaigns saved! View them in My Campaigns.', 'success');
    } catch (e) {
        showToast('Failed to save: ' + e.message, 'error');
    }
}

// ── Particle Background ─────────────────────────────────────────────────────

(function initParticles() {
    const canvas = document.getElementById('particleCanvas');
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    let particles = [];
    const PARTICLE_COUNT = 60;

    function resize() {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
    }
    resize();
    window.addEventListener('resize', resize);

    class Particle {
        constructor() { this.reset(); }
        reset() {
            this.x = Math.random() * canvas.width;
            this.y = Math.random() * canvas.height;
            this.vx = (Math.random() - 0.5) * 0.3;
            this.vy = (Math.random() - 0.5) * 0.3;
            this.radius = Math.random() * 1.5 + 0.5;
            this.alpha = Math.random() * 0.5 + 0.1;
            const colors = ['245, 158, 11', '59, 130, 246', '168, 85, 247'];
            this.color = colors[Math.floor(Math.random() * colors.length)];
        }
        update() {
            this.x += this.vx;
            this.y += this.vy;
            if (this.x < 0 || this.x > canvas.width) this.vx *= -1;
            if (this.y < 0 || this.y > canvas.height) this.vy *= -1;
        }
        draw() {
            ctx.beginPath();
            ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
            ctx.fillStyle = `rgba(${this.color}, ${this.alpha})`;
            ctx.fill();
        }
    }

    for (let i = 0; i < PARTICLE_COUNT; i++) particles.push(new Particle());

    function drawConnections() {
        for (let i = 0; i < particles.length; i++) {
            for (let j = i + 1; j < particles.length; j++) {
                const dx = particles[i].x - particles[j].x;
                const dy = particles[i].y - particles[j].y;
                const dist = Math.sqrt(dx * dx + dy * dy);
                if (dist < 150) {
                    ctx.beginPath();
                    ctx.moveTo(particles[i].x, particles[i].y);
                    ctx.lineTo(particles[j].x, particles[j].y);
                    ctx.strokeStyle = `rgba(255, 255, 255, ${0.03 * (1 - dist / 150)})`;
                    ctx.lineWidth = 0.5;
                    ctx.stroke();
                }
            }
        }
    }

    function animate() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        particles.forEach(p => { p.update(); p.draw(); });
        drawConnections();
        requestAnimationFrame(animate);
    }
    animate();
})();

// ═══════════════════════════════════════════════════════════════════════════
// NICHE QUIZ
// ═══════════════════════════════════════════════════════════════════════════

function updateStepIndicator() {
    const fill = document.getElementById('stepLineFill');
    for (let i = 1; i <= 3; i++) {
        const dot = document.getElementById(`stepDot${i}`);
        dot.classList.remove('active', 'completed');
        if (i < quizState.step) dot.classList.add('completed');
        else if (i === quizState.step) dot.classList.add('active');
    }
    fill.style.width = ((quizState.step - 1) / 2 * 100) + '%';
}

function goToStep(step) {
    quizState.step = step;
    document.getElementById('quizStep1').classList.add('hidden');
    document.getElementById('quizStep2').classList.add('hidden');
    document.getElementById('quizStep3').classList.add('hidden');
    document.getElementById('quizComplete').classList.add('hidden');
    document.getElementById(`quizStep${step}`).classList.remove('hidden');
    updateStepIndicator();
}

function selectIndustry(btn) {
    document.querySelectorAll('.industry-card').forEach(c => c.classList.remove('selected'));
    btn.classList.add('selected');
    document.getElementById('customIndustryRow').classList.add('hidden');

    const industry = btn.dataset.industry;
    quizState.industry = industry;

    setTimeout(() => {
        goToStep(2);
        loadSubNiches(industry);
    }, 300);
}

function selectIndustryOther(btn) {
    document.querySelectorAll('.industry-card').forEach(c => c.classList.remove('selected'));
    btn.classList.add('selected');
    document.getElementById('customIndustryRow').classList.remove('hidden');
    document.getElementById('customIndustryInput').focus();
}

function confirmCustomIndustry() {
    const val = document.getElementById('customIndustryInput').value.trim();
    if (!val) { showToast('Please enter your industry', 'error'); return; }
    quizState.industry = val;
    goToStep(2);
    loadSubNiches(val);
}

async function loadSubNiches(industry) {
    const grid = document.getElementById('subNicheGrid');
    const loading = document.getElementById('nicheLoading2');
    document.getElementById('selectedIndustryLabel').textContent = industry;

    grid.innerHTML = '';
    loading.classList.remove('hidden');
    setStatus('Finding sub-niches...', 'loading');

    try {
        const res = await fetch('/api/suggest-niches', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ industry })
        });
        const data = await res.json();
        loading.classList.add('hidden');
        setStatus('Ready', 'ready');

        if (data.error) { showToast(data.error, 'error'); return; }

        data.niches.forEach(niche => {
            const card = document.createElement('button');
            card.className = 'niche-card';
            card.textContent = niche;
            card.onclick = () => selectSubNiche(niche, card);
            grid.appendChild(card);
        });
    } catch (e) {
        loading.classList.add('hidden');
        setStatus('Ready', 'ready');
        showToast('Failed to load sub-niches', 'error');
    }
}

function selectSubNiche(niche, card) {
    document.querySelectorAll('#subNicheGrid .niche-card').forEach(c => c.classList.remove('selected'));
    if (card) card.classList.add('selected');
    quizState.subNiche = niche;

    setTimeout(() => {
        goToStep(3);
        loadMicroNiches(quizState.industry, niche);
    }, 300);
}

function confirmCustomSubNiche() {
    const val = document.getElementById('customSubNicheInput').value.trim();
    if (!val) { showToast('Please enter your sub-niche', 'error'); return; }
    selectSubNiche(val, null);
}

async function loadMicroNiches(industry, subNiche) {
    const grid = document.getElementById('microNicheGrid');
    const loading = document.getElementById('nicheLoading3');
    document.getElementById('breadcrumb1').textContent = industry;
    document.getElementById('breadcrumb2').textContent = subNiche;

    grid.innerHTML = '';
    loading.classList.remove('hidden');
    setStatus('Finding micro-niches...', 'loading');

    try {
        const res = await fetch('/api/suggest-niches', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ industry, sub_niche: subNiche })
        });
        const data = await res.json();
        loading.classList.add('hidden');
        setStatus('Ready', 'ready');

        if (data.error) { showToast(data.error, 'error'); return; }

        data.niches.forEach(niche => {
            const card = document.createElement('button');
            card.className = 'niche-card';
            card.textContent = niche;
            card.onclick = () => selectMicroNiche(niche, card);
            grid.appendChild(card);
        });
    } catch (e) {
        loading.classList.add('hidden');
        setStatus('Ready', 'ready');
        showToast('Failed to load micro-niches', 'error');
    }
}

function selectMicroNiche(niche, card) {
    document.querySelectorAll('#microNicheGrid .niche-card').forEach(c => c.classList.remove('selected'));
    if (card) card.classList.add('selected');
    quizState.microNiche = niche;

    setTimeout(() => showQuizComplete(), 300);
}

function confirmCustomMicroNiche() {
    const val = document.getElementById('customMicroNicheInput').value.trim();
    if (!val) { showToast('Please enter your micro-niche', 'error'); return; }
    quizState.microNiche = val;
    showQuizComplete();
}

function showQuizComplete() {
    quizState.step = 4;
    document.getElementById('quizStep1').classList.add('hidden');
    document.getElementById('quizStep2').classList.add('hidden');
    document.getElementById('quizStep3').classList.add('hidden');
    document.getElementById('quizComplete').classList.remove('hidden');

    document.getElementById('finalIndustry').textContent = quizState.industry;
    document.getElementById('finalSubNiche').textContent = quizState.subNiche;
    document.getElementById('finalMicroNiche').textContent = quizState.microNiche;

    // Update step indicator to all completed
    for (let i = 1; i <= 3; i++) {
        document.getElementById(`stepDot${i}`).classList.remove('active');
        document.getElementById(`stepDot${i}`).classList.add('completed');
    }
    document.getElementById('stepLineFill').style.width = '100%';

    showToast('Niche locked in!', 'success');
}

function skipToManual() {
    document.getElementById('quizSection').classList.add('hidden');
    document.getElementById('manualBuilder').classList.remove('hidden');

    // Pre-fill with quiz data if available
    const nameInput = document.querySelector('#campaignSection [data-field="campaign_name"]');
    const adsetInput = document.querySelector('#adsetSection [data-field="adset_name"]');
    const bodyInput = document.querySelector('.ad-card [data-field="body"]');
    const titleInput = document.querySelector('.ad-card [data-field="title"]');

    if (quizState.microNiche) {
        if (nameInput) nameInput.value = quizState.microNiche + ' Campaign';
        if (adsetInput) adsetInput.value = quizState.microNiche + ' - Core Audience';
        if (titleInput) titleInput.value = quizState.microNiche;
        updatePreview();
    }
}

// ═══════════════════════════════════════════════════════════════════════════
// PARALLEL CAMPAIGNS
// ═══════════════════════════════════════════════════════════════════════════

async function generateParallelCampaigns() {
    document.getElementById('quizSection').classList.add('hidden');
    document.getElementById('campaignsSection').classList.remove('hidden');
    document.getElementById('generationLoading').classList.remove('hidden');
    document.getElementById('campaignCardsGrid').innerHTML = '';
    document.getElementById('campaignsNicheLabel').textContent = quizState.microNiche;

    setStatus('Generating campaigns...', 'loading');

    try {
        const res = await fetch('/api/generate-parallel-campaigns', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                industry: quizState.industry,
                sub_niche: quizState.subNiche,
                micro_niche: quizState.microNiche
            })
        });
        const data = await res.json();
        document.getElementById('generationLoading').classList.add('hidden');

        if (data.error) {
            showToast('Campaign generation failed: ' + data.error, 'error');
            setStatus('Ready', 'ready');
            return;
        }

        parallelCampaigns = data.campaigns;
        renderCampaignCards();
        setStatus('Ready', 'ready');
        showToast(`Generated ${parallelCampaigns.length} campaigns!`, 'success');

    } catch (e) {
        document.getElementById('generationLoading').classList.add('hidden');
        setStatus('Ready', 'ready');
        showToast('Failed to generate campaigns', 'error');
    }
}

const CTA_MAP = {
    'LEARN_MORE': 'Learn More', 'SHOP_NOW': 'Shop Now', 'SIGN_UP': 'Sign Up',
    'DOWNLOAD': 'Download', 'GET_QUOTE': 'Get Quote', 'CONTACT_US': 'Contact Us',
    'BOOK_NOW': 'Book Now', 'APPLY_NOW': 'Apply Now', 'NO_BUTTON': ''
};

function renderCampaignCards() {
    const grid = document.getElementById('campaignCardsGrid');
    grid.innerHTML = '';

    parallelCampaigns.forEach((c, i) => {
        const card = document.createElement('div');
        card.className = `campaign-card ${c.selected ? '' : 'deselected'}`;
        card.id = `campaignCard${i}`;

        const targeting = c.targeting || {};
        const adCopy = c.ad_copy || {};
        const hasImage = !!c.image_url;

        card.innerHTML = `
            <div class="campaign-card-header">
                <div>
                    <span class="campaign-card-number">#${i + 1}</span>
                    <span class="campaign-card-title">${escapeHtml(c.campaign_name || '')}</span>
                </div>
                <button class="campaign-toggle ${c.selected ? 'active' : ''}" onclick="toggleCampaign(${i})" title="Toggle campaign"></button>
            </div>
            <div class="campaign-card-body">
                <div class="campaign-micro-niche">${escapeHtml(c.micro_niche || '')}</div>
                <div class="campaign-image-area" id="campaignImage${i}">
                    ${hasImage
                        ? `<img src="${c.image_url}" alt="Ad image">`
                        : `<div class="campaign-image-placeholder">
                            <svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"/></svg>
                            <span>No image yet</span>
                           </div>`
                    }
                </div>
                <div class="campaign-ad-copy">${escapeHtml(adCopy.body || '')}</div>
                <div class="campaign-targeting">
                    <strong>🎯 Targeting:</strong> Ages ${targeting.age_min || '?'}-${targeting.age_max || '?'} · ${targeting.gender || 'All'}<br>
                    <strong>Interests:</strong> ${escapeHtml(targeting.interests || 'N/A')}<br>
                    <strong>Behaviors:</strong> ${escapeHtml(targeting.behaviors || 'N/A')}
                </div>
                <div class="campaign-landing">📄 ${escapeHtml(c.landing_page_angle || '')}</div>
                <div class="campaign-card-actions">
                    <button class="btn-generate" onclick="generateCampaignImage(${i})" ${hasImage ? 'style="opacity:0.6"' : ''}>
                        <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/></svg>
                        ${hasImage ? 'Regenerate' : 'Generate'} Image
                    </button>
                </div>
            </div>
        `;
        grid.appendChild(card);
    });
}

function toggleCampaign(index) {
    parallelCampaigns[index].selected = !parallelCampaigns[index].selected;
    const card = document.getElementById(`campaignCard${index}`);
    const toggle = card.querySelector('.campaign-toggle');

    if (parallelCampaigns[index].selected) {
        card.classList.remove('deselected');
        toggle.classList.add('active');
    } else {
        card.classList.add('deselected');
        toggle.classList.remove('active');
    }

    // Also update gallery view if visible
    const galleryCard = document.getElementById(`galleryCard${index}`);
    if (galleryCard) {
        if (parallelCampaigns[index].selected) {
            galleryCard.classList.remove('deselected');
        } else {
            galleryCard.classList.add('deselected');
        }
    }
}

async function generateCampaignImage(index) {
    const campaign = parallelCampaigns[index];
    const imageArea = document.getElementById(`campaignImage${index}`);
    const card = document.getElementById(`campaignCard${index}`);
    const btn = card.querySelector('.btn-generate');

    if (!campaign.image_prompt) {
        showToast('No image prompt for this campaign', 'error');
        return;
    }

    btn.disabled = true;
    btn.classList.add('generating');
    imageArea.innerHTML = `<div class="campaign-image-placeholder"><div class="ai-spinner"></div><span>Generating...</span></div>`;
    setStatus(`Generating image ${index + 1}...`, 'loading');

    try {
        const res = await fetch('/api/generate-image', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ prompt: campaign.image_prompt })
        });
        const data = await res.json();

        if (data.error) throw new Error(data.error);

        campaign.image_url = data.url;
        imageArea.innerHTML = `<img src="${data.url}" alt="Ad image">`;

        // Update gallery view too
        const galleryImg = document.querySelector(`#galleryCard${index} .gallery-fb-image`);
        if (galleryImg) {
            galleryImg.innerHTML = `<img src="${data.url}" alt="Ad image">`;
        }

        setStatus('Ready', 'ready');
        showToast(`Image generated for campaign #${index + 1}`, 'success');

    } catch (e) {
        imageArea.innerHTML = `<div class="campaign-image-placeholder"><span style="color:var(--red)">Failed</span></div>`;
        setStatus('Ready', 'ready');
        showToast(`Image failed: ${e.message}`, 'error');
    }

    btn.disabled = false;
    btn.classList.remove('generating');
}

async function generateAllImages() {
    const selected = parallelCampaigns.map((c, i) => ({ campaign: c, index: i })).filter(x => x.campaign.selected);

    if (selected.length === 0) {
        showToast('No campaigns selected', 'error');
        return;
    }

    const progressBar = document.getElementById('imageProgress');
    const fill = document.getElementById('progressBarFill');
    const text = document.getElementById('progressText');
    const btn = document.getElementById('generateAllBtn');

    progressBar.classList.remove('hidden');
    btn.disabled = true;
    let completed = 0;

    text.textContent = `Generating images: 0/${selected.length}`;
    fill.style.width = '0%';

    for (const item of selected) {
        if (item.campaign.image_url) {
            completed++;
            text.textContent = `Generating images: ${completed}/${selected.length}`;
            fill.style.width = (completed / selected.length * 100) + '%';
            continue;
        }

        await generateCampaignImage(item.index);
        completed++;
        text.textContent = `Generating images: ${completed}/${selected.length}`;
        fill.style.width = (completed / selected.length * 100) + '%';
    }

    btn.disabled = false;
    text.textContent = `All ${completed} images generated!`;
    showToast('All images generated!', 'success');

    setTimeout(() => progressBar.classList.add('hidden'), 3000);
}

// ═══════════════════════════════════════════════════════════════════════════
// GALLERY VIEW
// ═══════════════════════════════════════════════════════════════════════════

function toggleGalleryView() {
    galleryMode = !galleryMode;
    const grid = document.getElementById('campaignCardsGrid');
    const gallery = document.getElementById('galleryView');
    const label = document.getElementById('galleryToggleLabel');

    if (galleryMode) {
        grid.classList.add('hidden');
        gallery.classList.remove('hidden');
        label.textContent = 'Card View';
        renderGallery();
    } else {
        grid.classList.remove('hidden');
        gallery.classList.add('hidden');
        label.textContent = 'Gallery View';
    }
}

function renderGallery() {
    const gallery = document.getElementById('galleryView');
    gallery.innerHTML = '';

    parallelCampaigns.forEach((c, i) => {
        const adCopy = c.ad_copy || {};
        const ctaText = CTA_MAP[c.cta] || 'Learn More';

        const card = document.createElement('div');
        card.className = `gallery-ad-card ${c.selected ? '' : 'deselected'}`;
        card.id = `galleryCard${i}`;

        card.innerHTML = `
            <div class="gallery-phone-frame">
                <div class="gallery-fb-post">
                    <div class="gallery-fb-header">
                        <div class="gallery-fb-avatar"></div>
                        <div>
                            <div class="gallery-fb-page">${escapeHtml(c.campaign_name || 'Campaign')}</div>
                            <div class="gallery-fb-sponsored">Sponsored · 🌐</div>
                        </div>
                    </div>
                    <div class="gallery-fb-body" contenteditable="true" data-campaign="${i}" data-field="body" onblur="updateCampaignField(${i}, 'body', this.textContent)">${escapeHtml(adCopy.body || '')}</div>
                    <div class="gallery-fb-image">
                        ${c.image_url
                            ? `<img src="${c.image_url}" alt="Ad">`
                            : `<div class="campaign-image-placeholder" style="height:100%;display:flex;align-items:center;justify-content:center"><span>No image</span></div>`
                        }
                    </div>
                    <div class="gallery-fb-link-bar">
                        <div>
                            <div class="gallery-fb-headline" contenteditable="true" onblur="updateCampaignField(${i}, 'headline', this.textContent)">${escapeHtml(adCopy.headline || '')}</div>
                            <div class="gallery-fb-description" contenteditable="true" onblur="updateCampaignField(${i}, 'description', this.textContent)">${escapeHtml(adCopy.description || '')}</div>
                        </div>
                        <button class="gallery-fb-cta">${ctaText}</button>
                    </div>
                </div>
            </div>
            <div class="gallery-card-controls">
                <span class="gallery-niche-label">${escapeHtml(c.micro_niche || '')}</span>
                <button class="campaign-toggle ${c.selected ? 'active' : ''}" onclick="toggleCampaign(${i})"></button>
            </div>
        `;
        gallery.appendChild(card);
    });
}

function updateCampaignField(index, field, value) {
    if (!parallelCampaigns[index].ad_copy) parallelCampaigns[index].ad_copy = {};
    parallelCampaigns[index].ad_copy[field] = value;
}

// ═══════════════════════════════════════════════════════════════════════════
// CSV EXPORT (for parallel campaigns)
// ═══════════════════════════════════════════════════════════════════════════

async function exportSelectedCampaigns() {
    // Check if we have parallel campaigns
    if (parallelCampaigns.length > 0) {
        exportParallelCampaignsCSV();
        return;
    }

    // Fallback: original manual flow
    generateCSV();
}

async function exportParallelCampaignsCSV() {
    const selected = parallelCampaigns.filter(c => c.selected);

    if (selected.length === 0) {
        showToast('No campaigns selected for export', 'error');
        return;
    }

    // Build CSV rows
    const ads = selected.map(c => {
        const targeting = c.targeting || {};
        const adCopy = c.ad_copy || {};
        return {
            campaign_name: c.campaign_name || '',
            campaign_objective: 'OUTCOME_LEADS',
            buying_type: 'AUCTION',
            campaign_status: 'PAUSED',
            campaign_budget_optimization: 'FALSE',
            adset_name: c.adset_name || '',
            adset_status: 'PAUSED',
            targeting_age_min: String(targeting.age_min || 18),
            targeting_age_max: String(targeting.age_max || 65),
            targeting_genders: targeting.gender || 'All',
            targeting_interests: targeting.interests || '',
            targeting_behaviors: targeting.behaviors || '',
            targeting_geo_locations: 'US',
            ad_name: (c.campaign_name || 'Ad') + ' - Creative 1',
            ad_status: 'PAUSED',
            body: adCopy.body || '',
            title: adCopy.headline || '',
            caption: adCopy.description || '',
            call_to_action: c.cta || 'LEARN_MORE',
            image_file: c.image_url || ''
        };
    });

    setStatus('Generating CSV...', 'loading');

    try {
        const res = await fetch('/api/generate-csv', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ ads })
        });
        const data = await res.json();

        if (data.error) throw new Error(data.error);

        lastExportCSVData = data;

        // Show CSV preview section
        const section = document.getElementById('csvPreviewSection');
        section.classList.remove('hidden');

        document.getElementById('csvExportRowCount').textContent = `${data.rows.length} campaign(s) · ${data.columns.length} columns`;

        // Build table
        const activeCols = data.columns.filter(col =>
            data.rows.some(row => row[col] && row[col].trim())
        );

        let html = '<table><thead><tr>';
        activeCols.forEach(col => { html += `<th>${escapeHtml(col)}</th>`; });
        html += '</tr></thead><tbody>';
        data.rows.forEach(row => {
            html += '<tr>';
            activeCols.forEach(col => {
                html += `<td title="${escapeHtml(row[col] || '')}">${escapeHtml(row[col] || '—')}</td>`;
            });
            html += '</tr>';
        });
        html += '</tbody></table>';
        document.getElementById('csvExportTableWrap').innerHTML = html;

        section.scrollIntoView({ behavior: 'smooth' });
        setStatus('Ready', 'ready');
        showToast(`CSV generated — ${data.rows.length} row(s)`, 'success');

    } catch (e) {
        setStatus('Ready', 'ready');
        showToast('CSV generation failed: ' + e.message, 'error');
    }
}

function downloadExportCSV() {
    if (!lastExportCSVData) return;
    const blob = new Blob([lastExportCSVData.csv_content], { type: 'text/csv' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = lastExportCSVData.filename;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
    showToast(`Downloaded ${lastExportCSVData.filename}`, 'success');
}

// ═══════════════════════════════════════════════════════════════════════════
// ORIGINAL MANUAL BUILDER FUNCTIONS
// ═══════════════════════════════════════════════════════════════════════════

function toggleSection(id) {
    const body = document.getElementById(`body-${id}`);
    const chevron = document.getElementById(`chevron-${id}`);
    if (body) body.classList.toggle('collapsed');
    if (chevron) chevron.classList.toggle('rotated');
}

function toggleSubSection(id) {
    const body = document.getElementById(`body-${id}`);
    const chevron = document.getElementById(`chevron-${id}`);
    if (body) body.classList.toggle('collapsed');
    if (chevron) chevron.classList.toggle('rotated');
}

function toggleCBO(value) {
    const group = document.getElementById('cboBudgetGroup');
    if (group) group.style.display = value === 'TRUE' ? '' : 'none';
}

function switchTab(tab) {
    document.querySelectorAll('.preview-tab').forEach(t => t.classList.remove('active'));
    document.querySelector(`[data-tab="${tab}"]`).classList.add('active');

    const previewPanel = document.getElementById('previewPanel');
    const csvPanel = document.getElementById('csvPanel');

    if (tab === 'preview') {
        previewPanel.classList.remove('hidden');
        csvPanel.classList.add('hidden');
    } else {
        previewPanel.classList.add('hidden');
        csvPanel.classList.remove('hidden');
    }
}

function updateCharCount(textarea) {
    const counter = textarea.parentElement.querySelector('.char-count');
    if (counter) {
        const len = textarea.value.length;
        const max = textarea.maxLength || 2200;
        counter.textContent = `${len.toLocaleString()} / ${max.toLocaleString()}`;
        counter.style.color = len > max * 0.9 ? '#ef4444' : '';
    }
}

function updatePreview() {
    const adCard = document.querySelectorAll('.ad-card')[previewAdIndex];
    if (!adCard) return;

    const body = getFieldValue(adCard, 'body') || 'Your ad text will appear here.';
    document.getElementById('previewBody').textContent = body;

    const title = getFieldValue(adCard, 'title') || 'Your Headline Here';
    document.getElementById('previewHeadline').textContent = title;

    const caption = getFieldValue(adCard, 'caption') || 'Your description text';
    document.getElementById('previewDescription').textContent = caption;

    const link = getFieldValue(adCard, 'link') || getFieldValue(adCard, 'display_link') || '';
    let displayDomain = 'example.com';
    if (link) { try { displayDomain = new URL(link).hostname; } catch { displayDomain = link.replace(/https?:\/\//, '').split('/')[0] || 'example.com'; } }
    document.getElementById('previewDisplayLink').textContent = getFieldValue(adCard, 'display_link') || displayDomain;

    const cta = getFieldValue(adCard, 'call_to_action') || 'LEARN_MORE';
    const ctaBtn = document.getElementById('previewCTA');
    const ctaText = CTA_MAP[cta] || 'Learn More';
    ctaBtn.textContent = ctaText;
    ctaBtn.style.display = ctaText ? '' : 'none';

    const campaignName = document.querySelector('[data-field="campaign_name"]');
    if (campaignName && campaignName.value) {
        document.getElementById('previewPageName').textContent = campaignName.value;
    }
}

function getFieldValue(container, fieldName) {
    const el = container.querySelector(`[data-field="${fieldName}"]`);
    return el ? el.value : '';
}

function addAd() {
    const container = document.getElementById('adsContainer');
    const index = adCount++;
    const num = document.querySelectorAll('.ad-card').length + 1;
    const section = document.createElement('section');
    section.className = 'form-card ad-card';
    section.dataset.adIndex = index;

    section.innerHTML = `
        <div class="card-header" onclick="toggleSection('ad-${index}')">
            <div class="flex items-center gap-2">
                <div class="section-icon ad-icon"><svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"/></svg></div>
                <h2 class="card-title">Ad Creative <span class="ad-number">#${num}</span></h2>
            </div>
            <div class="flex items-center gap-2">
                <button class="btn-delete-ad" onclick="event.stopPropagation(); removeAd(this);">✕ Remove</button>
                <svg class="chevron w-5 h-5 text-gray-400" id="chevron-ad-${index}" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/></svg>
            </div>
        </div>
        <div class="card-body" id="body-ad-${index}">
            <div class="field-grid">
                <div class="field-group col-span-2"><label class="field-label">Ad Name <span class="req">*</span></label><input type="text" class="field-input" data-field="ad_name" placeholder="e.g. Ad ${num}" oninput="updatePreview()"></div>
                <div class="field-group"><label class="field-label">Status</label><select class="field-input" data-field="ad_status"><option value="PAUSED">Paused</option><option value="ACTIVE">Active</option></select></div>
                <div class="field-group"><label class="field-label">Call to Action</label><select class="field-input" data-field="call_to_action" onchange="updatePreview()"><option value="">— None —</option><option value="LEARN_MORE">Learn More</option><option value="SHOP_NOW">Shop Now</option><option value="SIGN_UP">Sign Up</option><option value="DOWNLOAD">Download</option><option value="GET_QUOTE">Get Quote</option><option value="CONTACT_US">Contact Us</option><option value="BOOK_NOW">Book Now</option><option value="APPLY_NOW">Apply Now</option></select></div>
                <div class="field-group col-span-2"><label class="field-label">Body Text</label><textarea class="field-input field-textarea" data-field="body" placeholder="Primary text..." rows="3" maxlength="2200" oninput="updatePreview(); updateCharCount(this)"></textarea><span class="char-count">0 / 2,200</span></div>
                <div class="field-group"><label class="field-label">Headline</label><input type="text" class="field-input" data-field="title" placeholder="Headline" maxlength="255" oninput="updatePreview()"></div>
                <div class="field-group"><label class="field-label">Description</label><input type="text" class="field-input" data-field="caption" placeholder="Description" maxlength="255" oninput="updatePreview()"></div>
                <div class="field-group col-span-2"><label class="field-label">Link URL</label><input type="url" class="field-input" data-field="link" placeholder="https://..." oninput="updatePreview()"></div>
            </div>
            <div class="ai-gen-section">
                <div class="ai-gen-header"><span class="text-sm font-semibold text-amber-400">✨ AI Image Generation</span></div>
                <div class="ai-gen-body">
                    <div class="flex gap-2">
                        <input type="text" class="field-input flex-1 ai-prompt-input" data-ai-prompt placeholder="Describe the ad image...">
                        <button class="btn-generate" onclick="generateImage(this)"><svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/></svg>Generate</button>
                    </div>
                    <div class="generated-images" data-generated-images></div>
                </div>
            </div>
        </div>
    `;

    container.appendChild(section);
    section.scrollIntoView({ behavior: 'smooth', block: 'center' });
    showToast('Ad creative added', 'success');
}

function removeAd(btn) {
    const card = btn.closest('.ad-card');
    if (document.querySelectorAll('.ad-card').length <= 1) {
        showToast('You need at least one ad', 'error');
        return;
    }
    card.remove();
    document.querySelectorAll('.ad-card .ad-number').forEach((num, i) => num.textContent = `#${i + 1}`);
    previewAdIndex = Math.min(previewAdIndex, document.querySelectorAll('.ad-card').length - 1);
    updatePreview();
    showToast('Ad removed', 'info');
}

// ── AI Image Generation (Manual) ────────────────────────────────────────────

async function generateImage(btn) {
    const adCard = btn.closest('.ad-card') || btn.closest('.form-card');
    const promptInput = adCard.querySelector('[data-ai-prompt]');
    const container = adCard.querySelector('[data-generated-images]');
    const prompt = promptInput.value.trim();

    if (!prompt) { showToast('Please enter an image prompt', 'error'); promptInput.focus(); return; }

    btn.disabled = true;
    btn.classList.add('generating');
    const origText = btn.innerHTML;
    btn.innerHTML = `<svg class="w-4 h-4 animate-spin" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"/><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"/></svg> Generating...`;

    const placeholder = document.createElement('div');
    placeholder.className = 'generating-placeholder';
    placeholder.innerHTML = '<svg class="w-5 h-5 text-gray-500 animate-spin" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"/><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"/></svg>';
    container.appendChild(placeholder);

    setStatus('Generating image...', 'loading');

    try {
        const res = await fetch('/api/generate-image', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ prompt })
        });
        const data = await res.json();
        if (data.error) throw new Error(data.error);

        placeholder.remove();
        const thumb = document.createElement('div');
        thumb.className = 'generated-image-thumb';
        thumb.innerHTML = `<img src="${data.url}" alt="${prompt}" loading="lazy">`;
        thumb.onclick = () => selectImage(thumb, data.url, adCard);
        container.appendChild(thumb);

        if (container.querySelectorAll('.generated-image-thumb').length === 1) {
            selectImage(thumb, data.url, adCard);
        }

        setStatus('Ready', 'ready');
        showToast('Image generated successfully', 'success');
    } catch (err) {
        placeholder.remove();
        setStatus('Ready', 'ready');
        showToast(`Image generation failed: ${err.message}`, 'error');
    }

    btn.disabled = false;
    btn.classList.remove('generating');
    btn.innerHTML = origText;
}

function selectImage(thumb, url, adCard) {
    thumb.parentElement.querySelectorAll('.generated-image-thumb').forEach(t => t.classList.remove('selected'));
    thumb.classList.add('selected');
    document.getElementById('previewImage').innerHTML = `<img src="${url}" alt="Ad Image">`;
    const imageFileInput = adCard.querySelector('[data-field="image_file"]');
    if (imageFileInput) imageFileInput.value = url;
}

// ── CSV Generation (Manual) ─────────────────────────────────────────────────

async function generateCSV() {
    const ads = collectFormData();
    if (ads.length === 0) { showToast('No ad data to export', 'error'); return; }

    for (let i = 0; i < ads.length; i++) {
        if (!ads[i].campaign_name) { showToast('Campaign Name is required', 'error'); return; }
        if (!ads[i].adset_name) { showToast('Ad Set Name is required', 'error'); return; }
        if (!ads[i].ad_name) { showToast(`Ad #${i + 1}: Ad Name is required`, 'error'); return; }
    }

    setStatus('Generating CSV...', 'loading');

    try {
        const res = await fetch('/api/generate-csv', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ ads })
        });
        const data = await res.json();
        if (data.error) throw new Error(data.error);

        lastCSVData = data;
        renderCSVPreview(data);
        switchTab('csv');
        setStatus('Ready', 'ready');
        showToast(`CSV generated — ${data.rows.length} row(s)`, 'success');
    } catch (err) {
        setStatus('Ready', 'ready');
        showToast(`CSV generation failed: ${err.message}`, 'error');
    }
}

function collectFormData() {
    const ads = [];
    const adCards = document.querySelectorAll('.ad-card');
    const sharedData = {};
    const campaignSection = document.getElementById('campaignSection');
    const adsetSection = document.getElementById('adsetSection');

    if (campaignSection) campaignSection.querySelectorAll('[data-field]').forEach(el => { sharedData[el.dataset.field] = el.value; });
    if (adsetSection) adsetSection.querySelectorAll('[data-field]').forEach(el => { sharedData[el.dataset.field] = el.value; });

    adCards.forEach(card => {
        const adData = { ...sharedData };
        card.querySelectorAll('[data-field]').forEach(el => { adData[el.dataset.field] = el.value; });
        ads.push(adData);
    });
    return ads;
}

function renderCSVPreview(data) {
    document.getElementById('csvEmpty').classList.add('hidden');
    document.getElementById('csvContent').classList.remove('hidden');
    document.getElementById('csvRowCount').textContent = `${data.rows.length} row(s) · ${data.columns.length} columns`;

    const activeCols = data.columns.filter(col => data.rows.some(row => row[col] && row[col].trim()));
    let html = '<table><thead><tr>';
    activeCols.forEach(col => { html += `<th>${escapeHtml(col)}</th>`; });
    html += '</tr></thead><tbody>';
    data.rows.forEach(row => {
        html += '<tr>';
        activeCols.forEach(col => { html += `<td title="${escapeHtml(row[col] || '')}">${escapeHtml(row[col] || '—')}</td>`; });
        html += '</tr>';
    });
    html += '</tbody></table>';
    document.getElementById('csvTableWrap').innerHTML = html;
}

function downloadCSV() {
    if (!lastCSVData) return;
    const blob = new Blob([lastCSVData.csv_content], { type: 'text/csv' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url; a.download = lastCSVData.filename;
    document.body.appendChild(a); a.click(); document.body.removeChild(a);
    URL.revokeObjectURL(url);
    showToast(`Downloaded ${lastCSVData.filename}`, 'success');
}

// ── Status & Toast ──────────────────────────────────────────────────────────

function setStatus(text, type) {
    const badge = document.getElementById('statusBadge');
    if (!badge) return;
    badge.textContent = text;
    badge.className = 'status-badge';
    if (type === 'loading') badge.classList.add('loading');
    if (type === 'error') badge.classList.add('error');
}

function showToast(message, type = 'info') {
    const container = document.getElementById('toastContainer');
    const toast = document.createElement('div');
    toast.className = `toast ${type}`;
    const icons = { success: '✓', error: '✕', info: 'ℹ' };
    toast.innerHTML = `<span>${icons[type] || 'ℹ'}</span><span>${escapeHtml(message)}</span>`;
    container.appendChild(toast);
    setTimeout(() => {
        toast.style.animation = 'slideOut 0.3s ease forwards';
        setTimeout(() => toast.remove(), 300);
    }, 4000);
}

function escapeHtml(str) {
    if (!str) return '';
    const div = document.createElement('div');
    div.textContent = str;
    return div.innerHTML;
}

// ── CSS Animation Helper ────────────────────────────────────────────────────

const style = document.createElement('style');
style.textContent = `@keyframes spin { to { transform: rotate(360deg); } } .animate-spin { animation: spin 1s linear infinite; }`;
document.head.appendChild(style);

// ── Init ────────────────────────────────────────────────────────────────────

document.addEventListener('DOMContentLoaded', () => {
    updateStepIndicator();
});
