// suno.js — Suno 任务页面逻辑
(function() {
const form = document.getElementById('suno-form');
if (!form) return;
const BATCH_URL = form.dataset.batchCreateUrl;
const PERSONAS_URL = form.dataset.personasUrl;
const PROMPTS_URL = form.dataset.promptsUrl;
const INDEX_URL = form.dataset.indexUrl;
const DISPATCH_MODE = form.dataset.dispatchMode;

const accountSel = document.getElementById('suno-account');
const personaSel = document.getElementById('suno-persona');
const promptSel = document.getElementById('suno-prompt-template');
const descTa = document.getElementById('suno-description');
const tagsInp = document.getElementById('suno-tags');
const cntInp = document.getElementById('suno-count');
const addBtn = document.getElementById('suno-add-queue');
const submitBtn = document.getElementById('suno-submit-queue');
const queueSec = document.getElementById('suno-queue-section');
const queueTbl = document.getElementById('suno-queue-table');
const queueSum = document.getElementById('suno-queue-summary');

const queue = [];

// Remember account
if (accountSel && accountSel.value !== 'cloud_pool') {
    const KEY = 'suno_last_account_id';
    (function restoreAccount() {
        const saved = localStorage.getItem(KEY);
        if (saved && accountSel.querySelector('option[value="' + saved + '"]')) {
            accountSel.value = saved;
            loadPersonas(saved);
        }
    })();

    accountSel.addEventListener('change', function() {
        if (this.value) {
            localStorage.setItem(KEY, this.value);
            loadPersonas(this.value);
        } else {
            personaSel.innerHTML = '<option value="">-- 请先选账号 --</option>';
        }
    });
} else if (accountSel && accountSel.value === 'cloud_pool') {
    loadPersonas('cloud_pool');
}

function loadPersonas(accountId) {
    personaSel.innerHTML = '<option value="">加载中...</option>';
    const url = accountId === 'cloud_pool' ? PERSONAS_URL : (PERSONAS_URL + '?account_id=' + accountId);
    fetch(url)
        .then(r => r.json())
        .then(list => {
            if (!list || !list.length) {
                personaSel.innerHTML = '<option value="">无 persona（请刷新或重跑 probe）</option>';
                return;
            }
            let html = accountId === 'cloud_pool' ? '' : '<option value="">-- 选择 persona --</option>';
            html += list.map(p => '<option value="' + p.uuid + '" data-name="' + (p.name || '') + '">' + (p.name || p.uuid) + '</option>').join('');
            personaSel.innerHTML = html;

            // Set default value based on preferred models (default 5.5 fenix, then crow, then bluejay, etc.)
            let defaultUuid = '';
            const prefOrder = ['chirp-fenix', 'chirp-crow', 'chirp-bluejay', 'chirp-auk', 'chirp-v4', 'chirp-v3-5', 'chirp-v3-0', 'chirp-v2-xxl-alpha'];
            for (const pref of prefOrder) {
                if (list.some(p => p.uuid === pref)) {
                    defaultUuid = pref;
                    break;
                }
            }
            if (!defaultUuid && list.length > 0) {
                defaultUuid = list[0].uuid;
            }
            if (defaultUuid) {
                personaSel.value = defaultUuid;
            }
        })
        .catch(() => {
            personaSel.innerHTML = '<option value="">加载失败</option>';
        });
}

// ── Prompt templates ─────────────────────────────────────────────────
const promptIndex = {};  // id -> {description, tags}

(function loadPrompts() {
    if (!PROMPTS_URL || !promptSel) return;
    fetch(PROMPTS_URL)
        .then(r => r.json())
        .then(data => {
            const cats = (data && data.categories) || [];
            if (!cats.length) {
                promptSel.innerHTML = '<option value="">（无模板）</option>';
                return;
            }
            let html = '<option value="">-- 不使用模板 --</option>';
            for (const cat of cats) {
                html += '<optgroup label="' + escAttr(cat.name) + '">';
                for (const it of (cat.items || [])) {
                    promptIndex[it.id] = {
                        description: it.description || [],
                        golden_quotes: it.golden_quotes || [],
                        tags: it.tags || '',
                        label: it.label || '',
                        genre_prefix: it.genre_prefix || ''
                    };
                    html += '<option value="' + escAttr(it.id) + '">' + escText(it.label || it.id) + '</option>';
                }
                html += '</optgroup>';
            }
            promptSel.innerHTML = html;
        })
        .catch(() => {
            promptSel.innerHTML = '<option value="">加载失败</option>';
        });
})();

function getCombinedPrompt(tplId, tpl) {
    let desc = tpl.description;
    if (!desc || desc.length === 0) return '';
    
    let scenario = '';
    if (Array.isArray(desc)) {
        let history = [];
        try {
            const histStr = localStorage.getItem('suno_used_scenarios');
            if (histStr) history = JSON.parse(histStr);
        } catch(e) {}
        
        let pool = desc.filter(s => !history.includes(s));
        if (pool.length === 0) {
            pool = desc;
        }
        scenario = pool[Math.floor(Math.random() * pool.length)];
        
        // Push to history and keep last 120 items
        history.push(scenario);
        if (history.length > 120) history.shift();
        localStorage.setItem('suno_used_scenarios', JSON.stringify(history));
    } else {
        scenario = desc;
    }
    
    let quote = '';
    const randomGoldenChk = document.getElementById('suno-random-golden');
    if (tpl.golden_quotes && tpl.golden_quotes.length > 0) {
        if (randomGoldenChk && randomGoldenChk.checked) {
            quote = tpl.golden_quotes[Math.floor(Math.random() * tpl.golden_quotes.length)];
        } else {
            quote = tpl.golden_quotes[0];
        }
    }
    
    let labelStr = tpl.label || '';
    let prefix = '';
    if (labelStr.startsWith('春日') || labelStr.startsWith('夏日') || labelStr.startsWith('秋日') || labelStr.startsWith('冬日')) {
        prefix = '写一首' + labelStr + '情歌，' + (tpl.genre_prefix || '');
    } else {
        prefix = '写一首' + labelStr + '主题的' + (tpl.genre_prefix || '');
    }
    
    let combined = prefix + scenario;
    if (quote) {
        combined += '，因为' + quote + '。';
    }
    return combined;
}

if (promptSel) {
    promptSel.addEventListener('change', function() {
        const tpl = promptIndex[this.value];
        if (!tpl) return;
        descTa.value = getCombinedPrompt(this.value, tpl);
        if (!tagsInp.value.trim()) tagsInp.value = tpl.tags;
    });
}

const randomBtn = document.getElementById('suno-random-prompt');
if (randomBtn) {
    randomBtn.addEventListener('click', function() {
        if (!promptSel) return;
        let tplId = promptSel.value;
        if (!tplId) {
            const keys = Object.keys(promptIndex);
            if (keys.length === 0) {
                alert('模板未加载或暂无可用模板');
                return;
            }
            tplId = keys[Math.floor(Math.random() * keys.length)];
            promptSel.value = tplId;
        }
        
        const tpl = promptIndex[tplId];
        if (!tpl) return;
        
        descTa.value = getCombinedPrompt(tplId, tpl);
        tagsInp.value = tpl.tags;
    });
}

function escAttr(s) { return String(s).replace(/&/g,'&amp;').replace(/"/g,'&quot;').replace(/</g,'&lt;'); }
function escText(s) { return String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;'); }

function renderQueue() {
    const tb = queueTbl.querySelector('tbody');
    tb.innerHTML = '';
    let total = 0;
    queue.forEach((it, idx) => {
        total += it.count;
        const tr = document.createElement('tr');
        tr.innerHTML = '<td>' + (idx + 1) + '</td>'
            + '<td style="max-width:340px;">' + escapeHtml(it.description) + '</td>'
            + '<td>' + escapeHtml(it.tags || '-') + '</td>'
            + '<td>' + it.count + '</td>'
            + '<td><button type="button" class="btn btn-sm btn-danger" data-rm="' + idx + '">删除</button></td>';
        tb.appendChild(tr);
    });
    queueSec.style.display = queue.length ? '' : 'none';
    queueSum.textContent = '共 ' + queue.length + ' 条，' + total + ' 首歌（每条会同步在 Suno 出 2 个版本，故实际 clip 数 = 2 × 总歌数）';
    submitBtn.disabled = !queue.length;
    submitBtn.textContent = queue.length ? '提交 ' + queue.length + ' 条 (共 ' + total + ' 首)' : '请先添加到队列';
    queueTbl.querySelectorAll('[data-rm]').forEach(b => {
        b.addEventListener('click', function() {
            queue.splice(parseInt(this.dataset.rm), 1);
            renderQueue();
        });
    });
}

function escapeHtml(s) {
    return String(s).replace(/[&<>"']/g, c => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
}

addBtn.addEventListener('click', function() {
    const desc = descTa.value.trim();
    if (!desc) { alert('请输入描述词'); return; }
    const cnt = parseInt(cntInp.value) || 1;
    if (cnt < 1 || cnt > 10) { alert('数量须 1-10'); return; }
    queue.push({
        description: desc,
        tags: tagsInp.value.trim(),
        count: cnt,
    });
    descTa.value = '';
    renderQueue();
});

submitBtn.addEventListener('click', async function() {
    const accountId = accountSel.value;
    const personaUuid = personaSel.value;
    const personaName = personaSel.selectedOptions[0]?.dataset.name || '';
    if (!accountId) { alert('请选择账号'); return; }
    if (!personaUuid) { alert('请选择 persona'); return; }
    if (!queue.length) return;

    submitBtn.disabled = true;
    submitBtn.textContent = '提交中...';

    // Cloud dispatch uses a string sentinel; local dispatch uses numeric account id.
    const accountPayload = (accountId === 'cloud_pool') ? 'cloud_pool' : parseInt(accountId);

    try {
        const csrf = document.querySelector('meta[name="csrf-token"]')?.content || '';
        const resp = await fetch(BATCH_URL, {
            method: 'POST',
            headers: {'Content-Type': 'application/json', 'X-CSRF-Token': csrf},
            body: JSON.stringify({
                account_id: accountPayload,
                persona_uuid: personaUuid,
                persona_name: personaName,
                items: queue.map(it => ({description: it.description, tags: it.tags, count: it.count})),
            }),
        });
        const result = await resp.json();
        if (result.ok) {
            window.location.href = INDEX_URL;
        } else {
            alert('提交失败：' + (result.error || '未知错误'));
            submitBtn.disabled = false;
            renderQueue();
        }
    } catch (e) {
        alert('网络错误：' + e.message);
        submitBtn.disabled = false;
        renderQueue();
    }
});
})();
