import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
// import User from 'App/Models/User';
// import Role from 'App/Models/Role';
// import Database from '@ioc:Adonis/Lucid/Database';
import License from 'App/Models/License';
import Project from 'App/Models/Project';
// import type { ModelQueryBuilderContract } from '@ioc:Adonis/Lucid/Orm';
// import CreateUserValidator from 'App/Validators/CreateUserValidator';
// import UpdateUserValidator from 'App/Validators/UpdateUserValidator';
// import { RenderResponse } from '@ioc:EidelLev/Inertia';
import { schema, CustomMessages, rules } from '@ioc:Adonis/Core/Validator';
import dayjs from 'dayjs';

enum TitleTypes {
    Main = 'Main',
    Sub = 'Sub',
    Alternative = 'Alternative',
    Translated = 'Translated',
    Other = 'Other',
}

enum DescriptionTypes {
    Abstract = 'Abstract',
    Methods = 'Methods',
    Series_information = 'Series_information',
    Technical_info = 'Technical_info',
    Translated = 'Translated',
    Other = 'Other',
}

export default class DatasetController {
    public async create({ inertia }: HttpContextContract) {
        const licenses = await License.query().select('id', 'name_long').pluck('name_long', 'id');

        const projects = await Project.query().pluck('label', 'id');

        const doctypes = {
            analysisdata: { label: 'Analysis', value: 'analysisdata' },
            measurementdata: { label: 'Measurements', value: 'measurementdata' },
            monitoring: 'Monitoring',
            remotesensing: 'Remote Sensing',
            gis: 'GIS',
            models: 'Models',
            mixedtype: 'Mixed Type',
        };

        // const titletypes = {
        //     Sub: 'Sub',
        //     Alternative: 'Alternative',
        //     Translated: 'Translated',
        //     Other: 'Other',
        // };

        // let test = Object.entries(TitleTypes).map(([key, value]) => ({id: key, value: value}))

        // const languages = await Database.from('languages').select('*').where('active', true);
        return inertia.render('Submitter/Dataset/Create', {
            licenses: licenses,
            doctypes: doctypes,
            titletypes: Object.entries(TitleTypes)
                .filter(([value]) => value !== 'Main')
                .map(([key, value]) => ({ value: key, label: value })),
            descriptiontypes: Object.entries(DescriptionTypes)
                .filter(([value]) => value !== 'Abstract')
                .map(([key, value]) => ({ value: key, label: value })),
            // descriptiontypes: DescriptionTypes
            projects: projects,
        });
    }

    public async firstStep({ request, response }: HttpContextContract) {
        const newDatasetSchema = schema.create({
            language: schema.string({ trim: true }, [
                rules.regex(/^[a-zA-Z0-9-_]+$/), //Must be alphanumeric with hyphens or underscores
            ]),
            licenses: schema.array([rules.minLength(1)]).members(schema.number()), // define at least one license for the new dataset
            rights: schema.string([rules.equalTo('true')]),
        });

        try {
            //  Step 2 - Validate request body against  the schema

            await request.validate({ schema: newDatasetSchema, messages: this.messages });
            // console.log({ payload });
        } catch (error) {
            // Step 3 - Handle errors
            // return response.badRequest(error.messages);
            throw error;
        }
        return response.redirect().back();
    }

    public async secondStep({ request, response }: HttpContextContract) {
        const newDatasetSchema = schema.create({
            // first step
            language: schema.string({ trim: true }, [
                rules.regex(/^[a-zA-Z0-9-_]+$/), //Must be alphanumeric with hyphens or underscores
            ]),
            licenses: schema.array([rules.minLength(1)]).members(schema.number()), // define at least one license for the new dataset
            rights: schema.string([rules.equalTo('true')]),
            // second step
            type: schema.string({ trim: true }, [rules.minLength(3), rules.maxLength(255)]),
            creating_corporation: schema.string({ trim: true }, [rules.minLength(3), rules.maxLength(255)]),
            titles: schema.array([rules.minLength(1)]).members(
                schema.object().members({
                    value: schema.string({ trim: true }, [rules.minLength(3), rules.maxLength(255)]),
                    type: schema.enum(Object.values(TitleTypes)),
                    language: schema.string({ trim: true }, [
                        rules.minLength(2),
                        rules.maxLength(255),
                        rules.translatedLanguage('/language', 'type'),
                    ]),
                }),
            ),
            descriptions: schema.array([rules.minLength(1)]).members(
                schema.object().members({
                    value: schema.string({ trim: true }, [rules.minLength(3), rules.maxLength(255)]),
                    type: schema.enum(Object.values(DescriptionTypes)),
                    language: schema.string({ trim: true }, [
                        rules.minLength(2),
                        rules.maxLength(255),
                        rules.translatedLanguage('/language', 'type'),
                    ]),
                }),
            ),
            authors: schema.array([rules.minLength(1)]).members(schema.object().members({ email: schema.string({ trim: true }) })),

            // project_id: schema.number(),
        });

        try {
            //  Step 2 - Validate request body against  the schema
            await request.validate({ schema: newDatasetSchema, messages: this.messages });
            // console.log({ payload });
        } catch (error) {
            // Step 3 - Handle errors
            // return response.badRequest(error.messages);
            throw error;
        }
        return response.redirect().back();
    }

