import { showLoader, hideLoader } from './loader';

const SUMMARY_SELECTORS = {
    subTotal: {
        item: '.checkout-widget__item-bold',
        value: '.checkout-widget__item-value',
        title: 'Items subtotal:',
    },
    vat: {
        item: '.checkout-widget__item-vat',
        value: '.checkout-widget__item-value',
        title: 'VAT:',
    },
    clickAndCollectCost: {
        item: '.checkout-widget__item-cc',
        value: '.checkout-widget__item-value',
        title: 'Click & Collect:',
    },
    deliveryCost: {
        item: '.checkout-widget__item-delivery',
        value: '.checkout-widget__item-value',
        title: 'Delivery:',
    },
    charityPrice: {
        item: '.checkout-widget__item-charity',
        value: '.checkout-widget__item-value',
        title: 'Charity donation:',
    },
    discountTotal: {
        item: '.checkout-widget__details-discount',
        value: '.checkout-widget__detail-value',
    },
    giftCardApplied: {
        item: '.checkout-widget__gift-card',
        value: '.checkout-widget__item-value',
        title: 'Gift Card:',
    },
    total: { item: '.checkout-widget__total', value: '.checkout-widget__total-value' },
};

const CURRENCY_KEYS = new Set([
    'subTotal',
    'vat',
    'clickAndCollectCost',
    'deliveryCost',
    'charityPrice',
    'discountTotal',
    'total',
    'giftCardApplied',
]);

const GIFT_CARD_ALREADY_ADDED = 'GIFT_CARD_ALREADY_ADDED';
const PIS_REQUEST_TIMEOUT = 'PIS-REQUEST-TIMEOUT';
const PIS_INTEGRATION_ERROR = 'PIS-INTEGRATION-ERROR';
const PIS_INSUFFICIENT_AMOUNT = 'PIS-INSUFFICIENT-AMOUNT';
const PIS_PROCESSING_ERROR = 'PIS_PROCESSING_ERROR';
const HYBRIS_REQUEST_TIMEOUT = 'HYBRIS-REQUEST-TIMEOUT';
const HYBRIS_PIS_INTEGRATION_ERROR = 'HYBRIS-PIS_INTEGRATION-ERROR';
const HYBRIS_PIS_CONNECTION_ERROR = 'HYBRIS-PIS_CONNECTION-ERROR';
const ZERO_BALANCE = 'ZERO_BALANCE';
const SPLIT_PAYMENT_CARD_ERROR = 'SPLIT_PAYMENT_CARD_ERROR';

export const DEFAULT_ERROR_MESSAGE =
    'Unable to use Gift Card at this time, please try later or click here for support.';

export const DEFAULT_PAY_ERROR_MESSAGE =
    'Unfortunately there was a problem placing your order with Gift Card(s). Please click here for support.';

export const OK_CODE = 0;

export const MESSAGE_BY_CODE = {
    10: 'Gift Card number and / or PIN not recognised. A Gift Card will be locked following three unsuccessful PIN attempts.',
    16: 'Card locked due to three unsuccessful PIN entries. For support click here.',
    20: 'Unable to use Gift Card at this time, please try later or click here for support.',
    21: 'Gift Card number not recognised.',
    40: 'Unable to use Gift Card at this time, please try later or click here for support.',
    60: 'The entered Gift Card has expired. For support click here.',
    75: 'The entered Gift Card is invalid. For support click here.',
    [GIFT_CARD_ALREADY_ADDED]: 'Gift Card already added, please use a different card.',
    [PIS_REQUEST_TIMEOUT]:
        'Unable to use Gift Card at this time, please try later or click here for support.',
    [PIS_INTEGRATION_ERROR]:
        'Unable to use Gift Card at this time, please try later or click here for support.',
    [PIS_INSUFFICIENT_AMOUNT]:
        'Unfortunately there was a problem placing your order with Gift Card(s). Please click here for support.',
    [PIS_PROCESSING_ERROR]:
        'Unfortunately there was a problem placing your order with Gift Card(s). Please click here for support.',
    [HYBRIS_REQUEST_TIMEOUT]:
        'Unable to use Gift Card at this time, please try later or click here for support.',
    [HYBRIS_PIS_INTEGRATION_ERROR]:
        'Unable to use Gift Card at this time, please try later or click here for support.',
    [HYBRIS_PIS_CONNECTION_ERROR]:
        'Unable to use Gift Card at this time, please try later or click here for support.',
    [ZERO_BALANCE]:
        'Insufficient funds available, please try another Gift Card or alternate payment method.',
    99: 'The entered Gift Card is invalid. For support click here.',
    [-1]: 'Gift Card is unavailable at this time, please try later. For support click here.',
};

