/**
 * API Tester - 前端应用主逻辑
 * @author huazm
 */

// ==================== 粒子背景 ====================
class ParticleBackground {
    constructor(canvas) {
        this.canvas = canvas;
        this.ctx = canvas.getContext('2d');
        this.particles = [];
        this.particleCount = 80;
        this.resize();
        this.init();
        this.animate();
        window.addEventListener('resize', () => this.resize());
    }

    resize() {
        this.canvas.width = window.innerWidth;
        this.canvas.height = window.innerHeight;
    }

    init() {
        this.particles = [];
        for (let i = 0; i < this.particleCount; i++) {
            this.particles.push({
                x: Math.random() * this.canvas.width,
                y: Math.random() * this.canvas.height,
                vx: (Math.random() - 0.5) * 0.5,
                vy: (Math.random() - 0.5) * 0.5,
                size: Math.random() * 2 + 1,
                opacity: Math.random() * 0.5 + 0.2
            });
        }
    }

    animate() {
        this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);

        // 获取当前主题色
        const style = getComputedStyle(document.documentElement);
        const accentColor = style.getPropertyValue('--accent-primary').trim() || '#3b82f6';

        this.particles.forEach((p, i) => {
            // 更新位置
            p.x += p.vx;
            p.y += p.vy;

            // 边界检测
            if (p.x < 0 || p.x > this.canvas.width) p.vx *= -1;
            if (p.y < 0 || p.y > this.canvas.height) p.vy *= -1;

            // 绘制粒子
            this.ctx.beginPath();
            this.ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
            this.ctx.fillStyle = accentColor.replace(')', `, ${p.opacity})`).replace('rgb', 'rgba');
            this.ctx.fill();

            // 连接附近粒子
            for (let j = i + 1; j < this.particles.length; j++) {
                const p2 = this.particles[j];
                const dx = p.x - p2.x;
                const dy = p.y - p2.y;
                const dist = Math.sqrt(dx * dx + dy * dy);

                if (dist < 150) {
                    this.ctx.beginPath();
                    this.ctx.moveTo(p.x, p.y);
                    this.ctx.lineTo(p2.x, p2.y);
                    this.ctx.strokeStyle = accentColor.replace(')', `, ${0.1 * (1 - dist / 150)})`).replace('rgb', 'rgba');
                    this.ctx.stroke();
                }
            }
        });

        requestAnimationFrame(() => this.animate());
    }
}

// ==================== 主题管理 ====================
const themes = ['default', 'nebula', 'matrix', 'cyber', 'frost'];
let currentThemeIndex = 0;

function toggleTheme() {
    currentThemeIndex = (currentThemeIndex + 1) % themes.length;
    const theme = themes[currentThemeIndex];

    if (theme === 'default') {
        document.documentElement.removeAttribute('data-theme');
    } else {
        document.documentElement.setAttribute('data-theme', theme);
    }

    localStorage.setItem('api-tester-theme', theme);
}

function loadTheme() {
    const saved = localStorage.getItem('api-tester-theme');
    if (saved && themes.includes(saved)) {
        currentThemeIndex = themes.indexOf(saved);
        if (saved !== 'default') {
            document.documentElement.setAttribute('data-theme', saved);
        }
    }
}

// ==================== API 请求 ====================
async function sendRequest() {
    const sendBtn = document.getElementById('send-btn');
    const method = document.getElementById('method-select').value;
    const url = document.getElementById('url-input').value.trim();

    if (!url) {
        showToast('请输入 URL', 'error');
        return;
    }

    // 收集请求数据
    const headers = collectKeyValues('headers-editor');
    const params = collectKeyValues('params-editor');
    const bodyType = document.querySelector('input[name="bodyType"]:checked')?.value || 'none';
    const body = bodyType !== 'none' ? document.getElementById('body-editor').value : null;
    const authType = document.getElementById('auth-type').value;
    const authConfig = collectAuthConfig(authType);

    // 显示加载状态
    sendBtn.classList.add('loading');

    try {
        const response = await fetch('/api/request', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                method, url, headers, params, body,
                bodyType: bodyType !== 'none' ? bodyType : null,
                authType: authType !== 'none' ? authType : null,
                authConfig
            })
        });

        const result = await response.json();
        displayResponse(result);

    } catch (error) {
        displayResponse({ success: false, error: error.message });
    } finally {
        sendBtn.classList.remove('loading');
    }
}

