/**
 * SimplyIN Account Section Component
 * Global component that appears for all payment methods
 */
define([
    'uiComponent',
    'ko',
    'jquery',
    'Magento_Checkout/js/model/quote',
    'Simplyin_Payment/js/model/session-storage-manager',
    'Simplyin_Payment/js/model/country-data'
], function (Component, ko, $, quote, sessionStorageManager, countryData) {
    'use strict';

    return Component.extend({
        defaults: {
            template: 'Simplyin_Payment/checkout/simplyin-account-section',
            createSimplyInAccount: true,
            phoneNumber: '',
            selectedCountryCode: '+48',
            selectedCountryIso: 'PL',
            phoneNumberError: '',
            countryCodes: [],
            countryDropdownOpen: false,
            countrySearchQuery: '',
            filteredCountryCodes: [],
            isAuthenticated: false,
            isNewUser: true,
            showSection: true
        },

        /**
         * Get default value for create account checkbox from admin config
         * @returns {boolean}
         */
        getDefaultCreateAccountChecked: function () {
            if (window.checkoutConfig &&
                window.checkoutConfig.payment &&
                window.checkoutConfig.payment.simplyin_payment &&
                typeof window.checkoutConfig.payment.simplyin_payment.defaultCreateAccountChecked !== 'undefined') {
                return window.checkoutConfig.payment.simplyin_payment.defaultCreateAccountChecked;
            }
            return true; // fallback to checked if config not available
        },

        /**
         * Initialize component
         */
        initialize: function () {
            this._super();

            var self = this;

            // Initialize session storage manager
            sessionStorageManager.initialize();

            // Expose this component globally so mixins can access it
            window.simplyinAccountSection = this;

            // Check initial state
            this.updateVisibilityState();

            // Listen for auth state changes (when user logs in via popup)
            $(document).on('simplyin:auth_successful', function () {
                self.updateVisibilityState();
            });

            // Listen for email changes
            $(document).on('simplyin:email_changed', function () {
                self.updateVisibilityState();
            });

            // Listen for new user state changes
            $(document).on('simplyin:new_user_state_changed simplyin:showNewAccountOption', function () {
                self.updateVisibilityState();
            });

            // Poll for state changes periodically (backup)
            setInterval(function () {
                self.updateVisibilityState();
            }, 500);

            // ----------------------------------------------------------------
            // Auto-fill phoneNumber from the shipping address telephone field
            // ----------------------------------------------------------------

            /**
             * Extract digits-only number from a raw phone string.
             * Strips leading + or 00 international prefix and formatting chars.
             * e.g. "+919876543210" → "919876543210", "21324444" → "21324444"
             */
            function extractPhoneDigits(raw) {
                if (!raw) return '';
                var cleaned = String(raw).replace(/[\s\-\(\)\.]/g, '');
                if (cleaned.charAt(0) === '+') cleaned = cleaned.slice(1);
                else if (cleaned.indexOf('00') === 0) cleaned = cleaned.slice(2);
                return cleaned.replace(/\D/g, '');
            }

            // Flag: set to true when the customer manually types in the sly input
            // so auto-sync never overwrites their own entry afterwards
            self._userEditedPhone = false;

            /**
             * Sync telephone to the SimplyIN phone input.
             *
             * Priority:
             *   1. quote.shippingAddress().telephone  (authoritative Magento model)
             *   2. $('input[name="telephone"]').val() (DOM fallback)
             *
             * Always updates — so an early partial render can't get "stuck".
             * Stops updating once the customer manually edits the sly input.
             */
            function syncShippingPhone() {
                // Never run if section is hidden or customer already typed their own number
                if (!self.shouldShowNewAccountSection()) return;
                if (self._userEditedPhone) return;

                var raw = '';

                // --- Priority 1: Magento quote shippingAddress (authoritative) ---
                try {
                    var shippingAddr = quote.shippingAddress ? quote.shippingAddress() : null;
                    if (shippingAddr !== null &&
                        shippingAddr !== undefined &&
                        typeof shippingAddr === 'object' &&
                        shippingAddr.telephone !== null &&
                        shippingAddr.telephone !== undefined &&
                        String(shippingAddr.telephone).trim() !== '') {
                        raw = String(shippingAddr.telephone).trim();
                    }
                } catch (e) { /* quote not ready yet */ }

                // --- Priority 2: DOM input[name="telephone"] (fallback) ---
                if (!raw) {
                    try {
                        $('input[name="telephone"]').each(function () {
                            var v = $(this).val();
                            if (v && String(v).trim()) {
                                raw = String(v).trim();
                                return false; // break jQuery each
                            }
                        });
                    } catch (e) { /* DOM not ready yet */ }
                }

                if (!raw) return;

                var digits = extractPhoneDigits(raw);

                // Require at least 4 digits — avoids setting a single partial character
                if (!digits || digits.length < 4) return;

                // Only update if different from what is currently set
                if (self.phoneNumber() !== digits) {
                    self.phoneNumber(digits);
                    self.phoneNumberError('');
                }
            }

            // Mark as user-edited when customer manually types in the sly phone input
            // so auto-sync won't override it afterwards
            setTimeout(function () {
                var slyInput = document.querySelector('.simplyin-phone-number-input');
                if (slyInput) {
                    slyInput.addEventListener('input', function () {
                        self._userEditedPhone = true;
                    });
                }
            }, 1000);

            // Sync immediately after a short delay (Luma KO renders async)
            setTimeout(function () { syncShippingPhone(); }, 800);

            // Sync whenever Magento updates the shippingAddress KO observable
            quote.shippingAddress.subscribe(function () {
                // Small delay to let KO finish updating the address object
                setTimeout(function () { syncShippingPhone(); }, 300);
            });

            // Also sync on every DOM change to input[name="telephone"]
            // with retry loop to handle dynamic Luma rendering
            function attachDomPhoneListeners() {
                $('input[name="telephone"]').each(function () {
                    var field = $(this);
                    if (field.data('sly-sync-bound')) return;
                    field.data('sly-sync-bound', true);
                    field.on('blur change input', function () {
                        syncShippingPhone();
                    });
                });
            }

            attachDomPhoneListeners();
            var retries = 0;
            var retryTimer = setInterval(function () {
                retries++;
                attachDomPhoneListeners();
                syncShippingPhone();
                if (retries >= 20) clearInterval(retryTimer);
            }, 500);

            return this;
        },

        /**
         * Update visibility state based on auth and new user status
         */
        updateVisibilityState: function () {
            var authToken = sessionStorageManager.getAuthToken();
            var isAuth = authToken !== null && authToken !== '' && authToken.trim() !== '';
            var isNew = sessionStorageManager.isNewUser();

            // Update observables
            this.isAuthenticated(isAuth);
            this.isNewUser(isNew);

            // Calculate if section should show
            var shouldShow = !isAuth && isNew;

            if (this.showSection() !== shouldShow) {
                this.showSection(shouldShow);
            }
        },

        /**
         * Initialize observables
         */
        initObservable: function () {
            this._super()
                .observe([
                    'createSimplyInAccount',
                    'phoneNumber',
                    'selectedCountryCode',
                    'selectedCountryIso',
                    'phoneNumberError',
                    'countryCodes',
                    'countryDropdownOpen',
                    'countrySearchQuery',
                    'filteredCountryCodes',
                    'isAuthenticated',
                    'isNewUser',
                    'showSection'
                ]);

            var self = this;

            // Set default value for createSimplyInAccount from admin config
            this.createSimplyInAccount(this.getDefaultCreateAccountChecked());

            // Load country data
            this.countryCodes(countryData.getCountriesArray());
            this.filteredCountryCodes(this.countryCodes());

            // Set default country (Poland)
            this.selectedCountryIso('PL');
            this.selectedCountryCode('+48');

            // Watch for country search query changes
            this.countrySearchQuery.subscribe(function (query) {
                self.filterCountries(query);
            });

            // Watch for country ISO changes to update phone code
            this.selectedCountryIso.subscribe(function (isoCode) {
                if (isoCode) {
                    var phoneCode = countryData.getPhoneCode(isoCode);
                    if (phoneCode) {
                        self.selectedCountryCode(phoneCode);
                    }
                }
            });

            // Initialize dropdown after render
            setTimeout(function () {
                self.setupDropdownClickOutside();
            }, 500);

            return this;
        },

        /**
         * Check if should show the new account section
         * Uses the showSection observable for reactivity
         */
        shouldShowNewAccountSection: function () {
            return this.showSection();
        },

        /**
         * Get SimplyIN logo URL
         */
        getLogoUrl: function () {
            return window.checkoutConfig.payment.simplyin_payment ?
                window.checkoutConfig.payment.simplyin_payment.logoUrl : '';
        },

        /**
         * Get GDPR/Privacy Policy URL (locale-agnostic).
         * Backend resolves PL config -> EN config -> canonical fallback; the simply.in site self-localizes.
         */
        getGdprUrl: function () {
            if (window.checkoutConfig &&
                window.checkoutConfig.payment &&
                window.checkoutConfig.payment.simplyin_payment) {
                return window.checkoutConfig.payment.simplyin_payment.gdprUrl || 'https://simply.in/privacy-policy/';
            }
            return 'https://simply.in/privacy-policy/';
        },

        /**
         * Get Terms B2C URL (locale-agnostic).
         * Backend resolves PL config -> EN config -> canonical fallback; the simply.in site self-localizes.
         */
        getTermsB2cUrl: function () {
            if (window.checkoutConfig &&
                window.checkoutConfig.payment &&
                window.checkoutConfig.payment.simplyin_payment) {
                return window.checkoutConfig.payment.simplyin_payment.termsB2cUrl || 'https://simply.in/terms-b2c/';
            }
            return 'https://simply.in/terms-b2c/';
        },

        /**
         * Get Terms B2B URL based on store locale
         */
        getTermsB2bUrl: function () {
            if (window.checkoutConfig &&
                window.checkoutConfig.payment &&
                window.checkoutConfig.payment.simplyin_payment) {
                return window.checkoutConfig.payment.simplyin_payment.termsB2bUrl || 'https://www.simply.in/en/terms-b2b';
            }
            return 'https://www.simply.in/en/terms-b2b';
        },

        /**
         * Validate phone number
         */
        validatePhoneNumber: function () {
            if (!this.shouldShowNewAccountSection() || !this.createSimplyInAccount()) {
                return true;
            }

            var phone = this.phoneNumber().trim();

            if (!phone) {
                this.phoneNumberError('The phone number is required.');
                return false;
            }

            var phoneRegex = /^\d{6,15}$/;
            if (!phoneRegex.test(phone.replace(/[\s\-\(\)]/g, ''))) {
                this.phoneNumberError('Please enter a valid phone number.');
                return false;
            }

            this.phoneNumberError('');
            return true;
        },

        /**
         * Create SimplyIN account asynchronously
         */
        createSimplyInAccountAsync: function () {
            var self = this;
            var billingAddress = quote.billingAddress();
            var email = quote.guestEmail || (window.customerData && window.customerData.email);

            if (!email) {
                console.warn('SimplyIN: No email available for account creation');
                return;
            }

            var accountData = {
                email: email,
                firstName: billingAddress ? billingAddress.firstname : 'Customer',
                lastName: billingAddress ? billingAddress.lastname : 'User',
                phone: this.selectedCountryCode() + this.phoneNumber().trim()
            };

            // Store account creation data in session for later use
            sessionStorageManager.setItem('simplyin_pending_account', JSON.stringify(accountData));
        },

        /**
         * Toggle country dropdown
         */
        toggleCountryDropdown: function () {
            var isOpen = !this.countryDropdownOpen();
            this.countryDropdownOpen(isOpen);

            if (isOpen) {
                this.countrySearchQuery('');
                this.filteredCountryCodes(this.countryCodes());

                var self = this;
                setTimeout(function () {
                    var searchInput = document.querySelector('.simplyin-global-account-section .simplyin-country-search-input');
                    if (searchInput) {
                        searchInput.focus();
                    }
                }, 100);
            }
        },

        /**
         * Filter countries based on search query
         */
        filterCountries: function (query) {
            if (!query || query.trim() === '') {
                this.filteredCountryCodes(this.countryCodes());
                return;
            }

            var searchTerm = query.toLowerCase().trim();
            var filtered = this.countryCodes().filter(function (country) {
                var countryName = country.name.toLowerCase();
                var countryCode = country.code.toLowerCase();
                var countryIso = country.iso.toLowerCase();

                return countryName.indexOf(searchTerm) === 0 ||
                    countryName.indexOf(' ' + searchTerm) !== -1 ||
                    countryCode.indexOf(searchTerm) !== -1 ||
                    countryIso.indexOf(searchTerm) !== -1;
            });

            this.filteredCountryCodes(filtered);
        },

        /**
         * Handle keyboard navigation in country search
         */
        handleCountrySearchKeydown: function (data, event) {
            event.stopPropagation();

            if (event.keyCode === 13) {
                event.preventDefault();
                var filtered = this.filteredCountryCodes();
                if (filtered.length > 0) {
                    this.selectCountry(filtered[0]);
                }
                return false;
            }

            if (event.keyCode === 27) {
                event.preventDefault();
                this.countryDropdownOpen(false);
                return false;
            }

            return true;
        },

        /**
         * Select a country from dropdown
         */
        selectCountry: function (country) {
            this.selectedCountryIso(country.iso);
            this.selectedCountryCode(country.code);
            this.countryDropdownOpen(false);
            this.countrySearchQuery('');
        },

        /**
         * Get selected country flag path
         */
        getSelectedCountryFlag: function () {
            var countries = this.countryCodes();
            var selectedIso = this.selectedCountryIso();
            var country = countries.find(function (c) {
                return c.iso === selectedIso;
            });
            return country ? country.flagPath : '';
        },

        /**
         * Get selected country name (returns phone code for display)
         */
        getSelectedCountryName: function () {
            var countries = this.countryCodes();
            var selectedIso = this.selectedCountryIso();
            var country = countries.find(function (c) {
                return c.iso === selectedIso;
            });
            return country ? country.code : '';
        },

        /**
         * Setup click outside handler for dropdown
         */
        setupDropdownClickOutside: function () {
            var self = this;
            $(document).on('click', function (event) {
                var dropdown = $('.simplyin-global-account-section .simplyin-custom-dropdown');
                if (dropdown.length && !dropdown.is(event.target) && dropdown.has(event.target).length === 0) {
                    self.countryDropdownOpen(false);
                }
            });
        }
    });
});
