/**
 * SimplyIN Payment - 3D Secure Handler
 * Manages 3D Secure redirect flow (iframe and full-page)
 */
define([
    'jquery',
    'mage/translate',
    'Simplyin_Payment/js/payment/payment-status-poller'
], function ($, $t, paymentStatusPoller) {
    'use strict';

    return {
        /**
         * Iframe element for 3D Secure
         */
        iframeElement: null,

        /**
         * Iframe container element
         */
        iframeContainer: null,

        /**
         * Return URL after 3D Secure
         */
        returnUrl: null,

        /**
         * Payment ID being processed
         */
        paymentId: null,

        /**
         * Auth token for API calls
         */
        authToken: null,

        /**
         * Callback functions
         */
        callbacks: {
            onComplete: null,
            onCancel: null,
            onError: null
        },

        /**
         * Message listener reference
         */
        messageListener: null,

        /**
         * Handle 3D Secure redirect
         * @param {string} redirectUrl - URL to redirect to
         * @param {boolean} iframeAllowed - Whether iframe redirect is allowed
         * @param {Object} config - Configuration object
         * @returns {Promise}
         */
        handleRedirect: function (redirectUrl, iframeAllowed, config) {
            var self = this;

            // Store configuration
            this.paymentId = config.paymentId || '';
            this.authToken = config.authToken || '';
            this.returnUrl = config.returnUrl || window.location.href;

            if (config.callbacks) {
                this.callbacks = $.extend(this.callbacks, config.callbacks);
            }

            return new Promise(function (resolve, reject) {
                if (iframeAllowed) {
                    // Show 3D Secure in iframe within modal
                    self.showIframe(redirectUrl, resolve, reject);
                } else {
                    // Full page redirect
                    self.fullPageRedirect(redirectUrl, resolve, reject);
                }
            });
        },

        /**
         * Show 3D Secure page in iframe
         * @param {string} url - 3D Secure URL
         * @param {Function} resolve - Promise resolve
         * @param {Function} reject - Promise reject
         */
        showIframe: function (url, resolve, reject) {
            var self = this;

            // Create iframe container
            this.createIframeContainer();

            // Create iframe element
            this.iframeElement = document.createElement('iframe');
            this.iframeElement.id = 'simplyin-3ds-iframe';
            this.iframeElement.className = 'simplyin-3ds-iframe';
            this.iframeElement.src = url;
            this.iframeElement.setAttribute('frameborder', '0');
            this.iframeElement.setAttribute('allowfullscreen', 'true');
            this.iframeElement.setAttribute('allow', 'payment');

            // Add iframe to container
            var iframeWrapper = this.iframeContainer.querySelector('.simplyin-3ds-iframe-wrapper');
            iframeWrapper.appendChild(this.iframeElement);

            // Show container
            this.iframeContainer.style.display = 'block';

            // Set up message listener for completion
            this.setupMessageListener(resolve, reject);

            // Set up close button handler
            this.setupCloseHandler(reject);

            // Handle iframe load error
            this.iframeElement.onerror = function () {
                self.cleanup();
                reject({
                    code: 'IFRAME_LOAD_ERROR',
                    message: $t('Failed to load 3D Secure page')
                });
            };
        },

        /**
         * Create iframe container element
         */
        createIframeContainer: function () {
            // Remove existing container if present
            var existing = document.getElementById('simplyin-3ds-container');
            if (existing) {
                existing.remove();
            }

            // Create container
            this.iframeContainer = document.createElement('div');
            this.iframeContainer.id = 'simplyin-3ds-container';
            this.iframeContainer.className = 'simplyin-3ds-container';
            this.iframeContainer.innerHTML = `
                <div class="simplyin-3ds-overlay"></div>
                <div class="simplyin-3ds-modal">
                    <div class="simplyin-3ds-header">
                        <span class="simplyin-3ds-title">${$t('Secure Payment Verification')}</span>
                        <button type="button" class="simplyin-3ds-close" id="simplyin-3ds-close">
                            <span>&times;</span>
                        </button>
                    </div>
                    <div class="simplyin-3ds-iframe-wrapper">
                        <div class="simplyin-3ds-loading">
                            <div class="simplyin-spinner"></div>
                            <span>${$t('Loading secure verification...')}</span>
                        </div>
                    </div>
                </div>
            `;

            document.body.appendChild(this.iframeContainer);
        },

        /**
         * Set up message listener for iframe communication
         * @param {Function} resolve - Promise resolve
         * @param {Function} reject - Promise reject
         */
        setupMessageListener: function (resolve, reject) {
            var self = this;

            // Remove existing listener
            if (this.messageListener) {
                window.removeEventListener('message', this.messageListener);
            }

            this.messageListener = function (event) {
                // Validate message origin (should match 3D Secure domain)
                var data = event.data;

                if (!data) return;

                // Handle various 3D Secure completion messages
                if (data.type === 'SIMPLYIN_3DS_COMPLETE' ||
                    data.type === '3DS_COMPLETE' ||
                    data.status === 'COMPLETED' ||
                    data.status === 'SUCCESS') {
                    
                    self.onComplete(data, resolve);
                } else if (data.type === 'SIMPLYIN_3DS_CANCEL' ||
                           data.type === '3DS_CANCEL' ||
                           data.status === 'CANCELLED') {
                    
                    self.onCancel(reject);
                } else if (data.type === 'SIMPLYIN_3DS_ERROR' ||
                           data.type === '3DS_ERROR' ||
                           data.status === 'FAILED') {
                    
                    self.onError(data, reject);
                }
            };

            window.addEventListener('message', this.messageListener);
        },

        /**
         * Set up close button handler
         * @param {Function} reject - Promise reject
         */
        setupCloseHandler: function (reject) {
            var self = this;
            var closeBtn = document.getElementById('simplyin-3ds-close');
            var overlay = this.iframeContainer.querySelector('.simplyin-3ds-overlay');

            if (closeBtn) {
                closeBtn.onclick = function () {
                    self.onCancel(reject);
                };
            }

            if (overlay) {
                overlay.onclick = function () {
                    self.onCancel(reject);
                };
            }
        },

        /**
         * Handle full page redirect
         * @param {string} url - 3D Secure URL
         * @param {Function} resolve - Promise resolve
         * @param {Function} reject - Promise reject
         */
        fullPageRedirect: function (url, resolve, reject) {
            // Store payment info in session storage for retrieval after redirect
            try {
                sessionStorage.setItem('simplyin_3ds_payment_id', this.paymentId);
                sessionStorage.setItem('simplyin_3ds_auth_token', this.authToken);
                sessionStorage.setItem('simplyin_3ds_return_url', this.returnUrl);
                sessionStorage.setItem('simplyin_3ds_timestamp', Date.now().toString());
            } catch (e) {
                console.warn('Failed to store 3DS session data:', e);
            }

            // Redirect to 3D Secure page
            window.location.href = url;
        },

        /**
         * Handle 3D Secure completion
         * @param {Object} data - Completion data
         * @param {Function} resolve - Promise resolve
         */
        onComplete: function (data, resolve) {
            var self = this;

            this.cleanup();

            // Start polling for payment status
            paymentStatusPoller.startPolling(this.paymentId, this.authToken, {
                onCompleted: function (response) {
                    if (self.callbacks.onComplete) {
                        self.callbacks.onComplete(response);
                    }
                    resolve(response);
                },
                onFailed: function (error) {
                    if (self.callbacks.onError) {
                        self.callbacks.onError(error);
                    }
                    // Still resolve but with failed status
                    resolve({ success: false, error: error });
                },
                onTimeout: function (error) {
                    if (self.callbacks.onError) {
                        self.callbacks.onError(error);
                    }
                    resolve({ success: false, error: error });
                }
            }).catch(function (error) {
                if (self.callbacks.onError) {
                    self.callbacks.onError(error);
                }
                resolve({ success: false, error: error });
            });
        },

        /**
         * Handle 3D Secure cancellation
         * @param {Function} reject - Promise reject
         */
        onCancel: function (reject) {
            this.cleanup();

            var cancelError = {
                code: 'USER_CANCELLED',
                message: $t('Payment verification was cancelled. Would you like to try again?')
            };

            if (this.callbacks.onCancel) {
                this.callbacks.onCancel(cancelError);
            }

            reject(cancelError);
        },

        /**
         * Handle 3D Secure error
         * @param {Object} data - Error data
         * @param {Function} reject - Promise reject
         */
        onError: function (data, reject) {
            this.cleanup();

            var error = {
                code: data.errorCode || 'THREE_DS_ERROR',
                message: data.errorMessage || data.message || $t('3D Secure verification failed')
            };

            if (this.callbacks.onError) {
                this.callbacks.onError(error);
            }

            reject(error);
        },

        /**
         * Clean up iframe and listeners
         */
        cleanup: function () {
            // Remove message listener
            if (this.messageListener) {
                window.removeEventListener('message', this.messageListener);
                this.messageListener = null;
            }

            // Remove iframe container
            if (this.iframeContainer) {
                this.iframeContainer.remove();
                this.iframeContainer = null;
            }

            this.iframeElement = null;
        },

        /**
         * Check if returning from 3D Secure redirect
         * @returns {Object|null} - Stored 3DS data or null
         */
        checkReturnFrom3DS: function () {
            try {
                var paymentId = sessionStorage.getItem('simplyin_3ds_payment_id');
                var authToken = sessionStorage.getItem('simplyin_3ds_auth_token');
                var timestamp = sessionStorage.getItem('simplyin_3ds_timestamp');

                if (!paymentId || !timestamp) {
                    return null;
                }

                // Check if session is still valid (30 minutes)
                var elapsed = Date.now() - parseInt(timestamp, 10);
                if (elapsed > 30 * 60 * 1000) {
                    this.clear3DSSession();
                    return null;
                }

                return {
                    paymentId: paymentId,
                    authToken: authToken,
                    returnUrl: sessionStorage.getItem('simplyin_3ds_return_url')
                };
            } catch (e) {
                console.warn('Failed to check 3DS return:', e);
                return null;
            }
        },

        /**
         * Clear 3D Secure session data
         */
        clear3DSSession: function () {
            try {
                sessionStorage.removeItem('simplyin_3ds_payment_id');
                sessionStorage.removeItem('simplyin_3ds_auth_token');
                sessionStorage.removeItem('simplyin_3ds_return_url');
                sessionStorage.removeItem('simplyin_3ds_timestamp');
            } catch (e) {
                console.warn('Failed to clear 3DS session:', e);
            }
        },

        /**
         * Resume payment verification after 3D Secure redirect
         * @param {Object} callbacks - Callback functions
         * @returns {Promise}
         */
        resumeAfterRedirect: function (callbacks) {
            var self = this;
            var sessionData = this.checkReturnFrom3DS();

            if (!sessionData) {
                return Promise.reject({
                    code: 'NO_3DS_SESSION',
                    message: $t('No pending 3D Secure verification found')
                });
            }

            this.paymentId = sessionData.paymentId;
            this.authToken = sessionData.authToken;

            if (callbacks) {
                this.callbacks = $.extend(this.callbacks, callbacks);
            }

            // Clear session data
            this.clear3DSSession();

            // Start polling for payment status
            return paymentStatusPoller.startPolling(this.paymentId, this.authToken, {
                onCompleted: function (response) {
                    if (self.callbacks.onComplete) {
                        self.callbacks.onComplete(response);
                    }
                },
                onFailed: function (error) {
                    if (self.callbacks.onError) {
                        self.callbacks.onError(error);
                    }
                },
                onTimeout: function (error) {
                    if (self.callbacks.onError) {
                        self.callbacks.onError(error);
                    }
                }
            });
        }
    };
});
