/**
 * Reusable Nigeria phone utilities for VTU flows.
 *
 * Main normalized format:
 *   0XXXXXXXXXX (11 digits)
 */

export const NIGERIA_NETWORK_PREFIXES = {
    mtn: [
        '07025', '07026',
        '0703', '0704', '0706',
        '0803', '0806',
        '0810', '0813', '0814', '0816',
        '0903', '0906',
        '0913', '0916',
    ],
    airtel: [
        '0701', '0708',
        '0802', '0808',
        '0812',
        '0901', '0902', '0904', '0907',
        '0912',
    ],
    glo: [
        '0705',
        '0805', '0807',
        '0811', '0815',
        '0905',
        '0915',
    ],
    '9mobile': [
        '0809',
        '0817', '0818', '0819',
        '0908', '0909',
    ],
};

const SUPPORTED_NETWORKS = ['mtn', 'airtel', 'glo', '9mobile'];

/**
 * @param {string|null|undefined} value
 * @returns {string}
 */
const digitsOnly = (value) => String(value || '').replace(/\D+/g, '');

/**
 * @param {string|null|undefined} network
 * @returns {'mtn'|'airtel'|'glo'|'9mobile'|'unknown'}
 */
export const normalizeNigeriaNetworkSlug = (network) => {
    const raw = String(network || '').trim().toLowerCase();
    if (!raw) return 'unknown';

    if (raw === 'mtn') return 'mtn';
    if (raw === 'airtel') return 'airtel';
    if (raw === 'glo') return 'glo';
    if (['9mobile', 'etisalat', '9_mobile', '9-mobile'].includes(raw)) return '9mobile';

    return 'unknown';
};

/**
 * Accepts Nigerian numbers in common formats and returns local format.
 *
 * Examples:
 *  +2347065620433 => 07065620433
 *  2347065620433  => 07065620433
 *  0706 562 0433  => 07065620433
 *
 * @param {string|null|undefined} input
 * @returns {string|null}
 */
export const normalizeNigeriaPhoneNumber = (input) => {
    const digits = digitsOnly(input);
    if (!digits) return null;

    let local = digits;

    // +234XXXXXXXXXX or 234XXXXXXXXXX
    if (local.startsWith('234') && local.length === 13) {
        local = `0${local.slice(3)}`;
    }

    // 2340XXXXXXXXXX (some users include local zero after country code)
    if (local.startsWith('2340') && local.length === 14) {
        local = `0${local.slice(4)}`;
    }

    // 10-digit mobile without leading zero (e.g. 7065620433)
    if (local.length === 10) {
        local = `0${local}`;
    }

    if (!/^0[789]\d{9}$/.test(local)) {
        return null;
    }

    return local;
};

/**
 * Detect likely Nigerian network from normalized local number (0XXXXXXXXXX).
 *
 * @param {string|null|undefined} phone
 * @returns {'mtn'|'airtel'|'glo'|'9mobile'|'unknown'}
 */
export const detectNigeriaNetwork = (phone) => {
    const normalized = normalizeNigeriaPhoneNumber(phone);
    if (!normalized) return 'unknown';

    // Check longer prefixes first to avoid collisions (e.g. 07025 vs 0702*)
    const candidates = [];
    for (const [network, prefixes] of Object.entries(NIGERIA_NETWORK_PREFIXES)) {
        for (const prefix of prefixes) {
            candidates.push({ network, prefix });
        }
    }

    candidates.sort((a, b) => b.prefix.length - a.prefix.length);

    const found = candidates.find(({ prefix }) => normalized.startsWith(prefix));
    if (!found) return 'unknown';

    return /** @type {'mtn'|'airtel'|'glo'|'9mobile'} */ (found.network);
};

/**
 * VTU validation result shape.
 *
 * @typedef {{
 *   isValid: boolean;
 *   normalizedNumber: string|null;
 *   detectedNetwork: 'mtn'|'airtel'|'glo'|'9mobile'|'unknown';
 *   errors: string[];
 *   warnings: string[];
 * }} VtuPhoneValidationResult
 */

/**
 * Validate phone for VTU purchases with optional network mismatch enforcement.
 *
 * @param {string|null|undefined} phoneInput
 * @param {string|null|undefined} selectedNetwork
 * @param {{
 *   validateNetworkMatch?: boolean;
 *   mismatchAsError?: boolean;
 * }=} options
 * @returns {VtuPhoneValidationResult}
 */
export const validateVtuPhoneNumber = (phoneInput, selectedNetwork, options = {}) => {
    const result = {
        isValid: false,
        normalizedNumber: null,
        detectedNetwork: 'unknown',
        errors: [],
        warnings: [],
    };

    const validateNetworkMatch = options.validateNetworkMatch ?? true;
    const mismatchAsError = options.mismatchAsError ?? true;

    const normalizedNumber = normalizeNigeriaPhoneNumber(phoneInput);
    if (!normalizedNumber) {
        result.errors.push('Enter a valid Nigerian phone number (e.g. 07065620433).');
        return result;
    }

    result.normalizedNumber = normalizedNumber;
    result.detectedNetwork = detectNigeriaNetwork(normalizedNumber);

    const selected = normalizeNigeriaNetworkSlug(selectedNetwork);

    if (selected !== 'unknown') {
        if (result.detectedNetwork === 'unknown') {
            result.warnings.push('Network could not be detected confidently from this number.');
        } else if (selected !== result.detectedNetwork) {
            const readableSelected = selected === '9mobile' ? '9mobile' : selected.toUpperCase();
            const readableDetected = result.detectedNetwork === '9mobile' ? '9mobile' : result.detectedNetwork.toUpperCase();
            const message = `Selected network is ${readableSelected}, but number looks like ${readableDetected}.`;

            if (validateNetworkMatch && mismatchAsError) {
                result.errors.push(message);
            } else {
                result.warnings.push(message);
            }
        }
    }

    if (!SUPPORTED_NETWORKS.includes(result.detectedNetwork) && result.detectedNetwork !== 'unknown') {
        result.warnings.push('Detected network is not in the current supported mobile network list.');
    }

    result.isValid = result.errors.length === 0;
    return result;
};