    public async thirdStep({ request, response }: HttpContextContract) {
        const newDatasetSchema = schema.create({
            // first step
            language: schema.string({ trim: true }, [
                rules.regex(/^[a-zA-Z0-9-_]+$/), //Must be alphanumeric with hyphens or underscores
            ]),
            licenses: schema.array([rules.minLength(1)]).members(schema.number()), // define at least one license for the new dataset
            rights: schema.string([rules.equalTo('true')]),
            // second step
            type: schema.string({ trim: true }, [rules.minLength(3), rules.maxLength(255)]),
            creating_corporation: schema.string({ trim: true }, [rules.minLength(3), rules.maxLength(255)]),
            titles: schema.array([rules.minLength(1)]).members(
                schema.object().members({
                    value: schema.string({ trim: true }, [rules.minLength(3), rules.maxLength(255)]),
                    type: schema.enum(Object.values(TitleTypes)),
                    language: schema.string({ trim: true }, [
                        rules.minLength(2),
                        rules.maxLength(255),
                        rules.translatedLanguage('/language', 'type'),
                    ]),
                }),
            ),
            descriptions: schema.array([rules.minLength(1)]).members(
                schema.object().members({
                    value: schema.string({ trim: true }, [rules.minLength(3), rules.maxLength(255)]),
                    type: schema.enum(Object.values(DescriptionTypes)),
                    language: schema.string({ trim: true }, [
                        rules.minLength(2),
                        rules.maxLength(255),
                        rules.translatedLanguage('/language', 'type'),
                    ]),
                }),
            ),
            authors: schema.array([rules.minLength(1)]).members(schema.object().members({ email: schema.string({ trim: true }) })),
            // third step
            project_id: schema.number.optional(),
            embargo_date: schema.date.optional({ format: 'yyyy-MM-dd' }, [rules.after(10, 'days')]),
            coverage: schema.object().members({
                x_min: schema.number(),
                x_max: schema.number(),
                y_min: schema.number(),
                y_max: schema.number(),
                elevation_absolut: schema.number.optional(),
                elevation_min: schema.number.optional([
                    rules.requiredIfExists('elevation_max')                   
                ]),
                elevation_max: schema.number.optional([
                    rules.requiredIfExists('elevation_min')
                   
                ]),
                depth_absolut: schema.number.optional(),
                depth_min: schema.number.optional([
                    rules.requiredIfExists('depth_max')                   
                ]),
                depth_max: schema.number.optional([
                    rules.requiredIfExists('depth_min')
                   
                ]),
            }),
        });

        try {
            //  Step 2 - Validate request body against  the schema
            await request.validate({ schema: newDatasetSchema, messages: this.messages });
            // console.log({ payload });
        } catch (error) {
            // Step 3 - Handle errors
            // return response.badRequest(error.messages);
            throw error;
        }
        return response.redirect().back();
    }
    // public async store({ request, response, session }: HttpContextContract) {
    // 	// node ace make:validator CreateUser
    // 	try {
    // 		//  Step 2 - Validate request body against  the schema
    // 		await request.validate(CreateUserValidator);
    // 		// console.log({ payload });
    // 	} catch (error) {
    // 		// Step 3 - Handle errors
    // 		// return response.badRequest(error.messages);
    // 		throw error;
    // 	}
    // 	const input = request.only(['login', 'email', 'password']);
    // 	const user = await User.create(input);
    // 	if (request.input('roles')) {
    // 		const roles: Array<number> = request.input('roles');
    // 		await user.related('roles').attach(roles);
    // 	}

    // 	session.flash('message', 'User has been created successfully');
    // 	return response.redirect().toRoute('user.index');
    // }

    public messages: CustomMessages = {
        'minLength': '{{ field }} must be at least {{ options.minLength }} characters long',
        'maxLength': '{{ field }} must be less then {{ options.maxLength }} characters long',
        'required': '{{ field }} is required',
        'unique': '{{ field }} must be unique, and this value is already taken',
        // 'confirmed': '{{ field }} is not correct',
        'licences.minLength': 'at least {{ options.minLength }} permission must be defined',
        'licences.*.number': 'Define roles as valid numbers',
        'rights.equalTo': 'you must agree to continue',

        'titles.0.value.minLength': 'Main Title  must be at least {{ options.minLength }} characters long',
        'titles.0.value.required': 'Main Title is required',
        'titles.*.value.required': 'Additional title is required, if defined',
        'titles.*.type.required': 'Additional title type is required',
        'titles.*.language.required': 'Additional title language is required',
        'titles.*.language.translatedLanguage': 'The language of the translated title must be different from the language of the dataset',

        'descriptions.0.value.minLength': 'Main Abstract  must be at least {{ options.minLength }} characters long',
        'descriptions.0.value.required': 'Main Abstract is required',
        'descriptions.*.value.required': 'Additional description is required, if defined',
        'descriptions.*.type.required': 'Additional description type is required',
        'descriptions.*.language.required': 'Additional description language is required',
        'descriptions.*.language.translatedLanguage':
            'The language of the translated description must be different from the language of the dataset',

        'authors.minLength': 'at least {{ options.minLength }} author must be defined',

        'after': `{{ field }} must be older than ${dayjs().add(10, 'day')}`,
    };
}
