// cloud-presets.js
// 云端预设管理模块 (保持大尺寸 + 分页搜索)

// ═══════════════════════════════════════════════════════════════════════════
// 常量
// ═══════════════════════════════════════════════════════════════════════════

const CLOUD_PRESETS_API = 'https://draw.velure.top/';
const PLUGIN_KEY = 'xbaix';
const ITEMS_PER_PAGE = 8;

// ═══════════════════════════════════════════════════════════════════════════
// 状态
// ═══════════════════════════════════════════════════════════════════════════

let modalElement = null;
let allPresets = [];
let filteredPresets = [];
let currentPage = 1;
let onImportCallback = null;

// ═══════════════════════════════════════════════════════════════════════════
// API 调用
// ═══════════════════════════════════════════════════════════════════════════

export async function fetchCloudPresets() {
    const response = await fetch(CLOUD_PRESETS_API, {
        method: 'GET',
        headers: {
            'Accept': 'application/json',
            'X-Plugin-Key': PLUGIN_KEY,
            'Cache-Control': 'no-cache',
            'Pragma': 'no-cache'
        },
        cache: 'no-store'
    });
    
    if (!response.ok) throw new Error(`HTTP错误: ${response.status}`);
    const data = await response.json();
    return data.items || [];
}

export async function downloadPreset(url) {
    const response = await fetch(url);
    if (!response.ok) throw new Error(`下载失败: ${response.status}`);
    
    const data = await response.json();
    
    if (data.type !== 'novel-draw-preset' || !data.preset) {
        throw new Error('无效的预设文件格式');
    }
    
    return data;
}

// ═══════════════════════════════════════════════════════════════════════════
// 预设处理
// ═══════════════════════════════════════════════════════════════════════════

export function parsePresetData(data, generateId) {
    const DEFAULT_PARAMS = {
        model: 'nai-diffusion-4-5-full',
        sampler: 'k_euler_ancestral',
        scheduler: 'karras',
        steps: 28, scale: 6, width: 1216, height: 832, seed: -1,
        qualityToggle: true, autoSmea: false, ucPreset: 0, cfg_rescale: 0,
        variety_boost: false, sm: false, sm_dyn: false, decrisper: false,
    };
    
    return {
        id: generateId(),
        name: data.name || data.preset.name || '云端预设',
        positivePrefix: data.preset.positivePrefix || '',
        negativePrefix: data.preset.negativePrefix || '',
        params: { ...DEFAULT_PARAMS, ...(data.preset.params || {}) }
    };
}

export function exportPreset(preset) {
    const author = prompt("请输入你的作者名:", "") || "";
    const description = prompt("简介 (画风介绍):", "") || "";
    
    return {
        type: 'novel-draw-preset',
        version: 1,
        exportDate: new Date().toISOString(),
        name: preset.name,
        author: author,
        简介: description,
        preset: {
            positivePrefix: preset.positivePrefix,
            negativePrefix: preset.negativePrefix,
            params: { ...preset.params }
        }
    };
}

// ═══════════════════════════════════════════════════════════════════════════
// 样式 - 保持原始大尺寸
// ═══════════════════════════════════════════════════════════════════════════

function escapeHtml(str) {
    return String(str || '').replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
}

