// app.js - 普通脚本（非模块）

const { createApp, ref, reactive, computed, onMounted } = Vue;

// ============================================================
// 1. 把 modules/*.js 的内容直接合并进来（因为是普通脚本，不能 import）
// ============================================================

// ---------- api ----------
const API_BASE = '/api';
function getToken() {
    return localStorage.getItem('frpc_token') || '';
}
function getHeaders() {
    return {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + getToken(),
    };
}
async function apiFetch(endpoint, options = {}) {
    const url = API_BASE + endpoint;
    const headers = options.body instanceof FormData
        ? { 'Authorization': 'Bearer ' + getToken() }
        : getHeaders();
    const res = await fetch(url, {
        ...options,
        headers: { ...headers, ...(options.headers || {}) },
    });
    return res.json();
}

// ---------- auth ----------
function parseJwtExpire(token) {
    try {
        const payload = JSON.parse(atob(token.split('.')[1]));
        return payload.exp * 1000;
    } catch {
        return Date.now() + 7 * 24 * 60 * 60 * 1000;
    }
}
function saveAuthState(token, username) {
    const expire = parseJwtExpire(token);
    localStorage.setItem('frpc_token', token);
    localStorage.setItem('frpc_token_expire', String(expire));
    localStorage.setItem('frpc_username', username);
    return expire;
}
function loadAuthState() {
    const token = localStorage.getItem('frpc_token');
    const expire = parseInt(localStorage.getItem('frpc_token_expire') || '0', 10);
    const username = localStorage.getItem('frpc_username') || '';
    if (token && expire > Date.now()) {
        return { token, expire, username, valid: true };
    }
    clearAuthState();
    return { token: '', expire: 0, username: '', valid: false };
}
function clearAuthState() {
    localStorage.removeItem('frpc_token');
    localStorage.removeItem('frpc_token_expire');
    localStorage.removeItem('frpc_username');
}
async function login(username, password) {
    const data = await apiFetch('/login', {
        method: 'POST',
        body: JSON.stringify({ username, password }),
    });
    if (data.code === 0) {
        const token = data.data.token;
        const expire = saveAuthState(token, username);
        return { success: true, token, expire };
    }
    return { success: false, error: data.msg || '登录失败' };
}

// ---------- config ----------
const defaultConfig = {
    serverAddr: 'frp.whitetop.xyz',
    serverPort: 9358,
    token: '',
    logLevel: 'info',
    logMaxDays: 3,
    tcpMux: true,
    tcpMuxKeepalive: 30,
    heartbeatInterval: 15,
    heartbeatTimeout: 70,
    poolCount: 8,
};
async function loadConfig() {
    try {
        const data = await apiFetch('/config');
        if (data.code === 0) {
            return { ...defaultConfig, ...data.data };
        }
    } catch (e) {
        console.warn('加载配置失败', e);
    }
    return { ...defaultConfig };
}
async function saveConfigApi(config) {
    const data = await apiFetch('/config', {
        method: 'PUT',
        body: JSON.stringify(config),
    });
    return data;
}

// ---------- proxies ----------
async function loadProxies() {
    try {
        const data = await apiFetch('/proxies');
        if (data.code === 0) {
            return data.data || [];
        }
    } catch (e) {
        console.warn('加载隧道失败', e);
    }
    return [];
}
async function createProxy(proxy) {
    const data = await apiFetch('/proxy', {
        method: 'POST',
        body: JSON.stringify(proxy),
    });
    return data;
}
async function updateProxy(proxy) {
    const data = await apiFetch('/proxy/' + proxy.id, {
        method: 'PUT',
        body: JSON.stringify(proxy),
    });
    return data;
}
async function deleteProxy(id) {
    const data = await apiFetch('/proxy/' + id, {
        method: 'DELETE',
    });
    return data;
}
function filterProxies(list, keyword) {
    if (!keyword) return list;
    const kw = keyword.toLowerCase();
    return list.filter(p =>
        p.name.toLowerCase().includes(kw) ||
        p.localIP.includes(kw) ||
        String(p.remotePort).includes(kw)
    );
}

