import { drizzle } from 'drizzle-orm/mysql2';
import { sql } from 'drizzle-orm';
import {createPool } from 'mysql2/promise';
import type { PoolOptions, Pool} from 'mysql2/promise';
import consola from "consola";
export default defineNitroPlugin(async nitroApp => {

    const {mysql: config} = useRuntimeConfig()
    consola.info('MySQL ...');
    // 配置数据库
    const poolOptions: PoolOptions = {
        host: config.host,
        port: config.port,
        user: config.user,
        password: config.password,
        database: config.database,
        // ssl: config.db.ssl,
        waitForConnections: true,
        connectionLimit: 10,
        queueLimit: 0,
        // 启用此选项后，MySQL驱动程序将支持大数字（big numbers），这对于存储和处理 bigint 类型的数据尤为重要。
        // 如果不启用此选项，MySQL驱动程序可能无法正确处理超过 JavaScript 数字精度范围的大数值，导致数据精度丢失。
        supportBigNumbers: true,

        // 启用此选项后，MySQL驱动程序将在接收 bigint 或其他大数值时，将其作为字符串返回，而不是作为JavaScript数字。
        // 这种处理方式可以避免JavaScript本身的数值精度限制问题，确保大数值在应用程序中保持精确。
        bigNumberStrings: true,

        // typeCast: function (field, next) {
        //     if (field.type === 'LONGLONG') { // 处理 BIGINT 类型
        //         return field.string(); // 强制转换为字符串
        //     }
        //     return next();
        // }
    }
    let pool: Pool;
    try{
        pool = await createPool(poolOptions)
    }catch (e) {
        consola.error('MySQL onnection Error: ', e);
        throw e;
    }
    // 暴露数据库
    const db = drizzle(pool,{
        logger: {
            logQuery: (query, params) => {
                console.log(`SQL: ${query} - Params: ${JSON.stringify(params,  (_, v) =>
                    typeof v === 'bigint' ? v.toString() : v)}`); // 打印日志，包括查询和参数
            }
        }
    });
    const result = await db.execute(sql`SHOW TABLES`);
    const tableList = result.map(row => Object.values(row)[0]);
    consola.info('TableList', tableList.length)
    // 将连接池添加到 Nitro 应用上下文
    nitroApp.hooks.hook('request', async (event) => {
        event.context.mysql = db
    })
    nitroApp.hooks.hook('error', async () => {
        pool.end();
    })
})