function ensureStyles() {
    if (document.getElementById('cloud-presets-styles')) return;
    
    const style = document.createElement('style');
    style.id = 'cloud-presets-styles';
    style.textContent = `
/* ═══════════════════════════════════════════════════════════════════════════
   云端预设弹窗 - 保持大尺寸，接近 iframe 的布局
   ═══════════════════════════════════════════════════════════════════════════ */

.cloud-presets-overlay {
    position: fixed !important;
    top: 0 !important;
    left: 0 !important;
    width: 100vw !important;
    height: 100vh !important;
    z-index: 100001 !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    background: rgba(0, 0, 0, 0.85) !important;
    touch-action: none;
    -webkit-overflow-scrolling: touch;
    animation: cloudFadeIn 0.2s ease;
}

@keyframes cloudFadeIn { 
    from { opacity: 0; } 
    to { opacity: 1; } 
}

/* ═══════════════════════════════════════════════════════════════════════════
   弹窗主体 - 桌面端 80% 高度，宽度增加以适应网格
   ═══════════════════════════════════════════════════════════════════════════ */
.cloud-presets-modal {
    background: #161b22;
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: 16px;
    
    /* 大尺寸 - 比原来更宽以适应网格 */
    width: calc(100vw - 48px);
    max-width: 800px;
    height: 80vh;
    
    display: flex;
    flex-direction: column;
    overflow: hidden;
    box-shadow: 0 20px 60px rgba(0,0,0,0.5);
}

/* ═══════════════════════════════════════════════════════════════════════════
   手机端 - 接近全屏（和 iframe 一样）
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 768px) {
    .cloud-presets-modal {
        width: 100vw;
        height: 100vh;
        max-width: none;
        border-radius: 0;
        border: none;
    }
}

/* ═══════════════════════════════════════════════════════════════════════════
   头部
   ═══════════════════════════════════════════════════════════════════════════ */
.cp-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 20px;
    border-bottom: 1px solid rgba(255,255,255,0.1);
    flex-shrink: 0;
    background: #0d1117;
}

.cp-title {
    font-size: 16px;
    font-weight: 600;
    color: #e6edf3;
    display: flex;
    align-items: center;
    gap: 10px;
}

.cp-title i { color: #d4a574; }

.cp-close {
    width: 40px; 
    height: 40px;
    min-width: 40px;
    border: none;
    background: rgba(255,255,255,0.1);
    color: #e6edf3;
    cursor: pointer;
    border-radius: 8px;
    font-size: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s;
    -webkit-tap-highlight-color: transparent;
}

.cp-close:hover,
.cp-close:active { 
    background: rgba(255,255,255,0.2); 
}

/* ═══════════════════════════════════════════════════════════════════════════
   搜索栏
   ═══════════════════════════════════════════════════════════════════════════ */
.cp-search {
    padding: 12px 20px;
    background: #161b22;
    border-bottom: 1px solid rgba(255,255,255,0.05);
    flex-shrink: 0;
}

.cp-search-input {
    width: 100%;
    background: #0d1117;
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: 10px;
    padding: 12px 16px;
    color: #e6edf3;
    font-size: 14px;
    outline: none;
    transition: border-color 0.15s;
}

.cp-search-input::placeholder { color: #484f58; }
.cp-search-input:focus { border-color: rgba(212,165,116,0.5); }

/* ═══════════════════════════════════════════════════════════════════════════
   内容区域 - 填满剩余空间
   ═══════════════════════════════════════════════════════════════════════════ */
.cp-body {
    flex: 1;
    overflow-y: auto;
    padding: 20px;
    -webkit-overflow-scrolling: touch;
    background: #0d1117;
}

/* ═══════════════════════════════════════════════════════════════════════════
   网格布局
   ═══════════════════════════════════════════════════════════════════════════ */
.cp-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 16px;
}

@media (max-width: 500px) {
    .cp-grid {
        grid-template-columns: 1fr;
        gap: 12px;
    }
}

/* ═══════════════════════════════════════════════════════════════════════════
   卡片样式
   ═══════════════════════════════════════════════════════════════════════════ */
.cp-card {
    background: #21262d;
    border: 1px solid rgba(255,255,255,0.08);
    border-radius: 12px;
    padding: 16px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    transition: all 0.2s;
}

.cp-card:hover {
    border-color: rgba(212,165,116,0.5);
    transform: translateY(-2px);
    box-shadow: 0 8px 24px rgba(0,0,0,0.3);
}

.cp-card-head {
    display: flex;
    align-items: center;
    gap: 12px;
}

.cp-icon {
    width: 44px;
    height: 44px;
    background: rgba(212,165,116,0.15);
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 20px;
    flex-shrink: 0;
}

.cp-meta {
    flex: 1;
    min-width: 0;
    overflow: hidden;
}

.cp-name {
    font-weight: 600;
    font-size: 14px;
    color: #e6edf3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin-bottom: 4px;
}

.cp-author {
    font-size: 12px;
    color: #8b949e;
    display: flex;
    align-items: center;
    gap: 5px;
}

.cp-author i { font-size: 10px; opacity: 0.7; }

.cp-desc {
    font-size: 12px;
    color: #6e7681;
    line-height: 1.5;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    min-height: 36px;
}

.cp-btn {
    width: 100%;
    padding: 10px 14px;
    margin-top: auto;
    border: 1px solid rgba(212,165,116,0.4);
    background: rgba(212,165,116,0.12);
    color: #d4a574;
    border-radius: 8px;
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    transition: all 0.15s;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    -webkit-tap-highlight-color: transparent;
}

.cp-btn:hover {
    background: #d4a574;
    color: #0d1117;
    border-color: #d4a574;
}

.cp-btn:active {
    transform: scale(0.98);
}

.cp-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.cp-btn.success {
    background: #238636;
    border-color: #238636;
    color: #fff;
}

.cp-btn.error {
    background: #da3633;
    border-color: #da3633;
    color: #fff;
}

/* ═══════════════════════════════════════════════════════════════════════════
   分页控件
   ═══════════════════════════════════════════════════════════════════════════ */
.cp-pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 16px;
    padding: 16px 20px;
    border-top: 1px solid rgba(255,255,255,0.1);
    background: #161b22;
    flex-shrink: 0;
}

.cp-page-btn {
    padding: 10px 18px;
    min-height: 40px;
    background: #21262d;
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: 8px;
    color: #e6edf3;
    cursor: pointer;
    font-size: 13px;
    transition: all 0.15s;
    display: flex;
    align-items: center;
    gap: 6px;
    -webkit-tap-highlight-color: transparent;
}

.cp-page-btn:hover:not(:disabled) {
    background: #30363d;
    border-color: rgba(255,255,255,0.2);
}

.cp-page-btn:disabled {
    opacity: 0.35;
    cursor: not-allowed;
}

.cp-page-info {
    font-size: 14px;
    color: #8b949e;
    min-width: 70px;
    text-align: center;
    font-variant-numeric: tabular-nums;
}

/* ═══════════════════════════════════════════════════════════════════════════
   状态提示
   ═══════════════════════════════════════════════════════════════════════════ */
.cp-loading, .cp-error, .cp-empty {
    text-align: center;
    padding: 60px 20px;
    color: #8b949e;
}

.cp-loading i {
    font-size: 36px;
    color: #d4a574;
    margin-bottom: 16px;
    display: block;
}

.cp-empty i {
    font-size: 48px;
    opacity: 0.4;
    margin-bottom: 16px;
    display: block;
}

.cp-empty p {
    font-size: 12px;
    margin-top: 8px;
    opacity: 0.6;
}

.cp-error {
    color: #f85149;
}

/* ═══════════════════════════════════════════════════════════════════════════
   触摸优化
   ═══════════════════════════════════════════════════════════════════════════ */
@media (hover: none) and (pointer: coarse) {
    .cp-close { width: 44px; height: 44px; }
    .cp-search-input { min-height: 48px; padding: 14px 16px; }
    .cp-btn { min-height: 48px; padding: 12px 16px; }
    .cp-page-btn { min-height: 44px; padding: 12px 20px; }
}
`;
    document.head.appendChild(style);
}

