import { getSetting } from '@woocommerce/settings';
import { createElement, useState, useEffect } from '@wordpress/element';
import { useSelect } from '@wordpress/data';
import { registerPaymentMethod } from '@woocommerce/blocks-registry';

// ============================================
// Configuration & Constants
// ============================================

const settings = getSetting('ipag-gateway_data', {});
const labelText = settings.title || 'Pagamento cartão de crédito';

if (!window.ipagCheckoutObservers) {
    const observers = new Map();

    window.ipagCheckoutObservers = {
        register(name, handlers) {
            if (!name) {
                console.warn('ipagCheckoutObservers: Observer name is required to register');
                return;
            }
            observers.set(String(name), handlers || {});
        },
        unregister(name) {
            if (!name) {
                console.warn('ipagCheckoutObservers: Observer name is required to unregister');
                return;
            }
            observers.delete(String(name));
        },
        emitAsync(eventName, payload) {
            const results = [];

            observers.forEach((handlers, name) => {
                if (!handlers || typeof handlers[eventName] !== 'function') {
                    return;
                }

                try {
                    results.push(handlers[eventName](payload));
                } catch (error) {
                    console.warn(`ipagCheckoutObservers:${eventName} failed`, name, error);
                }
            });

            return results;
        },
        emit(eventName, payload) {
            observers.forEach((handlers, name) => {
                if (!handlers || typeof handlers[eventName] !== 'function') {
                    return;
                }

                try {
                    handlers[eventName](payload);
                } catch (error) {
                    console.warn(`ipagCheckoutObservers:${eventName} failed`, name, error);
                }
            });
        },
    };
}

const DIGITS_ONLY = /\D/g;

// ============================================
// Helper Functions
// ============================================

/**
 * Detect card brand from number
 */
const CARDS_NUMBER_LENGTH = 16;

const CARDS_BRANDS_PATTERNS = {
    elo: /^(401178|401179|431274|438935|451416|457393|457631|457632|504175|627780|636297|636368|(506699|5067[0-6]\d|50677[0-8])|(50900\d|5090[1-9]\d|509[1-9]\d{2})|65003[1-3]|(65003[5-9]|65004\d|65005[0-1])|(65040[5-9]|6504[1-3]\d)|(65048[5-9]|65049\d|6505[0-2]\d|65053[0-8])|(65054[1-9]|6505[5-8]\d|65059[0-8])|(65070\d|65071[0-8])|65072[0-7]|(65090[1-9]|65091\d|650920)|(65165[2-9]|6516[6-7]\d)|(65500\d|65501\d)|(65502[1-9]|6550[3-4]\d|65505[0-8]))\d{0,12}$/,
    visa: /^4\d{0,18}$/,
    mastercard:
        /^(5[1-5]\d{0,14}|22(2[1-9]|[3-9]\d)\d{0,12}|2[3-6]\d\d{0,13}|27(0\d|1\d|20)\d{0,12})$/,
    amex: /^3[47]\d{0,13}$/,
    discover: /^6(011|22|4|5)\d{0,15}$/,
    diners: /^3(0[0-5]|[689])\d{0,11}$/,
    jcb: /^(2131|1800|35)\d{0,15}$/,
    unionpay: /^62\d{0,17}$/,
    hipercard: /^(((606282)\d{0,10})|((3841)\d{0,12}))$/,
};

function detectBrand(number = '') {
    const digits = number.replace(DIGITS_ONLY, '');

    if (digits.length >= CARDS_NUMBER_LENGTH) {
        const detectedBrand = iPag?.getBrandInfo(digits);

        const brand_name = detectedBrand?.type && detectedBrand.type !== 'unknown' ? detectedBrand.type : '';

        if (brand_name) {
            return brand_name;
        }
    }

    for (const [brand, pattern] of Object.entries(CARDS_BRANDS_PATTERNS)) {
        if (pattern.test(digits)) return brand;
    }
    return '';
}

/**
 * Format card number for preview (show only last 4 digits)
 */
function formatMaskedNumber(value) {
    const digits = (value || '').replace(DIGITS_ONLY, '').slice(0, 16);
    const padded = digits.padEnd(16, '•');
    return `${padded.slice(0, 4)}  ${padded.slice(4, 8)}  ${padded.slice(
        8,
        12,
    )}  ${padded.slice(12, 16)}`;
}

/**
 * Format card number for input (groups of 4)
 */
function formatCardNumberInput(value) {
    const digits = (value || '').replace(DIGITS_ONLY, '').slice(0, 16);
    return digits.replace(/(\d{4})(?=\d)/g, '$1 ');
}

/**
 * Validate card number using Luhn algorithm
 */
