/**
 * Bun Web服务器脚本
 * 提供静态文件服务和API接口
 */

const fs = require('fs');
const path = require('path');

const BASE_DIR = path.resolve(process.env.BASE_DIR || process.cwd());
const WEB_DIR = path.join(BASE_DIR, 'web');
const DATA_DIR = path.join(BASE_DIR, 'data');
const PIC_DIR = path.join(BASE_DIR, 'pic');
const PUBLIC_DIR = path.join(BASE_DIR, 'public');

const PORT = Number(process.env.PORT || 8080);
const HOST = process.env.HOST || '127.0.0.1';

const CORS_HEADERS = {
    'Access-Control-Allow-Origin': '*',
    'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
    'Access-Control-Allow-Headers': 'Content-Type'
};

function json(data, status = 200) {
    return Response.json(data, {
        status,
        headers: CORS_HEADERS
    });
}

function text(body, status = 200) {
    return new Response(body, {
        status,
        headers: CORS_HEADERS
    });
}

function resolveSafePath(baseDir, requestPath) {
    const relativePath = requestPath.replace(/^\/+/, '');
    const resolvedPath = path.resolve(baseDir, relativePath);

    if (resolvedPath === baseDir || resolvedPath.startsWith(`${baseDir}${path.sep}`)) {
        return resolvedPath;
    }

    return null;
}

function listAvailableDates() {
    try {
        const files = fs.readdirSync(DATA_DIR);
        return files
            .filter((file) => file.endsWith('.json') && !file.includes('_raw') && !file.includes('test'))
            .map((file) => file.replace('.json', ''))
            .sort()
            .reverse();
    } catch {
        return [];
    }
}

async function serveFile(filePath) {
    const file = Bun.file(filePath);

    if (!(await file.exists())) {
        return text('Not Found', 404);
    }

    return new Response(file, {
        status: 200,
        headers: CORS_HEADERS
    });
}

const server = Bun.serve({
    hostname: HOST,
    port: PORT,
    async fetch(req) {
        if (req.method === 'OPTIONS') {
            return new Response(null, {
                status: 204,
                headers: CORS_HEADERS
            });
        }

        try {
            const { pathname } = new URL(req.url);

            if (pathname === '/api/dates') {
                return json({ dates: listAvailableDates() });
            }

            if (pathname.startsWith('/api/data/')) {
                const date = pathname.replace('/api/data/', '');
                const filePath = resolveSafePath(DATA_DIR, `${date}.json`);

                if (!filePath) {
                    return json({ error: '非法路径' }, 403);
                }

                const file = Bun.file(filePath);
                if (!(await file.exists())) {
                    return json({ error: '数据不存在' }, 404);
                }

                return new Response(file, {
                    status: 200,
                    headers: {
                        ...CORS_HEADERS,
                        'Content-Type': 'application/json; charset=utf-8'
                    }
                });
            }

            let filePath;
            if (pathname === '/') {
                filePath = path.join(WEB_DIR, 'index.html');
            } else if (pathname.startsWith('/data/')) {
                filePath = resolveSafePath(DATA_DIR, pathname.slice('/data/'.length));
            } else if (pathname.startsWith('/pic/')) {
                filePath = resolveSafePath(PIC_DIR, pathname.slice('/pic/'.length));
            } else if (pathname.startsWith('/public/')) {
                filePath = resolveSafePath(PUBLIC_DIR, pathname.slice('/public/'.length));
            } else {
                filePath = resolveSafePath(WEB_DIR, pathname);
            }

            if (!filePath) {
                return text('Forbidden', 403);
            }

            return serveFile(filePath);
        } catch (error) {
            console.error('服务器错误:', error);
            return text('Internal Server Error', 500);
        }
    }
});

console.log('==========================================');
console.log('北京市房地产数据监控服务器已启动');
console.log(`访问地址: http://${HOST}:${PORT}`);
console.log('按 Ctrl+C 停止服务器');
console.log('==========================================');

function shutdown(signal) {
    console.log(`\n${signal}\n正在关闭服务器...`);
    server.stop(true);
    console.log('服务器已关闭');
    process.exit(0);
}

process.on('SIGTERM', () => shutdown('SIGTERM'));
process.on('SIGINT', () => shutdown('SIGINT'));