// ═══════════════════════════════════════════════════════════════════════════
// UI 逻辑
// ═══════════════════════════════════════════════════════════════════════════

function createModal() {
    ensureStyles();
    
    const overlay = document.createElement('div');
    overlay.className = 'cloud-presets-overlay';
    
    // Template-only UI markup.
    // eslint-disable-next-line no-unsanitized/property
    overlay.innerHTML = `
        <div class="cloud-presets-modal">
            <div class="cp-header">
                <div class="cp-title">
                    <i class="fa-solid fa-cloud-arrow-down"></i>
                    云端绘图预设
                </div>
                <button class="cp-close" type="button">✕</button>
            </div>
            
            <div class="cp-search">
                <input type="text" class="cp-search-input" placeholder="🔍 搜索预设名称、作者或简介...">
            </div>

            <div class="cp-body">
                <div class="cp-loading">
                    <i class="fa-solid fa-spinner fa-spin"></i>
                    <div>正在获取云端数据...</div>
                </div>
                <div class="cp-error" style="display:none"></div>
                <div class="cp-empty" style="display:none">
                    <i class="fa-solid fa-box-open"></i>
                    <div>没有找到相关预设</div>
                    <p>试试其他关键词？</p>
                </div>
                <div class="cp-grid" style="display:none"></div>
            </div>
            
            <div class="cp-pagination" style="display:none">
                <button class="cp-page-btn" id="cp-prev">
                    <i class="fa-solid fa-chevron-left"></i> 上一页
                </button>
                <span class="cp-page-info" id="cp-info">1 / 1</span>
                <button class="cp-page-btn" id="cp-next">
                    下一页 <i class="fa-solid fa-chevron-right"></i>
                </button>
            </div>
        </div>
    `;
    
    // 事件绑定
    overlay.querySelector('.cp-close').onclick = closeModal;
    overlay.onclick = (e) => { if (e.target === overlay) closeModal(); };
    overlay.querySelector('.cloud-presets-modal').onclick = (e) => e.stopPropagation();
    overlay.querySelector('.cp-search-input').oninput = (e) => handleSearch(e.target.value);
    overlay.querySelector('#cp-prev').onclick = () => changePage(-1);
    overlay.querySelector('#cp-next').onclick = () => changePage(1);
    
    return overlay;
}

