import { NextApiRequest, NextApiResponse } from 'next';
import { PrismaClient } from '@prisma/client';
import { getServerSession } from "next-auth/next";
import { authOptions } from "../../auth/[...nextauth]";
import e from 'express';


const common = require('../../../../src/helpers/common');
const logger = require('../../../../src/logger');

// Utility to parse query parameters into a Prisma query
const parseQueryParams = (query: any) => {
    return {
        select: query.select ? JSON.parse(query.select) : undefined,
        include: query.include ? JSON.parse(query.include) : undefined,
        where: query.where ? JSON.parse(query.where) : undefined,
        orderBy: query.orderBy ? JSON.parse(query.orderBy) : undefined,
        skip: query.skip ? parseInt(query.skip, 10) : undefined,
        limit: query.limit ? parseInt(query.limit, 10) : undefined,
        distinct: query.distinct ? query.distinct.split(',') : undefined,
    };
};


const serializeValue = (value) => {
    if (value === null || value === undefined) {
        return 'NULL';
    }
    if (typeof value === 'string') {
        // Escape single quotes and backslashes for MySQL
        return `'${value.replace(/\\/g, "\\\\").replace(/'/g, "''")}'`;
    }
    if (typeof value === 'boolean') {
        // MySQL uses 1 and 0 for TRUE and FALSE
        return value ? '1' : '0';
    }
    if (typeof value === 'number') {
        return value;
    }
    if (value instanceof Date) {
        // Format date objects to MySQL date strings
        return `'${value.toISOString().slice(0, 19).replace('T', ' ')}'`;
    }
    if (Array.isArray(value) || typeof value === 'object') {
        // Convert arrays and objects to JSON strings and escape them
        return `'${JSON.stringify(value).replace(/\\/g, "\\\\").replace(/'/g, "''")}'`;
    }
    return value;
};

// Function to generate SQL INSERT statements for MySQL from data
const generateSQL = (data, tableName) => {
    return data.map(item => {
        const columns = Object.keys(item).join(", ");
        const values = Object.values(item).map(serializeValue).join(", ");
        return `INSERT INTO ${tableName} (${columns}) VALUES (${values});`;
    }).join("\n");
};
export default async function handler(req: NextApiRequest, res: NextApiResponse) {

    const session = await getServerSession(req, res, authOptions);

    if (!session) {
        return res.status(401).json({ error: "Unauthorized" });
    }


    const prisma: PrismaClient = common.getPrismaClient();
    const modelArray = (req.query.model || (req.body && req.body.model)) as string[];
    let queryOptions = {};

    if (req.method === 'POST' && req.headers['content-type']?.includes('application/json')) {
        // Handle POST request
        queryOptions = req.body;
    } else if (req.method === 'GET') {
        // Handle GET request
        queryOptions = parseQueryParams(req.query);
    }
    else if (req.method === 'DELETE') {
        // Handle DELETE request
        queryOptions = req.body;

    }

    try {
        if (!modelArray || modelArray.length === 0) {
            throw new Error('Model is required as a part of the URL path.');
        }
        const modelName = modelArray[0]; // Get the first part of the model array
        if (!prisma[modelName]) {
            throw new Error(`Model ${modelName} not found in Prisma client.`);
        }

        if (req.method === 'POST') {
            // Create a new record
            const result = await prisma[modelName].create({ data: queryOptions });
            res.status(201).json(result);
            return;
        } else if (req.method === 'DELETE') {
            // Delete a record
            const result = await prisma[modelName].delete({ where: queryOptions });
            res.status(200).json(result);
            return;
        }
        // Fetch records

        const result = await prisma[modelName].findMany(queryOptions);
        if (req.query.format === 'sql') {
            // Generate SQL if requested via query parameter
            const sql = generateSQL(result, modelName);
            res.setHeader('Content-Type', 'application/sql');
            res.send(sql);
        } else {
            // Normal JSON response
            res.status(200).json(result);
        }
    } catch (error) {
        console.error(error);
        res.status(500).json({ error: error.message });
    }
}
