import { Request, Response } from '@adonisjs/core/http';

Request.macro('wantsJSON', function (this: Request) {
    const firstType = this.types()[0];
    if (!firstType) {
        return false;
    }

    return firstType.includes('/json') || firstType.includes('+json');
});

declare module '@adonisjs/core/http' {
    interface Request {
        wantsJSON(): boolean;
    }
}

// By specifying this: Response in the function signature, you're explicitly stating
// that 'this' within the function should be of type 'Response', which resolves the TypeScript error.
// Response.macro('flash', function (this: Response, message: any) {
//     if (!this.ctx) {
//         throw new Error('Context is not available');
//     }
//     this.ctx!.session.flash(message);
//     return this;
// });
// Response.macro('flash', function (this: Response, key: string, message: any) {
//     if (!this.ctx) {
//         throw new Error('Context is not available');
//     }
//     this.ctx!.session.flash(key, message);
//     return this;
// });
Response.macro('flash', function (this: Response,  message: any, key?: string,) {
    if (!this.ctx) {
        throw new Error('Context is not available');
    }

    if (key !== undefined) {
        this.ctx!.session.flash(key, message);
    } else {
        this.ctx!.session.flash(message);
    }

    return this;
});
Response.macro('toRoute', function (this: Response, route: string) {
    this.redirect().toRoute(route);
    return this;
});
declare module '@adonisjs/core/http' {
    interface Response {
        flash(message: any): Response;
        flash(key: string, message: any): Response;
        toRoute(route: string): Response;
    }
}

// declare module '@adonisjs/lucid/orm' {
//     // interface ModelQueryBuilder {
//     //     pluck(value: string, id?: string): Promise<Object>;
//     // }

//     // interface ModelQueryBuilder<Model extends LucidModel, LucidRow> {
//     //     pluck(valueColumn: string, id?: string): Promise<{ [key: string]: any }>;
//     // }
//     // interface ModelQueryBuilderContract<Model extends LucidModel, Result = InstanceType<Model>> {
//     //     getCount(): Promise<BigInt>;
//     //     pluck(valueColumn: string, id?: string): Promise<{ [key: string]: any }>;
//     // }

//     // interface ModelQueryBuilderContract<Model extends LucidModel, Result = InstanceType<Model>>
//     interface ModelQueryBuilderContract<Model extends LucidModel, Result = InstanceType<Model>> {
//         // macro typescript definitions here
//         // whereTrue(columnName: string): this;
//         // whereFalse(columnName: string): this;
//         // any(): Promise<boolean>;
//         // selectCount(): Promise<BigInt>;
//         // selectIds(primaryKey?: string): Promise<number[]>;
//         // selectId(primaryKey?: string): Promise<number | undefined>;
//         // selectIdOrFail(primaryKey?: string): Promise<number>;
//         pluck(valueColumn: string, id?: string): Promise<{ [key: string]: any }>;
//     }
// }

// ModelQueryBuilder.macro('pluck', async function (this: ModelQueryBuilder, valueColumn: string, id?: string) : Promise<{ [key: string]: any }>{
//     // let rolesPluck: PluckConfig = {};
//     let rolesPluck: { [key: number]: any } = {};
//     const result = await this.exec();
//     result.forEach((user, index) => {
//         let idc;
//         if (!id) {
//             idc = index;
//         } else {
//             idc = user[id] as number;
//         }
//         const value = user[valueColumn];
//         // rolesPluck[idc] = user.name;
//         rolesPluck[idc] = value;
//     });
//     return rolesPluck;
// });