function handleSearch(query) {
    const q = query.toLowerCase().trim();
    filteredPresets = allPresets.filter(p => 
        (p.name || '').toLowerCase().includes(q) || 
        (p.author || '').toLowerCase().includes(q) ||
        (p.简介 || p.description || '').toLowerCase().includes(q)
    );
    currentPage = 1;
    renderPage();
}

function changePage(delta) {
    const maxPage = Math.ceil(filteredPresets.length / ITEMS_PER_PAGE) || 1;
    const newPage = currentPage + delta;
    if (newPage >= 1 && newPage <= maxPage) {
        currentPage = newPage;
        renderPage();
    }
}

function renderPage() {
    const grid = modalElement.querySelector('.cp-grid');
    const pagination = modalElement.querySelector('.cp-pagination');
    const empty = modalElement.querySelector('.cp-empty');
    const loading = modalElement.querySelector('.cp-loading');
    
    loading.style.display = 'none';
    
    if (filteredPresets.length === 0) {
        grid.style.display = 'none';
        pagination.style.display = 'none';
        empty.style.display = 'block';
        return;
    }
    
    empty.style.display = 'none';
    grid.style.display = 'grid';
    
    const maxPage = Math.ceil(filteredPresets.length / ITEMS_PER_PAGE);
    pagination.style.display = maxPage > 1 ? 'flex' : 'none';
    
    const start = (currentPage - 1) * ITEMS_PER_PAGE;
    const pageItems = filteredPresets.slice(start, start + ITEMS_PER_PAGE);
    
    // Escaped fields are used in the template.
    // eslint-disable-next-line no-unsanitized/property
    grid.innerHTML = pageItems.map(p => `
        <div class="cp-card">
            <div class="cp-card-head">
                <div class="cp-icon">🎨</div>
                <div class="cp-meta">
                    <div class="cp-name" title="${escapeHtml(p.name)}">${escapeHtml(p.name || '未命名')}</div>
                    <div class="cp-author"><i class="fa-solid fa-user"></i> ${escapeHtml(p.author || '匿名')}</div>
                </div>
            </div>
            <div class="cp-desc">${escapeHtml(p.简介 || p.description || '暂无简介')}</div>
            <button class="cp-btn" type="button" data-url="${escapeHtml(p.url)}">
                <i class="fa-solid fa-download"></i> 导入预设
            </button>
        </div>
    `).join('');
    
    // 绑定导入按钮
    grid.querySelectorAll('.cp-btn').forEach(btn => {
        btn.onclick = async (e) => {
            e.stopPropagation();
            const url = btn.dataset.url;
            if (!url || btn.disabled) return;
            
            btn.disabled = true;
            const origHtml = btn.innerHTML;
            // Template-only UI markup.
            // eslint-disable-next-line no-unsanitized/property
            btn.innerHTML = '<i class="fa-solid fa-spinner fa-spin"></i> 导入中';
            
            try {
                const data = await downloadPreset(url);
                if (onImportCallback) await onImportCallback(data);
                btn.classList.add('success');
                // Template-only UI markup.
                // eslint-disable-next-line no-unsanitized/property
                btn.innerHTML = '<i class="fa-solid fa-check"></i> 成功';
                setTimeout(() => {
                    btn.classList.remove('success');
                    // Template-only UI markup.
                    // eslint-disable-next-line no-unsanitized/property
                    btn.innerHTML = origHtml;
                    btn.disabled = false;
                }, 2000);
            } catch (err) {
                console.error('[CloudPresets]', err);
                btn.classList.add('error');
                // Template-only UI markup.
                // eslint-disable-next-line no-unsanitized/property
                btn.innerHTML = '<i class="fa-solid fa-xmark"></i> 失败';
                setTimeout(() => {
                    btn.classList.remove('error');
                    // Template-only UI markup.
                    // eslint-disable-next-line no-unsanitized/property
                    btn.innerHTML = origHtml;
                    btn.disabled = false;
                }, 2000);
            }
        };
    });
    
    // 更新分页信息
    modalElement.querySelector('#cp-info').textContent = `${currentPage} / ${maxPage}`;
    modalElement.querySelector('#cp-prev').disabled = currentPage === 1;
    modalElement.querySelector('#cp-next').disabled = currentPage === maxPage;
}