function isValidCardNumber(number) {
    const digits = (number || '').replace(DIGITS_ONLY, '');
    if (digits.length < 13 || digits.length > 19) return false;

    let sum = 0;
    let isEven = false;

    for (let i = digits.length - 1; i >= 0; i--) {
        let digit = parseInt(digits[i], 10);

        if (isEven) {
            digit *= 2;
            if (digit > 9) digit -= 9;
        }

        sum += digit;
        isEven = !isEven;
    }

    return sum % 10 === 0;
}

/**
 * Validate expiry date
 */
function isValidExpiry(expiry) {
    const digits = (expiry || '').replace(DIGITS_ONLY, '');
    if (digits.length !== 4) return false;

    const month = parseInt(digits.slice(0, 2), 10);
    const year = parseInt(digits.slice(2, 4), 10);

    if (month < 1 || month > 12) return false;

    const now = new Date();
    const currentYear = now.getFullYear() % 100;
    const currentMonth = now.getMonth() + 1;

    if (year < currentYear) return false;
    if (year === currentYear && month < currentMonth) return false;

    return true;
}

/**
 * Flatten nested objects into flat key/value pairs for paymentMethodData
 */
function flattenToPaymentData(obj, prefix = '') {
    const out = {};

    Object.entries(obj || {}).forEach(([key, value]) => {
        const path = prefix ? `${prefix}-${key}` : key;

        if (value && typeof value === 'object' && !Array.isArray(value)) {
            Object.assign(out, flattenToPaymentData(value, path));
            return;
        }

        out[path] = value === null || value === undefined ? '' : String(value);
    });

    return out;
}

function normalizeAcceptedBrands(value) {
    if (Array.isArray(value)) {
        return value.map((brand) => String(brand).trim()).filter(Boolean);
    }

    if (!value) {
        return [];
    }

    return String(value)
        .split(',')
        .map((brand) => brand.trim())
        .filter(Boolean);
}

function formatBrandLabel(brand) {
    return String(brand)
        .replace(/[-_]+/g, ' ')
        .replace(/\b\w/g, (char) => char.toUpperCase());
}

// ============================================
// UI Components
// ============================================

const brand_enabled = settings.brand === 'yes';

const allow_saved_cards_enabled = !!settings.allow_saved_cards;

const Label = ({ components }) => {
    const { PaymentMethodLabel } = components;
    return createElement(
        'div',
        { className: 'ipag-label-with-badge' },
        createElement(PaymentMethodLabel, {
            className: 'ipag-gateway-label',
            text: labelText,
        }),
        brand_enabled &&
        createElement('img', {
            src: settings.assets_url
                ? `${settings.assets_url}../images/ipag.png`
                : '/wp-content/plugins/ipag-gateway/images/ipag.png',
            alt: 'iPag',
            className: 'ipag-label-badge',
            title: 'Pagamentos seguros com iPag',
        }),
    );
};

const SavedTokenComponent = ({ eventRegistration, emitResponse, token }) => {
    const [savedInstallments, setSavedInstallments] = useState('0');
    const [errors, setErrors] = useState({ installments: '' });
    const { onPaymentSetup } = eventRegistration;

    useEffect(() => {
        const unsubscribe = onPaymentSetup(() => {
            if (isNaN(savedInstallments)) {
                setErrors({ installments: 'Selecione o número de parcelas' });

                return {
                    type: emitResponse.responseTypes.ERROR,
                    message: 'Selecione o número de parcelas para o cartão salvo.',
                    messageContext: emitResponse.noticeContexts.PAYMENTS,
                };
            }

            setErrors({ installments: '' });

            return {
                type: emitResponse.responseTypes.SUCCESS,
                meta: {
                    paymentMethodData: {
                        ipag_woo_payments_blocks: 'yes',
                        ipag_saved_card_option: 'saved',
                        ipag_saved_token_id: token ? String(token) : '',
                        ipag_saved_cards_installments: savedInstallments,
                    },
                },
            };
        });

        return unsubscribe;
    }, [
        onPaymentSetup,
        emitResponse.responseTypes.SUCCESS,
        emitResponse.responseTypes.ERROR,
        emitResponse.noticeContexts.PAYMENTS,
        savedInstallments,
        token,
    ]);

    const installmentOptions = (settings.installmentOptions || []).map((opt) =>
        createElement('option', { key: opt.value, value: opt.value }, opt.label),
    );

    return createElement(
        'div',
        { className: 'ipag-gateway-credit-form' },
        createElement(
            'p',
            {
                className:
                    'form-row' + (errors.installments ? ' woocommerce-invalid' : ''),
            },
            createElement(
                'label',
                { htmlFor: 'ipag_saved_cards_installments' },
                'Número de Parcelas ',
                createElement('abbr', { className: 'required' }, '*'),
            ),
            createElement(
                'select',
                {
                    id: 'ipag_saved_cards_installments',
                    name: 'ipag_saved_cards_installments',
                    className:
                        'select_field select-ipag box-fill' +
                        (errors.installments ? ' woocommerce-invalid' : ''),
                    value: savedInstallments,
                    onChange: (e) => {
                        setSavedInstallments(e.target.value);
                        if (errors.installments) {
                            setErrors({ installments: '' });
                        }
                    },
                },
                installmentOptions,
            ),
            errors.installments &&
            createElement(
                'span',
                { className: 'woocommerce-error', role: 'alert' },
                errors.installments,
            ),
        ),
    );
};

