define([
    'jquery',
    'PortalPeople_DisabledPostcodes/js/model/postcode-validator'
], function ($, postcodeValidator) {
    'use strict';

    var FIELD_SELECTOR = '[name*="postcode"]';
    var NEXT_SELECTOR = [
        '.checkout-shipping-method .action.continue',
        '.button.action.continue.primary',
        '.checkout-shipping-method button.continue',
        '.checkout-shipping-method .actions-toolbar button',
        'button[data-role="opc-continue"]'
    ].join(', ');
    var FIELD_MESSAGE_CLASS = 'portalpeople-disabled-postcode-message';
    var CHECKOUT_MESSAGE_CLASS = 'portalpeople-disabled-postcode-checkout-message';
    var FALLBACK_MESSAGE = 'We are sorry, we do not deliver to this area.';

    function isCheckoutPage() {
        return window.location.pathname.indexOf('/checkout') !== -1;
    }

    function getPostcode() {
        var value = $(FIELD_SELECTOR).first().val();
        return value ? String(value).trim() : '';
    }

    function setMessage(message, blocked) {
        var $field = $(FIELD_SELECTOR).first();
        var $container = $field.closest('.field');
        var $fieldMsg = $('.' + FIELD_MESSAGE_CLASS);
        var $next = $(NEXT_SELECTOR);
        var $checkoutMsg = $('.' + CHECKOUT_MESSAGE_CLASS);
        var $anchor = $next.first().closest('.actions-toolbar');

        if (!$anchor.length) {
            $anchor = $('.checkout-shipping-method');
        }

        if (blocked) {
            $field.addClass('mage-error').attr('aria-invalid', 'true');
            if (!$fieldMsg.length && $container.length) {
                $('<div/>', {
                    'class': 'portalpeople-postcode-error ' + FIELD_MESSAGE_CLASS,
                    text: message
                }).appendTo($container);
            } else {
                $fieldMsg.text(message).show();
            }
            // Ensure the message remains visible
            $fieldMsg.css('display', 'block');

            if (!$checkoutMsg.length && $anchor.length) {
                $('<div/>', {
                    'class': 'portalpeople-postcode-error portalpeople-postcode-error-checkout ' + CHECKOUT_MESSAGE_CLASS,
                    text: message + ' Please change your postcode to continue checkout.'
                }).appendTo($anchor);
            } else {
                $checkoutMsg.text(message + ' Please change your postcode to continue checkout.').show();
            }

            $next.prop('disabled', true).attr('aria-disabled', 'true');
        } else {
            $field.removeClass('mage-error').removeAttr('aria-invalid');
            if ($fieldMsg.length) {
                $fieldMsg.hide(); // Optional: Comment this line to keep the message visible even when unblocked
            }
            $checkoutMsg.remove();
            $next.prop('disabled', false).removeAttr('aria-disabled');
        }
    }

    function getConfig() {
        if (window.checkoutConfig && window.checkoutConfig.portalpeopleDisabledPostcodes) {
            return window.checkoutConfig.portalpeopleDisabledPostcodes;
        }

        // Fallback protects checkout behavior if checkoutConfig key is unavailable during render timing.
        return {
            enabled: true,
            exact: [],
            areas: ['BN26'],
            message: FALLBACK_MESSAGE
        };
    }

    function checkPostcode() {
        var $field = $(FIELD_SELECTOR).first();
        var config = getConfig();
        var message = config.message || FALLBACK_MESSAGE;

        // If the field isn't in the DOM at all (e.g. Knockout mid re-render), do nothing.
        // Only clear messages when the field exists but has no/empty value.
        if (!$field.length) {
            return;
        }

        var postcode = $field.val() ? String($field.val()).trim() : '';

        if (!postcode) {
            setMessage(FALLBACK_MESSAGE, false);
            return;
        }

        setMessage(message, postcodeValidator.isExcluded(postcode, config));
    }

    if (!isCheckoutPage()) {
        return;
    }

    $(document).on('input.portalpeopleDisabledPostcodesWatch change.portalpeopleDisabledPostcodesWatch blur.portalpeopleDisabledPostcodesWatch', FIELD_SELECTOR, function () {
        checkPostcode();
    });

    setInterval(function () {
        checkPostcode();
    }, 300);

    setTimeout(checkPostcode, 500);
});