// ==================== 辅助函数 ====================
function collectKeyValues(editorId) {
    const editor = document.getElementById(editorId);
    const rows = editor.querySelectorAll('.kv-row');
    const result = {};

    rows.forEach(row => {
        const key = row.querySelector('.kv-key')?.value.trim();
        const value = row.querySelector('.kv-value')?.value.trim();
        if (key) result[key] = value || '';
    });

    return Object.keys(result).length > 0 ? result : null;
}

function collectAuthConfig(authType) {
    if (authType === 'none') return null;

    const config = {};
    const container = document.getElementById('auth-config');
    const inputs = container.querySelectorAll('input');

    inputs.forEach(input => {
        if (input.dataset.key) {
            config[input.dataset.key] = input.value;
        }
    });

    return config;
}

function displayResponse(result) {
    const statusCode = document.getElementById('status-code');
    const statusText = document.getElementById('status-text');
    const responseTime = document.getElementById('response-time');
    const responseSize = document.getElementById('response-size');
    const responseBody = document.getElementById('response-body');
    const responseHeaders = document.getElementById('response-headers-view');

    if (result.success) {
        const code = result.statusCode;
        statusCode.textContent = code;
        statusCode.className = 'status-code ' + (code < 300 ? 'success' : code < 400 ? 'redirect' : 'error');
        statusText.textContent = getStatusText(code);
        responseTime.textContent = `${result.duration}ms`;
        responseSize.textContent = formatBytes(result.size || 0);

        // 格式化响应体
        let body = result.body;
        try {
            const parsed = JSON.parse(body);
            body = JSON.stringify(parsed, null, 2);
        } catch {}
        responseBody.querySelector('code').textContent = body;

        // 响应头
        if (result.headers) {
            responseHeaders.querySelector('code').textContent =
                JSON.stringify(result.headers, null, 2);
        }
    } else {
        statusCode.textContent = 'ERR';
        statusCode.className = 'status-code error';
        statusText.textContent = result.error || '请求失败';
        responseTime.textContent = result.duration ? `${result.duration}ms` : '--';
        responseSize.textContent = '--';
        responseBody.querySelector('code').textContent = result.error || '请求失败';
    }
}

function getStatusText(code) {
    const statusTexts = {
        200: 'OK', 201: 'Created', 204: 'No Content',
        301: 'Moved Permanently', 302: 'Found', 304: 'Not Modified',
        400: 'Bad Request', 401: 'Unauthorized', 403: 'Forbidden',
        404: 'Not Found', 405: 'Method Not Allowed', 500: 'Internal Server Error',
        502: 'Bad Gateway', 503: 'Service Unavailable'
    };
    return statusTexts[code] || 'Unknown';
}