// ---------- frpc ----------
async function getFrpcStatus() {
    try {
        const data = await apiFetch('/frpc/status');
        if (data.code === 0) {
            return data.data.running || false;
        }
    } catch (e) {
        console.warn('获取 frpc 状态失败', e);
    }
    return false;
}
async function reloadFrpc() {
    const data = await apiFetch('/frpc/reload', { method: 'POST' });
    return data;
}
async function startFrpc() {
    const data = await apiFetch('/frpc/start', { method: 'POST' });
    return data;
}
async function stopFrpc() {
    const data = await apiFetch('/frpc/stop', { method: 'POST' });
    return data;
}

// ---------- ui ----------
// Tab 切换
const activeTab = ref('proxies');
function switchTab(tab) {
    activeTab.value = tab;
}

// 弹窗控制
const dialogVisible = ref(false);
const dialogMode = ref('add');
const dialogForm = ref({
    id: null,
    name: '',
    type: 'tcp',
    localIP: '',
    localPort: 0,
    remotePort: 0,
});

function openAddDialog() {
    dialogMode.value = 'add';
    dialogForm.value = { id: null, name: '', type: 'tcp', localIP: '', localPort: 0, remotePort: 0 };
    dialogVisible.value = true;
}
function openEditDialog(proxy) {
    dialogMode.value = 'edit';
    dialogForm.value = { ...proxy };
    dialogVisible.value = true;
}
function closeDialog() {
    dialogVisible.value = false;
}

const searchKeyword = ref('');

// ---------- import/export 功能 ----------
async function triggerImport() {
    document.getElementById('tomlFileInput').click();
}
async function handleImport(e) {
    const file = e.target.files[0];
    if (!file) return;
    const formData = new FormData();
    formData.append('file', file);
    try {
        const res = await fetch('/api/import/toml', {
            method: 'POST',
            headers: { 'Authorization': 'Bearer ' + getToken() },
            body: formData,
        });
        const data = await res.json();
        if (data.code === 0) {
            alert(data.msg);
            await loadAllData();
        } else {
            alert('导入失败: ' + data.msg);
        }
    } catch (err) {
        alert('网络错误: ' + err.message);
    }
    e.target.value = '';
}
async function exportToml() {
    try {
        const configData = await apiFetch('/config');
        if (configData.code !== 0) {
            alert('获取配置失败');
            return;
        }
        const proxyData = await apiFetch('/proxies');
        if (proxyData.code !== 0) {
            alert('获取隧道列表失败');
            return;
        }
        const cfg = configData.data;
        const proxyList = proxyData.data || [];
        const tomlObj = {
            serverAddr: cfg.serverAddr,
            serverPort: cfg.serverPort,
            auth: { token: cfg.token },
            log: { to: './frpc.log', level: cfg.logLevel, maxDays: cfg.logMaxDays },
            transport: {
                tcpMux: cfg.tcpMux,
                tcpMuxKeepaliveInterval: cfg.tcpMuxKeepalive,
                heartbeatInterval: cfg.heartbeatInterval,
                heartbeatTimeout: cfg.heartbeatTimeout,
                poolCount: cfg.poolCount,
            },
            proxies: proxyList.map(p => ({
                name: p.name,
                type: p.type,
                localIP: p.localIP,
                localPort: p.localPort,
                remotePort: p.remotePort,
            })),
        };
        const tomlStr = TOML.stringify(tomlObj);
        const blob = new Blob([tomlStr], { type: 'text/plain' });
        const a = document.createElement('a');
        a.href = URL.createObjectURL(blob);
        a.download = 'frpc.toml';
        a.click();
        URL.revokeObjectURL(a.href);
    } catch (e) {
        alert('导出失败: ' + e.message);
    }
}

// ============================================================
// 2. Vue 应用
// ============================================================

