/*
|--------------------------------------------------------------------------
| Preloaded File - node ace make:preload rules/uniquePerson
|--------------------------------------------------------------------------
|*/

import { FieldContext } from '@vinejs/vine/types';
import db from '@adonisjs/lucid/services/db';
import vine from '@vinejs/vine';
import { VineString, VineNumber } from '@vinejs/vine';

/**
 * Options accepted by the unique rule
 */
type Options = {
    table: string;
    column: string;
    // whereNot?:  ((field: FieldContext) => string);
    idField: string;
};


async function isUniquePerson(value: unknown, options: Options, field: FieldContext) {
    if (typeof value !== 'string' && typeof value != 'number') {
        return;
    }

    // let ignoreId: string | undefined;
    // if (options.whereNot) {
    //     ignoreId = options.whereNot(field);
    // }
    const idValue = vine.helpers.getNestedValue(options.idField, field); //'Main' or 'Translated'

    const builder = db.from(options.table).select(options.column).where(options.column, value);
    // if existent id, exclide it from validating
    if (idValue) {
        builder.whereNot('id', '=', idValue);
    }
    const result = await builder.first();
    if (result) {
        // report that value is NOT unique
        field.report('The {{ field }} field is not unique', 'isUnique', field);
    
    }   
}

export const isUniquePersonRule = vine.createRule(isUniquePerson);


declare module '@vinejs/vine' {
    interface VineString {
        isUniquePerson(options: Options): this;
    }
    interface VineNumber {
        isUniquePerson(options: Options): this;
    }
}

VineString.macro('isUniquePerson', function (this: VineString, options: Options) {
    return this.use(isUniquePersonRule(options));
});
VineNumber.macro('isUniquePerson', function (this: VineNumber, options: Options) {
    return this.use(isUniquePersonRule(options));
});