function formatBytes(bytes) {
    if (bytes === 0) return '0 B';
    const k = 1024;
    const sizes = ['B', 'KB', 'MB', 'GB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}

function showToast(message, type = 'info') {
    const toast = document.createElement('div');
    toast.className = `toast toast-${type}`;
    toast.textContent = message;
    toast.style.cssText = `
        position: fixed;
        top: 20px;
        right: 20px;
        padding: 12px 24px;
        background: var(--bg-tertiary);
        border: 1px solid var(--${type === 'error' ? 'error' : 'accent-primary'});
        color: var(--text-primary);
        border-radius: 8px;
        z-index: 9999;
        animation: slideIn 0.3s ease;
    `;
    document.body.appendChild(toast);
    setTimeout(() => toast.remove(), 3000);
}

// ==================== 认证配置 UI ====================
function updateAuthUI(authType) {
    const container = document.getElementById('auth-config');
    container.innerHTML = '';

    const configs = {
        bearer: [{ key: 'token', label: 'Token', type: 'password' }],
        basic: [
            { key: 'username', label: '用户名', type: 'text' },
            { key: 'password', label: '密码', type: 'password' }
        ],
        apikey: [
            { key: 'key', label: 'Key Name', type: 'text' },
            { key: 'value', label: 'Key Value', type: 'password' },
            { key: 'location', label: '位置 (header/query)', type: 'text', default: 'header' }
        ]
    };

    const fields = configs[authType] || [];

    fields.forEach(field => {
        const group = document.createElement('div');
        group.className = 'auth-input-group';
        group.innerHTML = `
            <label>${field.label}</label>
            <input type="${field.type}" data-key="${field.key}"
                   value="${field.default || ''}" placeholder="${field.label}">
        `;
        container.appendChild(group);
    });
}

// ==================== Key-Value 编辑器 ====================
function addKVRow(editorId) {
    const editor = document.getElementById(editorId);
    const row = document.createElement('div');
    row.className = 'kv-row';
    row.innerHTML = `
        <input type="text" class="kv-key" placeholder="Key">
        <input type="text" class="kv-value" placeholder="Value">
        <button class="kv-remove">×</button>
    `;
    editor.appendChild(row);

    row.querySelector('.kv-remove').addEventListener('click', () => row.remove());
}

// ==================== 标签页切换 ====================
function setupTabs() {
    // 请求配置标签页
    document.querySelectorAll('.request-tabs .tab-btn').forEach(btn => {
        btn.addEventListener('click', () => {
            document.querySelectorAll('.request-tabs .tab-btn').forEach(b => b.classList.remove('active'));
            document.querySelectorAll('.request-content .tab-content').forEach(c => c.classList.remove('active'));

            btn.classList.add('active');
            document.getElementById(`${btn.dataset.tab}-content`).classList.add('active');
        });
    });

    // 响应标签页
    document.querySelectorAll('.response-tabs .tab-btn').forEach(btn => {
        btn.addEventListener('click', () => {
            document.querySelectorAll('.response-tabs .tab-btn').forEach(b => b.classList.remove('active'));
            btn.classList.add('active');

            const isBody = btn.dataset.tab === 'response-body';
            document.getElementById('response-body').classList.toggle('hidden', !isBody);
            document.getElementById('response-headers-view').classList.toggle('hidden', isBody);
        });
    });

    // 主导航标签页
    document.querySelectorAll('.header-nav .nav-btn').forEach(btn => {
        btn.addEventListener('click', () => {
            document.querySelectorAll('.header-nav .nav-btn').forEach(b => b.classList.remove('active'));
            btn.classList.add('active');

            // 切换面板显示
            const tab = btn.dataset.tab;
            document.getElementById('request-panel').classList.toggle('hidden', tab !== 'request');
            document.getElementById('response-panel').classList.toggle('hidden', tab !== 'request');
            document.getElementById('history-panel').classList.toggle('hidden', tab !== 'history');

            if (tab === 'history') loadHistory();
        });
    });
}


// ==================== 历史记录 ====================
async function loadHistory() {
    const list = document.getElementById('history-list');
    list.innerHTML = '<div style="text-align:center;color:var(--text-muted);">加载中...</div>';

    try {
        const response = await fetch('/api/history?size=50');
        const result = await response.json();

        if (result.success && result.data.length > 0) {
            list.innerHTML = result.data.map(item => `
                <div class="history-item" data-id="${item.id}" onclick="loadHistoryItem(${item.id})">
                    <span class="history-method ${item.method.toLowerCase()}">${item.method}</span>
                    <span class="history-url">${item.url}</span>
                    <span class="history-status">${item.statusCode || '--'}</span>
                    <span class="history-time">${new Date(item.createdAt).toLocaleString()}</span>
                </div>
            `).join('');
        } else {
            list.innerHTML = '<div style="text-align:center;color:var(--text-muted);">暂无历史记录</div>';
        }
    } catch (error) {
        list.innerHTML = '<div style="text-align:center;color:var(--error);">加载失败</div>';
    }
}

async function loadHistoryItem(id) {
    try {
        const response = await fetch(`/api/history?size=1000`);
        const result = await response.json();
        const item = result.data.find(h => h.id === id);

        if (item) {
            document.getElementById('method-select').value = item.method;
            document.getElementById('url-input').value = item.url;

            // 切换回请求面板
            document.querySelectorAll('.header-nav .nav-btn').forEach(b => b.classList.remove('active'));
            document.querySelector('.header-nav .nav-btn[data-tab="request"]').classList.add('active');
            document.getElementById('request-panel').classList.remove('hidden');
            document.getElementById('response-panel').classList.remove('hidden');
            document.getElementById('history-panel').classList.add('hidden');

            showToast('已加载历史记录', 'info');
        }
    } catch (error) {
        showToast('加载失败', 'error');
    }
}

// ==================== 语音输入 ====================
function setupVoiceInput() {
    const voiceBtn = document.getElementById('voice-input');

    if (!('webkitSpeechRecognition' in window) && !('SpeechRecognition' in window)) {
        voiceBtn.style.display = 'none';
        return;
    }

    const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
    const recognition = new SpeechRecognition();
    recognition.lang = 'zh-CN';
    recognition.continuous = false;

    let isRecording = false;

    voiceBtn.addEventListener('click', () => {
        if (isRecording) {
            recognition.stop();
            voiceBtn.classList.remove('recording');
            isRecording = false;
        } else {
            recognition.start();
            voiceBtn.classList.add('recording');
            isRecording = true;
        }
    });

    recognition.onresult = (event) => {
        const text = event.results[0][0].transcript;
        const urlInput = document.getElementById('url-input');
        urlInput.value = text;
        voiceBtn.classList.remove('recording');
        isRecording = false;
        showToast('语音识别成功', 'info');
    };

    recognition.onerror = () => {
        voiceBtn.classList.remove('recording');
        isRecording = false;
        showToast('语音识别失败', 'error');
    };
}

// ==================== JSON 格式化 ====================
function setupFormatButton() {
    document.getElementById('format-json-btn').addEventListener('click', () => {
        const editor = document.getElementById('body-editor');
        try {
            const parsed = JSON.parse(editor.value);
            editor.value = JSON.stringify(parsed, null, 2);
            showToast('格式化成功', 'info');
        } catch {
            showToast('JSON 格式错误', 'error');
        }
    });
}

// ==================== 预设按钮 ====================
function setupPresets() {
    document.querySelectorAll('.preset-btn').forEach(btn => {
        btn.addEventListener('click', () => {
            const key = btn.dataset.key;
            const value = btn.dataset.value;

            // 添加到 headers 编辑器
            const editor = document.getElementById('headers-editor');
            const rows = editor.querySelectorAll('.kv-row');

            // 检查是否已存在该 key
            let existingRow = null;
            for (const row of rows) {
                const keyInput = row.querySelector('.kv-key');
                if (keyInput.value === key) {
                    existingRow = row;
                    break;
                }
            }

            if (existingRow) {
                // 更新现有行
                const valueInput = existingRow.querySelector('.kv-value');
                valueInput.value = value;
                valueInput.focus();
                // 如果是鉴权类型，光标定位到值末尾方便输入 token
                if (btn.classList.contains('auth-preset')) {
                    valueInput.setSelectionRange(value.length, value.length);
                }
            } else {
                // 添加新行
                addKVRow('headers-editor');
                const newRow = editor.lastElementChild;
                newRow.querySelector('.kv-key').value = key;
                const valueInput = newRow.querySelector('.kv-value');
                valueInput.value = value;

                // 如果是鉴权或空值类型，自动聚焦到值输入框
                if (btn.classList.contains('auth-preset') || value === '') {
                    valueInput.focus();
                    valueInput.setSelectionRange(value.length, value.length);
                }
            }

            showToast(`已添加 ${key}`, 'info');
        });
    });
}

// ==================== 初始化 ====================
document.addEventListener('DOMContentLoaded', () => {
    // 初始化粒子背景
    new ParticleBackground(document.getElementById('particles-canvas'));

    // 加载主题
    loadTheme();

    // 设置事件监听
    document.getElementById('theme-toggle').addEventListener('click', toggleTheme);
    document.getElementById('send-btn').addEventListener('click', sendRequest);
    document.getElementById('auth-type').addEventListener('change', (e) => updateAuthUI(e.target.value));

    // 添加行按钮
    document.querySelectorAll('.add-row-btn').forEach(btn => {
        btn.addEventListener('click', () => addKVRow(btn.dataset.target));
    });

    // 删除行按钮
    document.querySelectorAll('.kv-remove').forEach(btn => {
        btn.addEventListener('click', () => btn.parentElement.remove());
    });

    // 清空历史
    document.getElementById('clear-history')?.addEventListener('click', async () => {
        if (confirm('确定要清空所有历史记录吗？')) {
            await fetch('/api/history/clear', { method: 'DELETE' });
            loadHistory();
        }
    });

    // 设置标签页
    setupTabs();
    setupVoiceInput();
    setupFormatButton();
    setupPresets();

    // 键盘快捷键
    document.addEventListener('keydown', (e) => {
        if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) {
            sendRequest();
        }
    });
});

