const express = require('express');
const db = require('../db/models');
const wrapAsync = require('../helpers').wrapAsync;
const router = express.Router();
const sjs = require('sequelize-json-schema');
const { getWidget, askGpt } = require('../services/openai');
const { LocalAIApi } = require('../ai/LocalAIApi');
const passport = require('passport');

const authMiddleware = passport.authenticate('jwt', { session: false });

const loadRolesModules = () => {
    try {
        return {
            RolesService: require('../services/roles'),
            RolesDBApi: require('../db/api/roles'),
        };
    } catch (error) {
        console.error('Roles modules are missing. Advanced roles are required for this endpoint.', error);
        const err = new Error('Roles modules are missing. Advanced roles are required for this endpoint.');
        err.originalError = error;
        throw err;
    }
};

router.delete(
    '/roles-info/:infoId',
    authMiddleware,
    wrapAsync(async (req, res) => {
        const { RolesService } = loadRolesModules();
        const role = await RolesService.removeRoleInfoById(
            req.query.infoId,
            req.query.roleId,
            req.query.key,
            req.currentUser,
        );

        res.status(200).send(role);
    }),
);

router.get(
    '/info-by-key',
    authMiddleware,
    wrapAsync(async (req, res) => {
        const { RolesService, RolesDBApi } = loadRolesModules();
        const roleId = req.query.roleId;
        const key = req.query.key;
        const currentUser = req.currentUser;
        let info = await RolesService.getRoleInfoByKey(
            key,
            roleId,
            currentUser,
        );
        const role = await RolesDBApi.findBy({ id: roleId });
        if (!role?.role_customization) {
            await Promise.all(["pie", "bar"].map(async (e) => {
                const schema = await sjs.getSequelizeSchema(db.sequelize, {});
                const payload = {
                    description: `Create some cool ${e} chart`,
                    modelDefinition: schema.definitions,
                };
                const widgetId = await getWidget(payload, currentUser?.id, roleId);
                if (widgetId) {
                    await RolesService.addRoleInfo(
                        roleId,
                        currentUser?.id,
                        'widgets',
                        widgetId,
                        req.currentUser,
                    );
                }
            }))
            info = await RolesService.getRoleInfoByKey(
                key,
                roleId,
                currentUser,
            );
        }
        res.status(200).send(info);
    }),
);

router.post(
    '/create_widget',
    authMiddleware,
    wrapAsync(async (req, res) => {
        const { RolesService } = loadRolesModules();
        const { description, userId, roleId } = req.body;

        const currentUser = req.currentUser;
        const schema = await sjs.getSequelizeSchema(db.sequelize, {});
        const payload = {
            description,
            modelDefinition: schema.definitions,
        };

        const widgetId = await getWidget(payload, userId, roleId);

        if (widgetId) {
            await RolesService.addRoleInfo(
                roleId,
                userId,
                'widgets',
                widgetId,
                currentUser,
            );

            return res.status(200).send(widgetId);
        } else {
            return res.status(400).send(widgetId);
        }
    }),
);

router.post(
    '/response',
    authMiddleware,
    wrapAsync(async (req, res) => {
        const body = req.body || {};
        const options = body.options || {};
        const payload = { ...body };
        delete payload.options;

        const response = await LocalAIApi.createResponse(payload, options);

        if (response.success) {
            return res.status(200).send(response);
        }

        console.error('AI proxy error:', response);
        const status = response.error === 'input_missing' ? 400 : 502;
        return res.status(status).send(response);
    }),
);

router.post(
    '/ask-gpt',
    wrapAsync(async (req, res) => {
        const { prompt } = req.body;
        if (!prompt) {
            return res.status(400).send({
                success: false,
                error: 'Prompt is required',
            });
        }

        const response = await askGpt(prompt);

        if (response.success) {
            return res.status(200).send(response);
        } else {
            return res.status(500).send(response);
        }
    }),
);


module.exports = router;