const { createElement, useState, useEffect } = wp.element;
const { registerBlockType } = wp.blocks;
const { TextControl, SelectControl, Notice } = wp.components;
const { useSelect, useDispatch, subscribe, select } = wp.data;
const { sprintf } = wp.i18n;

const popBlockData = window.PopCheckoutData || {};
const invoiceConfig = window.wc_el_inv_invoice || {};
const adminConfig = window.wc_el_inv_admin || {};
const popBlockMessages = popBlockData.pop_block_message || invoiceConfig.pop_block_message || {
    required: 'The "%s" field is required.',
    vat_tax__length: 'The "%s" field must be at least 6 characters long.',
    sdi_length: 'The "%s" field must be 7 characters long.',
    min_length: 'The "%s" field must be at least 3 characters long.',
};
const frontFieldsPosition = invoiceConfig.wc_fields_pos || popBlockData.wc_fields_pos || 'bottom';
const editorFieldsPosition = adminConfig.wc_fields_pos || popBlockData.wc_fields_pos || 'bottom';

function getLegacyFieldId(fieldOrId) {
    const rawId = typeof fieldOrId === 'string' ? fieldOrId : (fieldOrId?.legacy_id || fieldOrId?.id || '');
    if (rawId.indexOf('pop/') === 0) {
        return rawId.substring(4);
    }
    return rawId;
}

function getDomSafeFieldId(fieldId) {
    return String(fieldId || '').replace(/[^a-zA-Z0-9_-]/g, '_');
}

if (typeof wp !== 'undefined' && wp.data && wp.data.select('core/block-editor')) {
    var initialized = false;
    const unsubscribe = subscribe(() => {
        const blocks = wp.data.select('core/block-editor').getBlocks();

        // ignore the first renders until the blocks are loaded
        if (!initialized && blocks.length > 0) {
            initialized = true;
            return;
        }

        const blockExists = blocks.some(block => block.name === 'wc/pop-checkout');
        if (!blockExists && initialized) {
            const popBlockEditor = document.querySelector('.pop-checkout-fields');
            if (popBlockEditor) {
                popBlockEditor.remove();
                console.log('POP Checkout Fields removed');
            }
        }
    });
}

// Simple validation function
function validateField(field, value)
{
    const fieldId = getLegacyFieldId(field);

    if (field.required && (!value || value.trim() === '')) {
        return sprintf(popBlockMessages.required, field.label);
    }

    if (('billing_vat_number' === fieldId || 'billing_tax_code' === fieldId) && value && value.length < 6) {
        return sprintf(popBlockMessages.vat_tax__length, field.label);
    }

    if ('billing_sdi_type' === fieldId && value && value.length < 7) {
        return sprintf(popBlockMessages.sdi_length, field.label);
    }

    if (field.type === 'text' && value && value.length < 3) {
        return sprintf(popBlockMessages.min_length, field.label);
    }
    return null;
}

