import type { HttpContext } from '@adonisjs/core/http';
import MimeType from '#models/mime_type';
import vine, { SimpleMessagesProvider } from '@vinejs/vine';

export default class MimetypeController {
    public async index({ auth, inertia }: HttpContext) {
        const direction = 'asc'; // or 'desc'
        const mimetypes = await MimeType.query().orderBy('name', direction).exec();

        return inertia.render('Admin/Mimetype/Index', {
            mimetypes: mimetypes,
            can: {
                create: await auth.user?.can(['settings']),
                edit: await auth.user?.can(['settings']),
            },
        });
    }

    public async create({ inertia }: HttpContext) {
        // const permissions = await Permission.query().select('id', 'name').pluck('name', 'id');
        return inertia.render('Admin/Mimetype/Create', {});
    }

    public async store({ request, response, session }: HttpContext) {
        const newDatasetSchema = vine.object({
            name: vine.string().trim().isUnique({ table: 'mime_types', column: 'name' }),
            file_extension: vine.array(vine.string()).minLength(1), // define at least one extension for the new mimetype
            alternate_mimetype: vine.array(vine.string().isValidMimetype()).distinct().optional(), // define alias mimetypes
            enabled: vine.boolean(),
        });
        // await request.validate({ schema: newDatasetSchema, messages: this.messages });
        try {
            //  Step 2 - Validate request body against  the schema
            // await request.validate({ schema: newDatasetSchema, messages: this.messages });
            const validator = vine.compile(newDatasetSchema);
            validator.messagesProvider = new SimpleMessagesProvider(this.messages);          
            await request.validateUsing(validator, { messagesProvider: new SimpleMessagesProvider(this.messages) });
        } catch (error) {
            // Step 3 - Handle errors
            // return response.badRequest(error.messages);
            throw error;
        }
        const input = request.only(['name', 'enabled', 'file_extension', 'alternate_mimetype']);
        // Concatenate the file_extensions array into a string with '|' as the separator
        if (Array.isArray(input.file_extension)) {
            input.file_extension = input.file_extension.join('|');
        }
        // Concatenate the alias_mimetype array into a string with '|' as the separator
        if (Array.isArray(input.alternate_mimetype)) {
            input.alternate_mimetype = input.alternate_mimetype.join('|');
        }
        await MimeType.create(input);
        // if (request.input('roles')) {
        //     const roles: Array<number> = request.input('roles');
        //     await user.related('roles').attach(roles);
        // }

        session.flash('message', 'MimeType has been created successfully');
        return response.redirect().toRoute('settings.mimetype.index');
    }

    public messages = {
        'minLength': '{{ field }} must be at least {{ min }} characters long',
        'maxLength': '{{ field }} must be less then {{ max }} characters long',
        'isUnique': '{{ field }} must be unique, and this value is already taken',
        'required': '{{ field }} is required',
        'file_extension.minLength': 'at least {{ min }} mimetypes must be defined',
        'file_extension.*.string': 'Each file extension must be a valid string', // Adjusted to match the type
    };

    public async edit({ request, inertia }: HttpContext) {
        const id = request.param('id');
        const mimetype = await MimeType.query().where('id', id).firstOrFail();

        // const permissions = await Permission.query().pluck('name', 'id');
        // // const userHasRoles = user.roles;
        // const rolerHasPermissions = await role.related('permissions').query().orderBy('name').pluck('id');

        return inertia.render('Admin/Mimetype/Edit', {
            mimetype: mimetype,
        });
    }

    // public async update({ request, response, session }: HttpContext) {
    //     // node ace make:validator UpdateUser
    //     const id = request.param('id');
    //     const role = await Role.query().where('id', id).firstOrFail();

    //     // validate update form
    //     // await request.validate(UpdateRoleValidator);
    //     await request.validateUsing(updateRoleValidator, {
    //         meta: {
    //             roleId: role.id,
    //         },
    //     });

    //     // password is optional

    //     const input = request.only(['name', 'description']);
    //     await role.merge(input).save();
    //     // await user.save();

    //     if (request.input('permissions')) {
    //         const permissions: Array<number> = request.input('permissions');
    //         await role.related('permissions').sync(permissions);
    //     }

    //     session.flash('message', 'Role has been updated successfully');
    //     return response.redirect().toRoute('settings.role.index');
    // }

    public async down({ request, response }: HttpContext) {
        const id = request.param('id');
        const mimetype = (await MimeType.findOrFail(id)) as MimeType;
        mimetype.enabled = false;
        await mimetype.save();

        // session.flash({ message: 'person has been deactivated!' });
        return response.flash('mimetype  has been deactivated!', 'message').toRoute('settings.mimetype.index');
    }

    public async up({ request, response }: HttpContext) {
        const id = request.param('id');
        const mimetype = await MimeType.findOrFail(id);
        mimetype.enabled = true;
        await mimetype.save();

        // session.flash({ message: 'person has been activated!' });
        return response.flash('mimetype  has been activated!', 'message').toRoute('settings.mimetype.index');
    }

    // public async edit({ request, inertia }: HttpContext) {
    //     const id = request.param('id');
    //     const license = await License.query().where('id', id).firstOrFail();

    //     // const permissions = await Permission.query().pluck('name', 'id');
    //     // // const userHasRoles = user.roles;
    //     // const rolerHasPermissions = await role.related('permissions').query().orderBy('name').pluck('id');

    //     return inertia.render('Admin/License/Edit', {
    //         // permissions: permissions,
    //         license: license,
    //         // roleHasPermissions: Object.keys(rolerHasPermissions).map((key) => rolerHasPermissions[key]), //convert object to array with role ids
    //     });
    // }
    public async delete({ request, inertia, response, session }: HttpContext) {
        const id = request.param('id');
        try {
            const mimetype = await MimeType.query()
                // .preload('user', (builder) => {
                //     builder.select('id', 'login');
                // })
                .where('id', id)
                // .preload('files')
                .firstOrFail();
            // const validStates = ['inprogress', 'rejected_editor'];
            // if (!validStates.includes(dataset.server_state)) {
            //     // session.flash('errors', 'Invalid server state!');
            //     return response
            //         .flash(
            //             'warning',
            //             `Invalid server state. Dataset with id ${id} cannot be deleted. Datset has server state ${dataset.server_state}.`,
            //         )
            //         .redirect()
            //         .toRoute('dataset.list');
            // }
            return inertia.render('Admin/Mimetype/Delete', {
                mimetype,
            });
        } catch (error) {
            if (error.code == 'E_ROW_NOT_FOUND') {
                session.flash({ warning: 'Mimetype is not found in database' });
            } else {
                session.flash({ warning: 'general error occured, you cannot delete the mimetype' });
            }
            return response.redirect().toRoute('mimetype.index');
        }
    }

    public async deleteStore({ request, response, session }: HttpContext) {
        const id = request.param('id');
        const mimetype = await MimeType.findOrFail(id);
        await mimetype.delete();

        session.flash('message', `Mimetype ${mimetype.name} has been deleted.`);
        return response.redirect().toRoute('settings.mimetype.index');
    }
}
