import Google from 'google-libphonenumber';
const PhoneUtil = Google.PhoneNumberUtil.getInstance();
function parse(value, [...countries] = []) {
    const country = countries.shift();
    try {
        return PhoneUtil.parse(value, country);
    }
    catch (error) {
        if (countries.length > 0) {
            return parse(value, countries);
        }
        throw error;
    }
}
export const StringExtension = (joi) => {
    return {
        base: joi.string(),
        type: 'string',
        messages: {
            'string.phone': '"{{#label}}" did not seem to be a phone number'
        },
        rules: {
            nullable: {
                method() {
                    return this.allow('', null).default(null);
                }
            },
            phone: {
                method({ country, format, strict } = { country: ['FR', 'BE'] }) {
                    const args = {
                        country: country || 'FR',
                        strict: strict !== false,
                        format: format || 'standard'
                    };
                    return this.$_addRule({
                        name: 'phone',
                        args
                    });
                },
                args: [{
                        name: 'country',
                        ref: true,
                        assert: joi.alternatives().try(joi.array().items(joi.string()), joi.string())
                    }, {
                        name: 'strict',
                        ref: true,
                        assert: joi.boolean()
                    }, {
                        name: 'format',
                        ref: true,
                        assert: joi.valid('standard', 'e164', 'international', 'national', 'rfc3966')
                    }
                ],
                validate(value, { prefs, error }, { country, strict, format }) {
                    try {
                        const countries = country instanceof Array ? country : [country];
                        const proto = parse(value, countries);
                        if (strict && !PhoneUtil.isValidNumber(proto)) {
                            throw new Error('StrictPhoneNumber');
                        }
                        if (!prefs.convert) {
                            return value;
                        }
                        if (format === 'standard') {
                            return PhoneUtil.format(proto, Google.PhoneNumberFormat.NATIONAL).replace(/\s/g, '');
                        }
                        return PhoneUtil.format(proto, Google.PhoneNumberFormat[format.toUpperCase()]);
                    }
                    catch (err) {
                        const knownErrors = [...Object.values(Google.Error), 'StrictPhoneNumber'];
                        if (err instanceof Error && knownErrors.indexOf(err.message) !== -1) {
                            return error('string.phone');
                        }
                        throw err;
                    }
                }
            }
        }
    };
};