const app = createApp({
    setup() {
        // ===== 登录态 =====
        const loggedIn = ref(false);
        const loading = ref(false);
        const loginError = ref('');
        const loginForm = reactive({ username: '', password: '' });
        const token = ref('');
        const tokenExpireTime = ref(0);
        const transitioning = ref(false);
        const contentVisible = ref(false);
        let expireTimer = null;

        // ===== 数据 =====
        const globalConfig = reactive({});
        const proxies = ref([]);
        const frpcRunning = ref(false);
        const showDetail = ref(false);

        // ===== 初始化 =====
        onMounted(() => {
            const saved = loadAuthState();
            if (saved.valid) {
                token.value = saved.token;
                tokenExpireTime.value = saved.expire;
                loginForm.username = saved.username;
                loggedIn.value = true;
                loadAllData().then(() => {
                    contentVisible.value = true;
                    startExpireTimer();
                });
            }
        });

        const startExpireTimer = () => {
            if (expireTimer) clearInterval(expireTimer);
            expireTimer = setInterval(() => {
                if (Date.now() >= tokenExpireTime.value) {
                    doLogout();
                    alert('登录已超时，请重新登录');
                }
            }, 5000);
        };

        const loadAllData = async () => {
            const [cfg, list, running] = await Promise.all([
                loadConfig(),
                loadProxies(),
                getFrpcStatus(),
            ]);
            Object.assign(globalConfig, cfg);
            proxies.value = list;
            frpcRunning.value = running;
        };

        // ===== 登录/退出 =====
        const doLogin = async () => {
            if (!loginForm.username || !loginForm.password) {
                loginError.value = '请输入用户名和密码';
                return;
            }
            loading.value = true;
            loginError.value = '';
            const result = await login(loginForm.username, loginForm.password);
            if (result.success) {
                token.value = result.token;
                tokenExpireTime.value = result.expire;
                transitioning.value = true;
                loggedIn.value = true;
                setTimeout(async () => {
                    transitioning.value = false;
                    await loadAllData();
                    loading.value = false;
                    setTimeout(() => {
                        contentVisible.value = true;
                        startExpireTimer();
                    }, 300);
                }, 500);
            } else {
                loginError.value = result.error;
                loading.value = false;
            }
        };

        const doLogout = () => {
            if (expireTimer) clearInterval(expireTimer);
            contentVisible.value = false;
            loggedIn.value = false;
            token.value = '';
            tokenExpireTime.value = 0;
            loginForm.username = '';
            loginForm.password = '';
            loading.value = false;
            transitioning.value = false;
            clearAuthState();
        };

        // ===== 保存配置 =====
        const saveConfig = async () => {
            const result = await saveConfigApi(globalConfig);
            if (result.code === 0) {
                frpcRunning.value = await getFrpcStatus();
                alert('配置已更新并热加载');
            } else {
                alert('保存失败: ' + result.msg);
            }
        };

        // ===== 隧道操作 =====
        const toggleProxy = async (p) => {
            const result = await updateProxy(p);
            if (result.code !== 0) {
                alert('更新失败: ' + result.msg);
                proxies.value = await loadProxies();
            } else {
                frpcRunning.value = await getFrpcStatus();
            }
        };

        const removeProxy = async (id) => {
            console.log('🔍 removeProxy 被调用, id:', id);  // ← 加这行
            if (!confirm('确定要删除这条隧道吗？')) return;
            const result = await deleteProxy(id);
            if (result.code === 0) {
                proxies.value = await loadProxies();
                frpcRunning.value = await getFrpcStatus();
            } else {
                alert('删除失败: ' + result.msg);
            }
        };

        const confirmDialog = async () => {
            const form = dialogForm.value;
            if (!form.name || !form.localIP || !form.localPort || !form.remotePort) {
                alert('请填写完整信息');
                return;
            }
            const result = dialogMode.value === 'add'
                ? await createProxy(form)
                : await updateProxy(form);
            if (result.code === 0) {
                closeDialog();
                proxies.value = await loadProxies();
                frpcRunning.value = await getFrpcStatus();
            } else {
                alert('操作失败: ' + result.msg);
            }
        };

        // ===== 计算属性 =====
        const filteredProxies = computed(() => filterProxies(proxies.value, searchKeyword.value));

        return {
            loggedIn,
            loading,
            loginError,
            loginForm,
            doLogin,
            doLogout,
            activeTab,
            switchTab,
            globalConfig,
            showDetail,
            saveConfig,
            proxies,
            filteredProxies,
            toggleProxy,
            removeProxy,
            frpcRunning,
            dialogVisible,
            dialogMode,
            dialogForm,
            openAddDialog,
            openEditDialog,
            closeDialog,
            confirmDialog,
            searchKeyword,
            transitioning,
            contentVisible,
            triggerImport,
            handleImport,
            exportToml,
        };
    },
});

app.mount('#app');