const Content = ({ eventRegistration, emitResponse }) => {
    const [cardNumber, setCardNumber] = useState('');
    const [cardName, setCardName] = useState('');
    const [cardExpiry, setCardExpiry] = useState('');
    const [cardCvv, setCardCvv] = useState('');
    const [document, setDocument] = useState('');
    const [detectedBrand, setDetectedBrand] = useState('');
    const [installments, setInstallments] = useState('0');
    const [saveCardChecked, setSaveCardChecked] = useState(false);
    const [focusedField, setFocusedField] = useState('');
    const [errors, setErrors] = useState({
        cardNumber: '',
        cardName: '',
        cardExpiry: '',
        cardCvv: '',
        document: '',
        installments: '',
    });

    const checkoutSnapshot = useSelect((select) => {
        const cartStore = select('wc/store/cart');

        const cartData = cartStore?.getCartData ? cartStore.getCartData() : {};
        const customerData = cartStore?.getCustomerData ? cartStore.getCustomerData() : {};

        const billingAddress =
            customerData.billingAddress || cartData.billingAddress || {};
        const shippingAddress =
            customerData.shippingAddress || cartData.shippingAddress || {};

        const billingFullName = [billingAddress.first_name, billingAddress.last_name]
            .filter(Boolean)
            .join(' ');
        const shippingFullName = [
            shippingAddress.first_name,
            shippingAddress.last_name,
        ]
            .filter(Boolean)
            .join(' ');

        return {
            customer: {
                fullName: billingFullName,
                email: billingAddress.email || '',
                phone: billingAddress.phone || '',
            },
            billingAddress: {
                ...billingAddress,
                fullName: billingFullName,
            },
            shippingAddress: {
                ...shippingAddress,
                fullName: shippingFullName,
            },
            cart: {
                items: Array.isArray(cartData.items)
                    ? cartData.items.map((item) => ({
                        id: item.id,
                        name: item.name,
                        quantity: item.quantity,
                        sku: item.sku,
                        price: item.prices?.price || '',
                        description: item.description || item.short_description || '',
                    }))
                    : [],
                totalCents: cartData.totals?.total_price || '',
                currencyMinorUnit: cartData.totals?.currency_minor_unit ?? 2,
            },
        };
    }, []);

    const expiryDigits = cardExpiry.replace(DIGITS_ONLY, '');
    const expiryYearDisplay = expiryDigits.slice(2, 4).padEnd(2, '•');
    const expiryMonthDisplay = expiryDigits.slice(0, 2).padEnd(2, '•');

    const brandLogoUrl = detectedBrand ? `${settings.images_url}${detectedBrand}.png` : null;
    const cvvDisplay = cardCvv ? '•'.repeat(Math.min(cardCvv.length, 4)) : '•••';
    const acceptedBrands = normalizeAcceptedBrands(settings.accepted_cards);
    const selectedBrandKey = detectedBrand ? String(detectedBrand).toLowerCase() : '';
    const acceptedBrandItems = acceptedBrands.map((brand) => {
        const brandKey = String(brand).toLowerCase();
        const brandLabel = formatBrandLabel(brandKey);
        const brandImageUrl = settings.images_url
            ? `${settings.images_url}${brandKey}.png`
            : null;
        const isSelected = selectedBrandKey && brandKey === selectedBrandKey;

        return createElement(
            'li',
            {
                key: brandKey,
                className:
                    `ipag-accepted-brand ipag-brand-${brandKey}` +
                    (isSelected ? ' is-selected' : ''),
            },
            brandImageUrl
                ? createElement('img', {
                    src: brandImageUrl,
                    alt: brandLabel,
                    title: brandLabel,
                })
                : createElement('span', {}, brandLabel),
        );
    });

    const { onPaymentSetup } = eventRegistration;

    useEffect(() => {
        window.ipagCheckoutObservers?.emit('mount', checkoutSnapshot);
        return () => { window.ipagCheckoutObservers?.emit('unmount', checkoutSnapshot); }
    }, []);

    useEffect(() => {
        const unsubscribe = onPaymentSetup(() => {

            return new Promise((resolve) => {
                const validationErrors = {};

                const state = {
                    cardNumber,
                    cardName,
                    cardExpiry,
                    cardCvv,
                    document,
                    detectedBrand,
                    installments,
                    saveCardChecked,
                };

                // Validate card number
                if (!state.cardNumber || state.cardNumber.length < 13) {
                    validationErrors.cardNumber = 'Número do cartão é obrigatório';
                } else if (!isValidCardNumber(state.cardNumber)) {
                    validationErrors.cardNumber = 'Número do cartão inválido';
                } else if (!state.detectedBrand) {
                    validationErrors.cardNumber = 'Bandeira do cartão não identificada';
                } else if (
                    acceptedBrands.length > 0 &&
                    !acceptedBrands
                        .map((brand) => String(brand).toLowerCase())
                        .includes(String(state.detectedBrand).toLowerCase())
                ) {
                    validationErrors.cardNumber = 'Bandeira do cartão não aceita';
                }

                // Validate cardholder name
                if (!state.cardName || state.cardName.trim().length < 3) {
                    validationErrors.cardName = 'Nome do titular é obrigatório';
                }

                // Validate expiry
                const expiryDigits = state.cardExpiry.replace(DIGITS_ONLY, '');
                if (!expiryDigits || expiryDigits.length !== 4) {
                    validationErrors.cardExpiry = 'Data de validade é obrigatória';
                } else if (!isValidExpiry(expiryDigits)) {
                    validationErrors.cardExpiry = 'Data de validade inválida ou expirada';
                }

                // Validate CVV
                const cvvLength = state.detectedBrand === 'amex' ? 4 : 3;
                if (!iPag?.validateCVV(state.cardCvv, state.detectedBrand)) {
                    validationErrors.cardCvv = `CVV deve ter ${cvvLength} dígitos`;
                }

                // Extract CPF digits (always, for return data)
                const cpfDigits = state.document.replace(DIGITS_ONLY, '');

                // Validate CPF (if not disabled)
                if (settings.disable_card_cpf !== 'yes') {
                    if (!cpfDigits || cpfDigits.length !== 11) {
                        validationErrors.document = 'CPF é obrigatório';
                    } else if (!isCpf(cpfDigits)) {
                        validationErrors.document = 'CPF inválido';
                    }
                }

                // Validate installments
                if (isNaN(state.installments)) {
                    validationErrors.installments = 'Selecione o número de parcelas';
                }

                if (Object.keys(validationErrors).length > 0) {
                    setErrors(validationErrors);
                    resolve({
                        type: emitResponse.responseTypes.ERROR,
                        message: 'Por favor, corrija os erros no formulário.',
                        messageContext: emitResponse.noticeContexts.PAYMENTS,
                    });

                    return;
                }

                setErrors({});

                const paymentMethodData = {
                    ipag_woo_payments_blocks: 'yes',
                    ipag_credito_card_cpf: cpfDigits,
                    ipag_credito_card_cvv: state.cardCvv,
                    ipag_credito_card_num: state.cardNumber,
                    ipag_credito_card_name: state.cardName,
                    ipag_credito_card_expiry: state.cardExpiry,
                    ipag_credito_card_type: state.detectedBrand,
                    ipag_credito_installments: state.installments,
                    ipag_check_save_card: state.saveCardChecked ? 'yes' : 'no',
                };

                let finalPaymentMethodData = paymentMethodData;

                const applyPayloadOverrides = (detail) => {
                    if (!detail || typeof detail !== 'object') {
                        return;
                    }

                    if (detail.paymentMethodData && typeof detail.paymentMethodData === 'object') {
                        finalPaymentMethodData = {
                            ...finalPaymentMethodData,
                            ...flattenToPaymentData(detail.paymentMethodData),
                        };
                        return;
                    }

                    finalPaymentMethodData = {
                        ...finalPaymentMethodData,
                        ...flattenToPaymentData(detail),
                    };
                };

                let timeoutId = null;
                let pendingCount = 0;

                const finish = (result) => {
                    if (timeoutId) {
                        clearTimeout(timeoutId);
                        timeoutId = null;
                    }

                    window.ipagCheckoutObservers?.emit('paymentClosed', {
                        type: result?.type || '',
                        paymentMethodData: finalPaymentMethodData,
                        details: result,
                    });

                    resolve(result);
                };

                const observerResults = window.ipagCheckoutObservers?.emitAsync(
                    'paymentSetup',
                    {
                        paymentMethodData,
                        checkoutSnapshot,
                    },
                ) || [];

                const asyncTasks = [];

                observerResults.forEach((result) => {
                    if (!result) {
                        return;
                    }

                    if (typeof result.then === 'function') {
                        pendingCount += 1;
                        asyncTasks.push(
                            result
                                .then((detail) => {
                                    applyPayloadOverrides(detail);
                                })
                                .catch((error) => {
                                    console.warn('paymentSetup observer failed', error);
                                }),
                        );
                        return;
                    }

                    applyPayloadOverrides(result);
                });

                if (pendingCount === 0) {
                    finish({
                        type: emitResponse.responseTypes.SUCCESS,
                        meta: { paymentMethodData: finalPaymentMethodData },
                    });
                    return;
                }

                timeoutId = setTimeout(() => {
                    finish({
                        type: emitResponse.responseTypes.ERROR,
                        message: 'Ocorreu um erro durante o processamento do pagamento. Por favor, tente novamente.',
                        messageContext: emitResponse.noticeContexts.PAYMENTS,
                    });
                }, 5 * 60 * 1000); // 5 minutes timeout to prevent hanging in case of issues with subscribers

                Promise.allSettled(asyncTasks).then(() => {
                    finish({
                        type: emitResponse.responseTypes.SUCCESS,
                        meta: { paymentMethodData: finalPaymentMethodData },
                    });
                });
            });
        });

        return unsubscribe;
    }, [
        onPaymentSetup,
        emitResponse.responseTypes.SUCCESS,
        emitResponse.responseTypes.ERROR,
        emitResponse.noticeContexts.PAYMENTS,
        cardNumber,
        cardName,
        cardExpiry,
        cardCvv,
        document,
        detectedBrand,
        installments,
        saveCardChecked,
        checkoutSnapshot,
    ]);

    // Build installment options from backend data
    const installmentOptions = (settings.installmentOptions || []).map((opt) =>
        createElement('option', { key: opt.value, value: opt.value }, opt.label),
    );

    // Update card number preview
    const handleCardNumberChange = (e) => {
        const raw = (e.target.value || '').replace(DIGITS_ONLY, '').slice(0, 16);
        setCardNumber(raw);
        if (errors.cardNumber) {
            setErrors((prev) => ({ ...prev, cardNumber: '' }));
        }

        const brand = detectBrand(raw);

        setDetectedBrand(brand);
    };

    // Update cardholder name preview
    const handleCardNameChange = (e) => {
        setCardName(e.target.value);
        if (errors.cardName) {
            setErrors((prev) => ({ ...prev, cardName: '' }));
        }
    };

    // Update expiry preview
    const handleExpiryChange = (e) => {
        let raw = (e.target.value || '').replace(DIGITS_ONLY, '');

        if (raw.length === 6 && raw[2] === '2' && raw[3] === '0') {
            const part1 = raw.slice(0, 2);
            const part2 = raw.slice(4);

            const combined = part1 + part2;
            raw = combined;
        }

        raw = raw.slice(0, 4);

        if (errors.cardExpiry) {
            setErrors((prev) => ({ ...prev, cardExpiry: '' }));
        }
        const currentYY = new Date().getFullYear() % 100;

        let mm = raw.slice(0, 2);
        let yy = raw.slice(2, 4);

        if (mm.length === 2) {
            const mmNum = Math.min(12, Math.max(1, parseInt(mm, 10) || 1));
            mm = String(mmNum).padStart(2, '0');
        }

        if (yy.length === 2) {
            const yyNum = parseInt(yy, 10);
            yy = String(Math.max(yyNum, currentYY)).padStart(2, '0');
        }

        const formatted = yy.length > 0 ? `${mm} / ${yy}` : mm;
        setCardExpiry(formatted);
    };

    // Update CVV preview
    const handleCvvChange = (e) => {
        const value = e.target.value;
        setCardCvv(value);
        if (errors.cardCvv) {
            setErrors((prev) => ({ ...prev, cardCvv: '' }));
        }
    };

    const handleDocumentInput = (e) => {
        const v = String(e.target.value).replace(/\D/g, '');
        if (errors.document) {
            setErrors((prev) => ({ ...prev, document: '' }));
        }

        if (v.length > 11) {
            setDocument(window.maskCnpj(v));
            return;
        }

        setDocument(window.maskCpf(v));
    };

    const handleInstallmentsChange = (e) => {
        setInstallments(e.target.value);
        if (errors.installments) {
            setErrors((prev) => ({ ...prev, installments: '' }));
        }
    };

    const handleSaveCardChange = (e) => {
        setSaveCardChecked(!!e.target.checked);
    };

    return createElement(
        'div',
        { className: 'ipag-gateway-credit-form' },
        createElement(
            'div',
            { className: 'ipag-card-option' },
            createElement(
                'div',
                { className: 'ipag-card-form-fields' },
                // Card preview
                settings.disable_card_fill_preview !== 'yes' &&
                createElement(
                    'div',
                    { id: 'card_wrapper', className: 'card_wrapper' },
                    createElement(
                        'div',
                        {
                            id: 'card_container',
                            className:
                                'card_container' +
                                (focusedField ? ' has-focus' : '') +
                                (detectedBrand ? ` brand-${detectedBrand}` : ''),
                        },
                        createElement(
                            'div',
                            {
                                className:
                                    'ipag-card-number' +
                                    (focusedField === 'number'
                                        ? ' is-focused'
                                        : focusedField
                                            ? ' is-dimmed'
                                            : ''),
                            },
                            formatMaskedNumber(cardNumber) || '••••  ••••  ••••  ••••',
                        ),
                        createElement(
                            'div',
                            {
                                className:
                                    'ipag-card-name' +
                                    (focusedField === 'name'
                                        ? ' is-focused'
                                        : focusedField
                                            ? ' is-dimmed'
                                            : ''),
                            },
                            cardName.toUpperCase() || 'TITULAR DO CARTÃO',
                        ),
                        createElement(
                            'div',
                            {
                                className:
                                    'ipag-card-expiry' +
                                    (focusedField === 'expiry'
                                        ? ' is-focused'
                                        : focusedField
                                            ? ' is-dimmed'
                                            : ''),
                            },
                            createElement(
                                'span',
                                { className: 'card-expiry-month' },
                                expiryMonthDisplay,
                            ),
                            ' / ',
                            createElement(
                                'span',
                                { className: 'card-expiry-year' },
                                expiryYearDisplay,
                            ),
                        ),
                        createElement(
                            'span',
                            {
                                className:
                                    'ipag-card-cvv' +
                                    (focusedField === 'cvv'
                                        ? ' is-focused'
                                        : focusedField
                                            ? ' is-dimmed'
                                            : ''),
                            },
                            cvvDisplay,
                        ),
                    ),
                    acceptedBrandItems.length > 0 &&
                    createElement(
                        'div',
                        { className: 'ipag-accepted-brands' },
                        createElement(
                            'ul',
                            {
                                className:
                                    'ipag-accepted-brands-list' +
                                    (selectedBrandKey ? ' has-selected' : ''),
                            },
                            acceptedBrandItems,
                        ),
                    ),
                ),
                // Card number input
                createElement(
                    'p',
                    {
                        className:
                            'form-row' + (errors.cardNumber ? ' woocommerce-invalid' : ''),
                    },
                    createElement(
                        'label',
                        { htmlFor: 'ipag_credito_card_num' },
                        'Número do Cartão ',
                        createElement(
                            'abbr',
                            { className: 'required', title: 'Digite o número do cartão' },
                            '*',
                        ),
                    ),
                    createElement(
                        'div',
                        { className: 'ipag-input-with-icon' },
                        createElement('input', {
                            type: 'text',
                            name: 'ipag_credito_card_num',
                            id: 'ipag_credito_card_num',
                            maxLength: 19,
                            className:
                                'input-text input-ipag' +
                                (errors.cardNumber ? ' woocommerce-invalid' : ''),
                            placeholder: '•••• •••• •••• ••••',
                            autoComplete: 'off',
                            inputMode: 'numeric',
                            value: formatCardNumberInput(cardNumber),
                            onInput: handleCardNumberChange,
                            onFocus: () => setFocusedField('number'),
                            onBlur: () => setFocusedField(''),
                        }),
                        createElement('img', {
                            src: brandLogoUrl,
                            id: 'ipag_credito_card_type_icon',
                            className: 'ipag-card-brand',
                            alt: 'Card brand',
                            style: { display: detectedBrand ? 'block' : 'none', bottom: '50%', transform: 'translateY(50%)' },
                        }),
                    ),
                    errors.cardNumber &&
                    createElement(
                        'span',
                        { className: 'woocommerce-error', role: 'alert' },
                        errors.cardNumber,
                    ),
                ),
                // Cardholder name
                createElement(
                    'p',
                    {
                        className:
                            'form-row' + (errors.cardName ? ' woocommerce-invalid' : ''),
                    },
                    createElement(
                        'label',
                        { htmlFor: 'ipag_credito_card_name' },
                        'Titular do Cartão ',
                        createElement(
                            'abbr',
                            { className: 'required', title: 'Digite o nome do titular' },
                            '*',
                        ),
                    ),
                    createElement('input', {
                        type: 'text',
                        name: 'ipag_credito_card_name',
                        placeholder: 'Maria da Silva',
                        id: 'ipag_credito_card_name',
                        className:
                            'input-text input-ipag' +
                            (errors.cardName ? ' woocommerce-invalid' : ''),
                        autoComplete: 'cc-name',
                        value: cardName,
                        onChange: handleCardNameChange,
                        onFocus: () => setFocusedField('name'),
                        onBlur: () => setFocusedField(''),
                    }),
                    errors.cardName &&
                    createElement(
                        'span',
                        { className: 'woocommerce-error', role: 'alert' },
                        errors.cardName,
                    ),
                ),
                // Expiry and CVV in flex row
                createElement(
                    'div',
                    { className: 'form-row row-flex' },
                    createElement(
                        'div',
                        {
                            className:
                                'ipag-expiry-col' +
                                (errors.cardExpiry ? ' woocommerce-invalid' : ''),
                        },
                        createElement(
                            'label',
                            { htmlFor: 'ipag_credito_card_expiry' },
                            'Validade (MM/AA) ',
                            createElement('abbr', { className: 'required' }, '*'),
                        ),
                        createElement('input', {
                            type: 'tel',
                            name: 'ipag_credito_card_expiry',
                            id: 'ipag_credito_card_expiry',
                            className:
                                'input-text input-ipag half-fill' +
                                (errors.cardExpiry ? ' woocommerce-invalid' : ''),
                            placeholder: 'MM / AA',
                            autoComplete: 'cc-exp',
                            inputMode: 'numeric',
                            maxLength: 7,
                            value: cardExpiry,
                            onInput: handleExpiryChange,
                            onFocus: () => setFocusedField('expiry'),
                            onBlur: () => setFocusedField(''),
                        }),
                        errors.cardExpiry &&
                        createElement(
                            'span',
                            {
                                className: 'woocommerce-error',
                                role: 'alert',
                                style: { fontSize: '0.85em' },
                            },
                            errors.cardExpiry,
                        ),
                    ),
                    createElement(
                        'div',
                        {
                            className:
                                'ipag-cvv-col' + (errors.cardCvv ? ' woocommerce-invalid' : ''),
                        },
                        createElement(
                            'label',
                            { htmlFor: 'ipag_credito_card_cvv' },
                            'CVV ',
                            createElement('abbr', { className: 'required' }, '*'),
                        ),
                        createElement('input', {
                            id: 'ipag_credito_card_cvv',
                            name: 'ipag_credito_card_cvv',
                            className:
                                'input-text input-ipag wc-credit-card-form-card-cvc' +
                                (errors.cardCvv ? ' woocommerce-invalid' : ''),
                            type: 'tel',
                            maxLength: 4,
                            autoComplete: 'cc-csc',
                            placeholder: '•••',
                            inputMode: 'numeric',
                            value: cardCvv,
                            onInput: handleCvvChange,
                            onFocus: () => setFocusedField('cvv'),
                            onBlur: () => setFocusedField(''),
                        }),
                        errors.cardCvv &&
                        createElement(
                            'span',
                            {
                                className: 'woocommerce-error',
                                role: 'alert',
                                style: { fontSize: '0.85em' },
                            },
                            errors.cardCvv,
                        ),
                    ),
                ),
                // CPF (if not disabled)
                settings.disable_card_cpf !== 'yes' &&
                createElement(
                    'p',
                    {
                        className:
                            'form-row' + (errors.document ? ' woocommerce-invalid' : ''),
                    },
                    createElement(
                        'label',
                        { htmlFor: 'ipag_credito_card_cpf' },
                        'CPF do Portador ',
                        createElement('abbr', { className: 'required' }, '*'),
                    ),
                    createElement('input', {
                        type: 'text',
                        name: 'ipag_credito_card_cpf',
                        id: 'ipag_credito_card_cpf',
                        maxLength: 14,
                        className:
                            'box-fill input-ipag' +
                            (errors.document ? ' woocommerce-invalid' : ''),
                        placeholder: '•••.•••.•••.••',
                        inputMode: 'numeric',
                        value: document,
                        onInput: handleDocumentInput,
                    }),
                    errors.document &&
                    createElement(
                        'span',
                        { className: 'woocommerce-error', role: 'alert' },
                        errors.document,
                    ),
                ),
                // Installments
                createElement(
                    'p',
                    {
                        className:
                            'form-row' + (errors.installments ? ' woocommerce-invalid' : ''),
                    },
                    createElement(
                        'label',
                        { htmlFor: 'ipag_credito_installments' },
                        'Número de Parcelas ',
                        createElement('abbr', { className: 'required' }, '*'),
                    ),
                    createElement(
                        'select',
                        {
                            id: 'ipag_credito_installments',
                            name: 'ipag_credito_installments',
                            className:
                                'select_field select-ipag box-fill' +
                                (errors.installments ? ' woocommerce-invalid' : ''),
                            value: installments,
                            onChange: handleInstallmentsChange,
                        },
                        installmentOptions,
                    ),
                    errors.installments &&
                    createElement(
                        'span',
                        { className: 'woocommerce-error', role: 'alert' },
                        errors.installments,
                    ),
                ),
                // Save card checkbox
                settings.allow_saved_cards &&
                createElement(
                    'div',
                    {
                        className: 'form-row wc-block-components-checkbox',
                        style: { marginBottom: '.5rem' },
                    },
                    createElement(
                        'label',
                        {
                            htmlFor: 'ipag_check_save_card',
                            className: 'checkbox-control',
                        },
                        createElement('input', {
                            id: 'ipag_check_save_card',
                            className:
                                'wc-block-components-checkbox__input ipag-check-save-card check-ipag',
                            type: 'checkbox',
                            name: 'ipag_check_save_card',
                            value: '1',
                            checked: saveCardChecked,
                            onChange: handleSaveCardChange,
                            'aria-invalid': 'false',
                        }),
                        createElement(
                            'svg',
                            {
                                className: 'wc-block-components-checkbox__mark',
                                viewBox: '0 0 24 24',
                                'aria-hidden': 'true',
                            },
                            createElement('path', {
                                fill: 'currentColor',
                                d: 'M20.29 5.71a1 1 0 10-1.41-1.41L9 14.59 5.12 10.7A1 1 0 103.7 12.12L8.59 17a1 1 0 001.41 0L20.29 5.71z',
                            }),
                        ),
                        createElement(
                            'span',
                            { className: 'wc-block-components-checkbox__label' },
                            settings.save_card_checkbox_label,
                        ),
                    ),
                ),
                // Hidden inputs
                createElement('input', {
                    type: 'hidden',
                    className: 'ipag_helper_cart_total',
                    value: settings.cart_total,
                }),
                // Array.from(settings.cart_products || []).forEach((product, index) => {
                //     createElement('input', { type: 'hidden', name: `ipag_helper_product[${index}][name]`, value: product.name });
                //     createElement('input', { type: 'hidden', name: `ipag_helper_product[${index}][price_cents]`, value: product.price_cents });
                //     createElement('input', { type: 'hidden', name: `ipag_helper_product[${index}][quantity]`, value: product.quantity });
                //     createElement('input', { type: 'hidden', name: `ipag_helper_product[${index}][id]`, value: product.id });
                //     createElement('input', { type: 'hidden', name: `ipag_helper_product[${index}][sku]`, value: product.sku });
                //     createElement('input', { type: 'hidden', name: `ipag_helper_product[${index}][description]`, value: product.description });
                // }),
                // ...(settings.cart_products || []).map((product, index) =>
                //     [
                //         createElement('input', { type: 'hidden', name: `ipag_helper_product[${index}][name]`, value: product.name }),
                //         createElement('input', { type: 'hidden', name: `ipag_helper_product[${index}][price_cents]`, value: product.price_cents }),
                //         createElement('input', { type: 'hidden', name: `ipag_helper_product[${index}][quantity]`, value: product.quantity }),
                //         createElement('input', { type: 'hidden', name: `ipag_helper_product[${index}][id]`, value: product.id }),
                //         createElement('input', { type: 'hidden', name: `ipag_helper_product[${index}][sku]`, value: product.sku }),
                //         createElement('input', { type: 'hidden', name: `ipag_helper_product[${index}][description]`, value: product.description }),
                //     ]
                createElement(
                    'div',
                    {},
                    Array.from(settings.cart_products || []).map((product, index) => [
                        createElement('input', {
                            type: 'hidden',
                            name: `ipag_helper_product[${index}][name]`,
                            value: product.name,
                        }),
                        createElement('input', {
                            type: 'hidden',
                            name: `ipag_helper_product[${index}][price_cents]`,
                            value: product.price_cents,
                        }),
                        createElement('input', {
                            type: 'hidden',
                            name: `ipag_helper_product[${index}][quantity]`,
                            value: product.quantity,
                        }),
                        createElement('input', {
                            type: 'hidden',
                            name: `ipag_helper_product[${index}][id]`,
                            value: product.id,
                        }),
                        createElement('input', {
                            type: 'hidden',
                            name: `ipag_helper_product[${index}][sku]`,
                            value: product.sku,
                        }),
                        createElement('input', {
                            type: 'hidden',
                            name: `ipag_helper_product[${index}][description]`,
                            value: product.description,
                        }),
                    ]),
                ),
            ),
        ),
    );
};

const canMakePayment = () => true;

const IpagGatewayPaymentMethod = {
    name: 'ipag-gateway',
    label: createElement(Label),
    content: createElement(Content),
    edit: createElement(Content),
    savedTokenComponent: createElement(SavedTokenComponent),
    canMakePayment,
    ariaLabel: labelText,
    supports: {
        ...(settings.supports || {}),
        showSavedCards: allow_saved_cards_enabled,
    },
};

registerPaymentMethod(IpagGatewayPaymentMethod);