export const PAY_MESSAGE_BY_CODE = {
    101: 'Unable to use Gift Cards at this time, please try later or click here for support.',
    102: 'Unfortunately there was a problem with requesting your card details from the payment provider. Available funds on your Gift Card are unchanged.',
    103: 'Unfortunately there was a problem placing your order with Gift Card(s). Please click here for support.',
    104: 'Unfortunately there was a problem placing your order with Gift Card(s). Please click here for support.',
    [PIS_REQUEST_TIMEOUT]:
        'Unable to use Gift Card at this time, please try later or click here for support.',
    [PIS_INTEGRATION_ERROR]:
        'Unable to use Gift Card at this time, please try later or click here for support.',
    [PIS_INSUFFICIENT_AMOUNT]:
        'Unfortunately there was a problem placing your order with Gift Card(s). Please click here for support.',
    [PIS_PROCESSING_ERROR]:
        'Unfortunately there was a problem placing your order with Gift Card(s). Please click here for support.',
    [HYBRIS_REQUEST_TIMEOUT]:
        'Unable to use Gift Card at this time, please try later or click here for support.',
    [HYBRIS_PIS_INTEGRATION_ERROR]:
        'Unable to use Gift Card at this time, please try later or click here for support.',
    [HYBRIS_PIS_CONNECTION_ERROR]:
        'Unable to use Gift Card at this time, please try later or click here for support.',
    [SPLIT_PAYMENT_CARD_ERROR]:
        'Unfortunately there was a problem with requesting your card details from the payment provider. Available funds on your Gift Card are unchanged.',
};

export const ADD_GIFT_CARD = 'addGiftCard';
export const REMOVE_GIFT_CARD = 'removeGiftCard';
export const PAY_WITH_GIFT_CARD = 'payWithGiftCard';

export const FAQ_URL = 'https://www.wickes.co.uk/gifts';

export const escapeHtml = (s) =>
    $('<div>')
        .text(String(s || ''))
        .html();

export const linkifyClickHere = (msg) =>
    escapeHtml(msg).replace(
        /\bclick here\b/gi,
        `<a href="${FAQ_URL}" target="_blank" rel="noopener" class="notification_link">click here</a>`
    );

export function formatGc16(raw) {
    const digits = String(raw || '')
        .replace(/\D/g, '')
        .slice(0, 16);
    return digits.replace(/(\d{4})(?=\d)/g, '$1-');
}

function formatGBP(value) {
    if (value === null || typeof value === 'undefined' || String(value).trim() === '') {
        return value;
    }

    const cleanedValue = String(value).replace(/[^\d.-]/g, '');
    const numberValue = Number(cleanedValue);

    if (Number.isFinite(numberValue)) {
        return `£${numberValue.toFixed(2)}`;
    }

    return value;
}

export function buildHintContext(count, limit) {
    const max = count >= limit;

    return {
        canAdd: !max,
        max,
        hintClass: `giftcard-summary__hint${max ? ' giftcard-summary__hint--max' : ''}`,
    };
}

export function buildSummaryEqualMap(data) {
    return Object.entries(SUMMARY_SELECTORS).map(([key, d]) => {
        const raw = data[key];
        let dataValue = raw;

        if (key === 'giftCardApplied') {
            if (isZeroAmount(raw)) {
                dataValue = '';
            } else if (raw != null && raw !== '') {
                dataValue = formatGBP(raw);
                if (typeof dataValue === 'string' && dataValue.startsWith('£')) {
                    dataValue = `-${dataValue}`;
                }
            }
        } else {
            if (CURRENCY_KEYS.has(key) && raw != null && raw !== '') {
                dataValue = formatGBP(raw);
            }
        }

        return {
            item: d.item,
            itemValue: d.value,
            dataValue,
            ...(d.title ? { title: d.title } : {}),
        };
    });
}

export function isZeroAmount(val) {
    const cleaned = String(val ?? '').replace(/[^\d.]/g, '');
    if (!cleaned) {
        return false;
    }
    const num = Number(cleaned);
    return Number.isFinite(num) && num === 0;
}

// --- API/Event-Dispatching Functions ---

export function verifyGiftCard($loader, giftCardNumber, pin) {
    showLoader($loader);
    return new Promise((resolve, reject) => {
        const payload = { giftCardNumber, pin };
        const detail = { resolve, reject, payload };
        const evt = createEvent(ADD_GIFT_CARD, payload, detail);
        window.dispatchEvent(evt);
    }).finally(() => {
        hideLoader($loader);
    });
}

export function removeGiftCard($loader, index) {
    showLoader($loader);
    return new Promise((resolve, reject) => {
        const payload = { index };
        const detail = { resolve, reject, payload };
        const evt = createEvent(REMOVE_GIFT_CARD, payload, detail);
        window.dispatchEvent(evt);
    }).finally(() => {
        hideLoader($loader);
    });
}

export function payWithGiftCard() {
    return new Promise((resolve, reject) => {
        const detail = { resolve, reject };
        const evt = createEvent(PAY_WITH_GIFT_CARD, undefined, detail);
        window.dispatchEvent(evt);
    });
}
