/**
 * Simply.IN Session Storage Manager
 * Handles localStorage with expiration and email change detection
 * Uses localStorage instead of sessionStorage to persist across page refreshes
 */
define([
    'jquery'
], function ($) {
    'use strict';

    // Session expiration time - 1 hour
    var EXPIRATION_TIME = 60 * 60 * 1000; // 60 minutes (1 hour) in milliseconds
    var STORAGE_PREFIX = 'simplyin_';
    var EMAIL_KEY = STORAGE_PREFIX + 'current_email';
    var TIMESTAMP_KEY = STORAGE_PREFIX + 'timestamp';

    return {
        /**
         * Set item in localStorage with timestamp
         */
        setItem: function (key, value) {
            try {
                var fullKey = STORAGE_PREFIX + key;
                var data = {
                    value: value,
                    timestamp: new Date().getTime()
                };
                localStorage.setItem(fullKey, JSON.stringify(data));
                
                // Update global timestamp
                localStorage.setItem(TIMESTAMP_KEY, new Date().getTime().toString());
            } catch (e) {
                console.error('SimplyIn Storage: Error setting item', e);
            }
        },

        /**
         * Get item from localStorage with expiration check
         */
        getItem: function (key) {
            try {
                var fullKey = STORAGE_PREFIX + key;
                var item = localStorage.getItem(fullKey);
                
                if (!item) {
                    return null;
                }

                var data = JSON.parse(item);
                var currentTime = new Date().getTime();
                var age = currentTime - data.timestamp;

                // Check if expired (30 minutes)
                if (age > EXPIRATION_TIME) {
                    this.removeItem(key);
                    return null;
                }

                // Refresh session timestamp on access (keep session alive while user is active)
                this.refreshSession();

                return data.value;
            } catch (e) {
                console.error('SimplyIn Storage: Error getting item', e);
                return null;
            }
        },

        /**
         * Remove item from localStorage
         */
        removeItem: function (key) {
            try {
                var fullKey = STORAGE_PREFIX + key;
                localStorage.removeItem(fullKey);
            } catch (e) {
                console.error('SimplyIn Storage: Error removing item', e);
            }
        },

        /**
         * Clear all Simply.IN related items
         */
        clearAll: function () {
            try {
                var keys = Object.keys(localStorage);
                keys.forEach(function (key) {
                    if (key.startsWith(STORAGE_PREFIX)) {
                        localStorage.removeItem(key);
                    }
                });
            } catch (e) {
                console.error('SimplyIn Storage: Error clearing all', e);
            }
        },

        /**
         * Check if session is expired
         * Returns true only if timestamp exists AND is older than EXPIRATION_TIME
         * Returns false if no timestamp (caller should handle this case)
         */
        isExpired: function () {
            try {
                var timestamp = localStorage.getItem(TIMESTAMP_KEY);
                if (!timestamp) {
                    // No timestamp - can't determine expiration
                    // Return false to avoid clearing potentially valid data
                    return false;
                }

                var currentTime = new Date().getTime();
                var age = currentTime - parseInt(timestamp);
                var isExpired = age > EXPIRATION_TIME;

                return isExpired;
            } catch (e) {
                console.error('SimplyIn Storage: Error checking expiration', e);
                // On error, return false to avoid clearing data
                return false;
            }
        },

        /**
         * Set current email and clear storage if email changed
         */
        setCurrentEmail: function (email) {
            try {
                var currentEmail = localStorage.getItem(EMAIL_KEY);
                
                // If email changed, clear all Simply.IN data
                if (currentEmail && currentEmail !== email) {
                    this.clearAll();
                }

                // Set new email
                localStorage.setItem(EMAIL_KEY, email);
            } catch (e) {
                console.error('SimplyIn Storage: Error setting email', e);
            }
        },

        /**
         * Get current email
         */
        getCurrentEmail: function () {
            try {
                return localStorage.getItem(EMAIL_KEY);
            } catch (e) {
                console.error('SimplyIn Storage: Error getting email', e);
                return null;
            }
        },

        /**
         * Check if email has changed
         */
        hasEmailChanged: function (newEmail) {
            var currentEmail = this.getCurrentEmail();
            return currentEmail && currentEmail !== newEmail;
        },

        /**
         * Initialize storage - check expiration and clear if needed
         * Only clears data if session is definitely expired (has timestamp and it's old)
         * Does NOT clear if timestamp is missing (could be a storage issue)
         */
        initialize: function () {
            // Check if this is a new user (has new_user flag but no auth token)
            var isNewUser = this.getItem('new_user') === 'true';
            var hasAuthToken = !!this.getItem('auth_token');
            var timestamp = localStorage.getItem(TIMESTAMP_KEY);
            
            // Don't clear data if it's a new user without auth token yet
            if (isNewUser && !hasAuthToken) {
                return;
            }
            
            // Only clear if we have a timestamp AND it's expired
            // If no timestamp exists, don't clear - the data might still be valid
            // and the timestamp might have been lost due to storage issues
            if (timestamp && this.isExpired()) {
                this.clearAll();
            } else if (!timestamp && hasAuthToken) {
                // We have auth token but no timestamp - set timestamp now to prevent future issues
                localStorage.setItem(TIMESTAMP_KEY, new Date().getTime().toString());
            }
        },

        /**
         * Get auth token with expiration check
         */
        getAuthToken: function () {
            return this.getItem('auth_token');
        },

        /**
         * Set auth token
         */
        setAuthToken: function (token) {
            this.setItem('auth_token', token);
        },

        /**
         * Get user data with expiration check
         */
        getUserData: function () {
            var data = this.getItem('user_data');
            if (data && typeof data === 'string') {
                try {
                    return JSON.parse(data);
                } catch (e) {
                    return data;
                }
            }
            return data;
        },

        /**
         * Set user data
         */
        setUserData: function (userData) {
            var data = typeof userData === 'string' ? userData : JSON.stringify(userData);
            this.setItem('user_data', data);
        },

        /**
         * Get new user flag
         */
        isNewUser: function () {
            return this.getItem('new_user') === 'true';
        },

        /**
         * Set new user flag
         */
        setNewUser: function (isNew) {
            this.setItem('new_user', isNew ? 'true' : 'false');
        },

        /**
         * Get new user email
         */
        getNewUserEmail: function () {
            return this.getItem('new_user_email');
        },

        /**
         * Set new user email
         */
        setNewUserEmail: function (email) {
            this.setItem('new_user_email', email);
        },

        /**
         * Check if user was recognized by SimplyIN (checkEmail returned userExists=true)
         * This is set even if user doesn't complete OTP verification.
         */
        isUserRecognized: function () {
            return this.getItem('user_recognized') === 'true';
        },

        /**
         * Set user recognized flag (user exists in SimplyIN but may not have verified OTP)
         */
        setUserRecognized: function (recognized) {
            this.setItem('user_recognized', recognized ? 'true' : 'false');
        },

        /**
         * Clear authentication data
         */
        clearAuthData: function () {
            this.removeItem('auth_token');
            this.removeItem('user_data');
            // Drop the recognized flag too, so SimplyIN methods are not offered after auth is cleared.
            this.removeItem('user_recognized');
        },

        /**
         * Clear new user data
         */
        clearNewUserData: function () {
            this.removeItem('new_user');
            this.removeItem('new_user_email');
        },

        /**
         * Get remaining time before expiration (in minutes)
         */
        getRemainingTime: function () {
            try {
                var timestamp = localStorage.getItem(TIMESTAMP_KEY);
                if (!timestamp) {
                    return 0;
                }

                var currentTime = new Date().getTime();
                var age = currentTime - parseInt(timestamp);
                var remaining = EXPIRATION_TIME - age;

                return Math.max(0, Math.floor(remaining / 60000)); // Convert to minutes
            } catch (e) {
                console.error('SimplyIn Storage: Error getting remaining time', e);
                return 0;
            }
        },

        /**
         * Refresh timestamp (extend session)
         */
        refreshSession: function () {
            try {
                localStorage.setItem(TIMESTAMP_KEY, new Date().getTime().toString());
            } catch (e) {
                console.error('SimplyIn Storage: Error refreshing session', e);
            }
        },

        /**
         * Get notification token ID for push notification polling
         */
        getNotificationTokenId: function () {
            return this.getItem('notification_token_id');
        },

        /**
         * Set notification token ID for push notification polling
         */
        setNotificationTokenId: function (tokenId) {
            this.setItem('notification_token_id', tokenId);
        },

        /**
         * Clear notification token ID
         */
        clearNotificationTokenId: function () {
            this.removeItem('notification_token_id');
        },

        /**
         * Get pending email for push notification
         */
        getPendingEmail: function () {
            return this.getItem('pending_email');
        },

        /**
         * Set pending email for push notification
         */
        setPendingEmail: function (email) {
            this.setItem('pending_email', email);
        },

        /**
         * Clear pending email
         */
        clearPendingEmail: function () {
            this.removeItem('pending_email');
        },

        /**
         * Get selected parcel locker
         */
        getSelectedParcelLocker: function () {
            var data = this.getItem('selected_parcel_locker');
            if (data && typeof data === 'string') {
                try {
                    return JSON.parse(data);
                } catch (e) {
                    return data;
                }
            }
            return data;
        },

        /**
         * Set selected parcel locker
         * Also automatically sets delivery type to 'parcel_locker'
         */
        setSelectedParcelLocker: function (lockerData) {
            var data = typeof lockerData === 'string' ? lockerData : JSON.stringify(lockerData);
            this.setItem('selected_parcel_locker', data);
            // Automatically set delivery type to parcel_locker when a locker is selected
            this.setSelectedDeliveryType('parcel_locker');
        },

        /**
         * Clear selected parcel locker
         */
        clearSelectedParcelLocker: function () {
            this.removeItem('selected_parcel_locker');
        },

        /**
         * Get parcel locker minimal info for order creation
         * Returns {lockerId: string, providerName: string} or null if no locker selected
         */
        getParcelLockerMinimalInfo: function () {
            var lockerData = this.getSelectedParcelLocker();
            
            if (!lockerData) {
                return null;
            }
            
            // Extract lockerId
            var lockerId = lockerData.lockerId;
            if (!lockerId) {
                console.warn('SimplyIn Storage: Parcel locker data missing lockerId');
                return null;
            }
            
            // Extract provider name from providerName or provider field
            var providerName = lockerData.providerName || lockerData.provider;
            if (!providerName) {
                console.warn('SimplyIn Storage: Parcel locker data missing providerName/provider');
                return null;
            }
            
            // Normalize provider name to lowercase
            providerName = providerName.toLowerCase();
            
            return {
                lockerId: lockerId,
                providerName: providerName
            };
        },

        /**
         * Check if current delivery is parcel locker type
         * @returns {boolean}
         */
        isParcelLockerDelivery: function () {
            return this.getSelectedDeliveryType() === 'parcel_locker';
        },

        /**
         * Get selected delivery type (courier or parcel_locker)
         */
        getSelectedDeliveryType: function () {
            return this.getItem('selected_delivery_type') || 'courier';
        },

        /**
         * Set selected delivery type
         */
        setSelectedDeliveryType: function (type) {
            this.setItem('selected_delivery_type', type);
        },

        // ==========================================
        // Payment Session Methods
        // ==========================================

        /**
         * Set payment state
         * @param {Object} paymentState - Payment state object containing:
         *   - paymentId: string
         *   - orderId: string (SimplyIN order ID)
         *   - magentoQuoteId: string
         *   - paymentMethod: string (add_card, saved_card, blik)
         *   - paymentStatus: string (INITIATED, PENDING_3DS, COMPLETED, FAILED)
         *   - redirectUrl: string (optional)
         */
        setPaymentState: function (paymentState) {
            var data = typeof paymentState === 'string' ? paymentState : JSON.stringify(paymentState);
            this.setItem('payment_state', data);
        },

        /**
         * Get payment state
         * @returns {Object|null} Payment state object or null if not found/expired
         */
        getPaymentState: function () {
            var data = this.getItem('payment_state');
            if (data && typeof data === 'string') {
                try {
                    return JSON.parse(data);
                } catch (e) {
                    return data;
                }
            }
            return data;
        },

        /**
         * Update payment status
         * @param {string} status - New payment status
         */
        updatePaymentStatus: function (status) {
            var state = this.getPaymentState();
            if (state) {
                state.paymentStatus = status;
                state.lastUpdated = new Date().getTime();
                this.setPaymentState(state);
            }
        },

        /**
         * Clear payment state
         */
        clearPaymentState: function () {
            this.removeItem('payment_state');
        },

        /**
         * Get payment ID from current payment state
         * @returns {string|null}
         */
        getPaymentId: function () {
            var state = this.getPaymentState();
            return state ? state.paymentId : null;
        },

        /**
         * Check if there's a pending payment
         * @returns {boolean}
         */
        hasPendingPayment: function () {
            var state = this.getPaymentState();
            if (!state) return false;
            
            return state.paymentStatus === 'INITIATED' || 
                   state.paymentStatus === 'PENDING_3DS' ||
                   state.paymentStatus === 'PENDING';
        },

        /**
         * Set 3D Secure redirect data
         * @param {Object} data - 3DS data containing paymentId, redirectUrl, etc.
         */
        set3DSData: function (data) {
            var threeDSData = typeof data === 'string' ? data : JSON.stringify(data);
            this.setItem('3ds_data', threeDSData);
        },

        /**
         * Get 3D Secure redirect data
         * @returns {Object|null}
         */
        get3DSData: function () {
            var data = this.getItem('3ds_data');
            if (data && typeof data === 'string') {
                try {
                    return JSON.parse(data);
                } catch (e) {
                    return data;
                }
            }
            return data;
        },

        /**
         * Clear 3D Secure data
         */
        clear3DSData: function () {
            this.removeItem('3ds_data');
        },

        /**
         * Check if returning from 3D Secure redirect
         * @returns {boolean}
         */
        isReturningFrom3DS: function () {
            var data = this.get3DSData();
            return data !== null && data.paymentId;
        },

        /**
         * Clear all payment-related data
         */
        clearAllPaymentData: function () {
            this.clearPaymentState();
            this.clear3DSData();
        },

        // ==========================================
        // Selected Address ID Methods
        // ==========================================

        /**
         * Get selected billing address ID
         * @returns {string|null}
         */
        getSelectedBillingAddressId: function () {
            return this.getItem('selected_billing_address_id');
        },

        /**
         * Set selected billing address ID
         * @param {string} addressId - The SimplyIN billing address _id
         */
        setSelectedBillingAddressId: function (addressId) {
            this.setItem('selected_billing_address_id', addressId);
        },

        /**
         * Get selected shipping address ID
         * @returns {string|null}
         */
        getSelectedShippingAddressId: function () {
            return this.getItem('selected_shipping_address_id');
        },

        /**
         * Set selected shipping address ID
         * @param {string} addressId - The SimplyIN shipping address _id
         */
        setSelectedShippingAddressId: function (addressId) {
            this.setItem('selected_shipping_address_id', addressId);
        },

        /**
         * Clear selected address IDs
         */
        clearSelectedAddressIds: function () {
            this.removeItem('selected_billing_address_id');
            this.removeItem('selected_shipping_address_id');
            this.removeItem('selected_billing_address');
            this.removeItem('selected_shipping_address');
        },

        // ==========================================
        // Complete Address Object Methods
        // ==========================================

        /**
         * Get complete selected billing address object
         * @returns {Object|null}
         */
        getSelectedBillingAddress: function () {
            var data = this.getItem('selected_billing_address');
            if (data && typeof data === 'string') {
                try {
                    return JSON.parse(data);
                } catch (e) {
                    return null;
                }
            }
            return data;
        },

        /**
         * Set complete selected billing address object
         * @param {Object} address - The complete SimplyIN billing address object
         */
        setSelectedBillingAddress: function (address) {
            var data = typeof address === 'string' ? address : JSON.stringify(address);
            this.setItem('selected_billing_address', data);
        },

        /**
         * Get complete selected shipping address object
         * @returns {Object|null}
         */
        getSelectedShippingAddress: function () {
            var data = this.getItem('selected_shipping_address');
            if (data && typeof data === 'string') {
                try {
                    return JSON.parse(data);
                } catch (e) {
                    return null;
                }
            }
            return data;
        },

        /**
         * Set complete selected shipping address object
         * @param {Object} address - The complete SimplyIN shipping address object
         */
        setSelectedShippingAddress: function (address) {
            var data = typeof address === 'string' ? address : JSON.stringify(address);
            this.setItem('selected_shipping_address', data);
        }
    };
});