// ═══════════════════════════════════════════════════════════════════════════
// 公开接口
// ═══════════════════════════════════════════════════════════════════════════

export async function openCloudPresetsModal(importCallback) {
    onImportCallback = importCallback;
    
    if (!modalElement) modalElement = createModal();
    document.body.appendChild(modalElement);
    
    // 重置状态
    currentPage = 1;
    modalElement.querySelector('.cp-loading').style.display = 'block';
    modalElement.querySelector('.cp-grid').style.display = 'none';
    modalElement.querySelector('.cp-pagination').style.display = 'none';
    modalElement.querySelector('.cp-empty').style.display = 'none';
    modalElement.querySelector('.cp-error').style.display = 'none';
    modalElement.querySelector('.cp-search-input').value = '';
    
    try {
        allPresets = await fetchCloudPresets();
        filteredPresets = [...allPresets];
        renderPage();
    } catch (e) {
        console.error('[CloudPresets]', e);
        modalElement.querySelector('.cp-loading').style.display = 'none';
        const errEl = modalElement.querySelector('.cp-error');
        errEl.style.display = 'block';
        errEl.textContent = '加载失败: ' + e.message;
    }
}

export function closeModal() {
    modalElement?.remove();
}

export function downloadPresetAsFile(preset) {
    const data = exportPreset(preset);
    const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `${preset.name || 'preset'}.json`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
}

export function destroyCloudPresets() {
    closeModal();
    modalElement = null;
    allPresets = [];
    filteredPresets = [];
    document.getElementById('cloud-presets-styles')?.remove();
}