// React component for fields
function PopCheckoutFields({ fields }) {
    const safeFields = Array.isArray(fields) ? fields : Object.values(fields || {});

    const additionalFields = useSelect(select => select('wc/store/checkout').getAdditionalFields() || {}, []);

    const { setAdditionalFields, __internalSetHasError } = useDispatch('wc/store/checkout');

    const [errors, setErrors] = useState({});

    // Set defaults at startup (if empty)
    useEffect(() => {
        let newAdditionalFields = { ...additionalFields };
        let updated = false;

        safeFields.forEach(field => {
            if (!field.id) {
                return;
            }

            const choiceField = safeFields.find(f => getLegacyFieldId(f) === 'billing_choice_type');
            const typeField = safeFields.find(f => getLegacyFieldId(f) === 'billing_invoice_type');
            const taxCodeField = safeFields.find(f => getLegacyFieldId(f) === 'billing_tax_code');
            const vatNumberField = safeFields.find(f => getLegacyFieldId(f) === 'billing_vat_number');
            const sdiCodeField = safeFields.find(f => getLegacyFieldId(f) === 'billing_sdi_type');

            if (
                field.id &&
                (
                    newAdditionalFields[field.id] === undefined ||
                    newAdditionalFields[field.id] === null ||
                    newAdditionalFields[field.id] === ''
                ) &&
                field.default !== undefined &&
                field.default !== ''
            ) {
                newAdditionalFields[field.id] = field.default;
                updated = true;
            }

            const choiceValue = choiceField ? (newAdditionalFields[choiceField.id] || choiceField.value || choiceField.default || '') : '';
            const typeValue = typeField ? (newAdditionalFields[typeField.id] || typeField.value || typeField.default || '') : '';
            const taxCodeValue = taxCodeField ? (newAdditionalFields[taxCodeField.id] || taxCodeField.value || taxCodeField.default || '') : '';

            if (choiceField && typeField && 'receipt' === choiceValue) {
                newAdditionalFields[typeField.id] = 'private';
                updated = true;
            }

            if (typeField && 'private' === typeValue && taxCodeField && taxCodeValue) {
                newAdditionalFields[taxCodeField.id] = taxCodeValue;
                if (sdiCodeField) {
                    newAdditionalFields[sdiCodeField.id] = '';
                }
                if (vatNumberField) {
                    newAdditionalFields[vatNumberField.id] = '';
                }
                updated = true;
            } else if (typeField && 'private' !== typeValue) {
                if (taxCodeField) {
                    newAdditionalFields[taxCodeField.id] = taxCodeValue;
                }
                if (sdiCodeField) {
                    newAdditionalFields[sdiCodeField.id] = newAdditionalFields[sdiCodeField.id] || sdiCodeField?.value || sdiCodeField?.default || '';
                }
                if (vatNumberField) {
                    newAdditionalFields[vatNumberField.id] = newAdditionalFields[vatNumberField.id] || vatNumberField?.value || vatNumberField?.default || '';
                }
                updated = true;
            }
        });

        if (updated) {
            setAdditionalFields(newAdditionalFields);
        }
    }, []);

    // Block submit if there are errors
    useEffect(() => {
        const hasErrors = Object.values(errors).some(Boolean);
        if (hasErrors) {
            __internalSetHasError('custom_validation', 'Ci sono errori nei campi personalizzati.');
        } else {
            __internalSetHasError('custom_validation', null);
        }
    }, [errors]);

    // When a field changes
    function onChangeField(id, val) {
        const newAdditionalFields = { ...additionalFields, [id]: val };
        setAdditionalFields(newAdditionalFields);

        // Immediate validation
        const field = safeFields.find(f => f.id === id);
        const errorMsg = validateField(field, val);

        setErrors(prev => ({ ...prev, [id]: errorMsg }));

        if (errorMsg) {
            __internalSetHasError(id, errorMsg);
        } else {
            __internalSetHasError(id, null);
        }
    }

    if (!safeFields.length) {
        return createElement('p', null, 'No fields configured.');
    }

    return createElement('div', { className: 'pop-checkout-fields' },
        safeFields.map(field => {
            if (!field.id) return null;
            const fieldError = errors[field.id];
            const legacyId = getLegacyFieldId(field);
            const wrapperId = getDomSafeFieldId(field.id);
            const domFieldId = legacyId || wrapperId;
            const domWrapperId = `${domFieldId}_field`;
            const domFieldClass = `${(legacyId || wrapperId)}_field`;

            if (field.type === 'select') {
                const options = Object.entries(field.options || {}).map(([value, label]) => ({ value, label }));
                return createElement('div', { key: field.id, className: domFieldClass, id: domWrapperId },
                    createElement(SelectControl, {
                        id: domFieldId,
                        name: field.id,
                        label: field.label,
                        options: options,
                        value: additionalFields[field.id] || additionalFields[legacyId] || field.default || '',
                        onChange: val => onChangeField(field.id, val),
                        required: !!field.required,
                    }),
                    fieldError && createElement(Notice, { status: 'error', isDismissible: false }, fieldError)
                );
            }

            if (field.type === 'text') {
                return createElement('div', { key: field.id, className: domFieldClass, id: domWrapperId },
                    createElement(TextControl, {
                        id: domFieldId,
                        name: field.id,
                        label: field.label,
                        value: additionalFields[field.id] || additionalFields[legacyId] || field.default || '',
                        placeholder: field.placeholder || '',
                        onChange: val => onChangeField(field.id, val),
                        required: !!field.required,
                    }),
                    fieldError && createElement(Notice, { status: 'error', isDismissible: false }, fieldError)
                );
            }

            return null;
        })
    );
}

const EditComponent = ( props ) => {
    const fields = window.PopCheckoutData?.fields || [];
    return createElement('div', { className: 'pop-checkout-root' },
        createElement('h3', {}, 'POP Checkout Fields'),
        createElement('pre', {}, JSON.stringify(fields, null, 2))
    );
};

registerBlockType('wc/pop-checkout', {
    title: 'POP Checkout Fields',
    icon: 'cart',
    category: 'woocommerce',
    attributes: {
        fields: {
            type: 'array',
            default: [],
        },
    },
    edit: function (props) {
        const fields = window.PopCheckoutData?.fields || [];
        return createElement(PopCheckoutFields, { fields });
    },
    save: function () {
        return null;
    }
});

// Mount the React block in the frontend (checkout)
document.addEventListener('DOMContentLoaded', () => {
    const root = document.getElementById('pop-checkout-root');
    if (root) {
        const fields = JSON.parse(root.getAttribute('data-fields') || '[]');
        const { render, createElement } = wp.element;
        render(createElement(PopCheckoutFields, { fields }), root);
    }

    const observer = new MutationObserver(() => {
        const wcBillingEditorFields = document.querySelector('.wc-block-checkout__shipping-fields');
        const wcBillingFields = document.querySelector('.wc-block-checkout__billing-fields');

        const popBlockEditor = document.querySelector('.pop-checkout-fields');
        const popBlockWrap = document.getElementById('pop-checkout');
        const popBlock = document.getElementById('pop-checkout-root');

        if (wcBillingFields && popBlock && !wcBillingFields.contains(popBlock)) {
            var pos = frontFieldsPosition;
            popBlock.classList.add('pop_fields_pos_' + pos);
            if ("bottom" === frontFieldsPosition) {
                wcBillingFields.appendChild(popBlockWrap);
            } else if ("top" === frontFieldsPosition) {
                wcBillingFields.insertBefore(popBlockWrap, wcBillingFields.firstChild);
            }
        }
        if (wcBillingEditorFields && popBlockEditor && !wcBillingEditorFields.contains(popBlockEditor)) {
            var pos = editorFieldsPosition;
            popBlockEditor.classList.add('pop_fields_pos_' + pos);
            if ("bottom" === editorFieldsPosition) {
                wcBillingEditorFields.appendChild(popBlockEditor);
            } else if ("top" === editorFieldsPosition) {
                wcBillingEditorFields.insertBefore(popBlockEditor, wcBillingEditorFields.firstChild);
            }
        }
    });
    observer.observe(document.body, { childList: true, subtree: true });
});
