import { h, proxyCustomElement, HTMLElement, createEvent } from '@stencil/core/internal/client';
import { A as Api } from './Api.js';
import { A as ApplePayConfig, a as ApplePayHelpers, b as ApplePayPaymentRequest, c as ApplePaySessionStatus, d as ApplePayButtonStyle, e as ApplePayButtonType, f as ApplePayMerchantCapability } from './ApplePay.js';
import { S as StyledHost } from './styled-host.js';
import './justifi-details2.js';
import './event-types.js';
import './justifi-radio-list-item2.js';
import { S as Skeleton } from './skeleton.js';
import { c as checkoutStore, o as onChange } from './checkout.store.js';

// Centralized error codes for Apple Pay service
var ApplePayServiceErrorCode;
(function (ApplePayServiceErrorCode) {
    ApplePayServiceErrorCode["UNAVAILABLE"] = "UNAVAILABLE";
    ApplePayServiceErrorCode["SESSION_ERROR"] = "SESSION_ERROR";
    ApplePayServiceErrorCode["MERCHANT_VALIDATION_ERROR"] = "MERCHANT_VALIDATION_ERROR";
    ApplePayServiceErrorCode["PAYMENT_PROCESSING_ERROR"] = "PAYMENT_PROCESSING_ERROR";
    ApplePayServiceErrorCode["USER_CANCELLED"] = "USER_CANCELLED";
})(ApplePayServiceErrorCode || (ApplePayServiceErrorCode = {}));
class ApplePayService {
    constructor() {
        this.api = Api();
    }
    /**
     * Initialize Apple Pay configuration
     */
    initialize(applePayConfig) {
        this.applePayConfig = new ApplePayConfig(applePayConfig);
        if (!this.applePayConfig.isValid) {
            throw new Error('Invalid Apple Pay configuration provided');
        }
    }
    /**
     * Validate merchant with Apple Pay servers via API
     */
    async validateMerchant(authToken, accountId) {
        const endpoint = 'apple_pay/merchant_session';
        try {
            const response = await this.api.post({
                endpoint,
                authToken,
                headers: {
                    'Sub-Account': accountId,
                },
                body: {
                    domain: window.location.hostname,
                    display_name: this.applePayConfig.displayName
                }
            });
            return response;
        }
        catch (error) {
            console.error('Backend validation failed:', error);
            throw new Error('Merchant validation failed');
        }
    }
    /**
     * Process Apple Pay payment via API (fixed to match original logic)
     */
    async processPayment(authToken, accountId, payload) {
        const endpoint = 'apple_pay/process_token';
        const result = await this.api.post({
            endpoint,
            authToken,
            body: payload,
            headers: {
                'Sub-Account': accountId,
            },
        });
        return {
            success: result.id && !!result.data.token,
            data: result,
        };
    }
    /**
     * Check if Apple Pay is available on this device/browser
     */
    isAvailable() {
        return (ApplePayHelpers.isApplePaySupported() && ApplePayHelpers.canMakePayments());
    }
    /**
     * Check if the user has an active card for the merchant
     */
    async canMakePaymentsWithActiveCard() {
        if (!this.applePayConfig) {
            throw new Error('Apple Pay not initialized. Call initialize() first.');
        }
        return await ApplePayHelpers.canMakePaymentsWithActiveCard(this.applePayConfig.merchantIdentifier);
    }
    /**
     * Start Apple Pay session
     */
    async startPaymentSession(paymentRequest, authToken, accountId) {
        // Begin session
        if (!this.applePayConfig) {
            console.error('[ApplePayService] Missing applePayConfig. Did you call initialize()?');
            throw new Error('Apple Pay not initialized. Call initialize() first.');
        }
        // if (!this.isAvailable()) {
        //   throw new Error('Apple Pay is not available on this device/browser');
        // }
        const request = new ApplePayPaymentRequest(paymentRequest);
        if (!request.isValid) {
            const missingFields = [];
            if (!request.countryCode)
                missingFields.push('countryCode');
            if (!request.currencyCode)
                missingFields.push('currencyCode');
            if (!request.merchantCapabilities ||
                request.merchantCapabilities.length === 0)
                missingFields.push('merchantCapabilities');
            if (!request.supportedNetworks || request.supportedNetworks.length === 0)
                missingFields.push('supportedNetworks');
            if (!request.total || !request.total.label || !request.total.amount)
                missingFields.push('total');
            console.error('[ApplePayService] Payment request is invalid. Missing/invalid:', missingFields);
            throw new Error('Invalid payment request provided');
        }
        this.currentPaymentRequest = request;
        return new Promise((resolve, reject) => {
            try {
                // Defensive checks for Apple Pay environment
                if (typeof window === 'undefined' || !('ApplePaySession' in window)) {
                    console.error('[ApplePayService] ApplePaySession not available on window');
                    return reject({
                        success: false,
                        error: {
                            code: ApplePayServiceErrorCode.UNAVAILABLE,
                            message: 'ApplePaySession API is not available in this environment',
                        },
                    });
                }
                this.currentSession = new window.ApplePaySession(3, request);
                this.setupSessionEventHandlers(resolve, reject, authToken, accountId);
                this.currentSession.begin();
            }
            catch (error) {
                console.error('[ApplePayService] Exception while starting session:', error);
                reject({
                    success: false,
                    error: {
                        code: ApplePayServiceErrorCode.SESSION_ERROR,
                        message: error instanceof Error
                            ? error.message
                            : 'Failed to start Apple Pay session',
                    },
                });
            }
        });
    }
    /**
     * Abort current Apple Pay session
     */
    abortPaymentSession() {
        if (this.currentSession) {
            this.currentSession.abort();
            this.currentSession = undefined;
            this.currentPaymentRequest = undefined;
        }
    }
    /**
     * Setup Apple Pay session event handlers
     */
    setupSessionEventHandlers(resolve, reject, authToken, accountId) {
        if (!this.currentSession ||
            !this.applePayConfig ||
            !this.currentPaymentRequest) {
            console.error('[ApplePayService] setupSessionEventHandlers called without required state', {
                hasSession: Boolean(this.currentSession),
                hasConfig: Boolean(this.applePayConfig),
                hasPaymentRequest: Boolean(this.currentPaymentRequest),
            });
            return;
        }
        this.currentSession.onvalidatemerchant = async () => {
            try {
                if (!authToken) {
                    console.error('[ApplePayService] Missing authToken for merchant validation');
                    throw new Error('Authentication token not provided.');
                }
                const merchantSession = await this.validateMerchant(authToken, accountId);
                try {
                    this.currentSession.completeMerchantValidation(merchantSession);
                }
                catch (completionError) {
                    console.error('Error calling completeMerchantValidation:', completionError);
                    throw completionError;
                }
            }
            catch (error) {
                console.error('=== MERCHANT VALIDATION ERROR ===');
                console.error('Error during merchant validation:', error);
                if (error && error.stack) {
                    console.error('Error stack:', error.stack);
                }
                this.currentSession.abort();
                reject({
                    success: false,
                    error: {
                        code: ApplePayServiceErrorCode.MERCHANT_VALIDATION_ERROR,
                        message: error instanceof Error
                            ? error.message
                            : 'Merchant validation failed',
                    },
                });
            }
        };
        this.currentSession.onpaymentauthorized = async (event) => {
            try {
                const payment = event.payment;
                const paymentPayload = Object.assign(Object.assign({}, payment.token), { product_details: {
                        name: this.currentPaymentRequest.total.label,
                        price: ApplePayHelpers.parseAmount(this.currentPaymentRequest.total.amount),
                        description: this.currentPaymentRequest.total.label,
                    } });
                const paymentResult = await this.processPayment(authToken, accountId, paymentPayload);
                if (paymentResult.success) {
                    this.currentSession.completePayment({
                        status: ApplePaySessionStatus.STATUS_SUCCESS,
                    });
                    resolve({
                        success: true,
                        token: payment.token,
                        paymentMethodId: paymentResult.data.id,
                    });
                }
                else {
                    console.error('PSP reported payment failure:', paymentResult.data);
                    this.currentSession.completePayment({
                        status: ApplePaySessionStatus.STATUS_FAILURE,
                    });
                    reject({
                        success: false,
                        error: {
                            code: ApplePayServiceErrorCode.PAYMENT_PROCESSING_ERROR,
                            message: 'Payment processing failed',
                        },
                    });
                }
            }
            catch (error) {
                console.error('=== PAYMENT PROCESSING ERROR ===');
                console.error('Error processing payment:', error);
                if (error && error.stack) {
                    console.error('Error stack:', error.stack);
                }
                this.currentSession.completePayment({
                    status: ApplePaySessionStatus.STATUS_FAILURE,
                });
                reject({
                    success: false,
                    error: {
                        code: ApplePayServiceErrorCode.PAYMENT_PROCESSING_ERROR,
                        message: error instanceof Error
                            ? error.message
                            : 'Payment processing failed',
                    },
                });
            }
            finally {
                this.currentSession = undefined;
                this.currentPaymentRequest = undefined;
            }
        };
        this.currentSession.onpaymentmethodselected = () => {
            const paymentUpdate = {
                newTotal: this.currentPaymentRequest.total,
                newLineItems: this.currentPaymentRequest.lineItems || [],
            };
            try {
                this.currentSession.completePaymentMethodSelection(paymentUpdate);
            }
            catch (error) {
                console.error('Error completing payment method selection:', error);
                this.currentSession.abort();
            }
        };
        this.currentSession.onshippingmethodselected = () => {
            this.currentSession.completeShippingMethodSelection({
                status: ApplePaySessionStatus.STATUS_SUCCESS,
                newTotal: this.currentPaymentRequest.total,
                newLineItems: this.currentPaymentRequest.lineItems || [],
            });
        };
        this.currentSession.oncancel = (event) => {
            if (event.sessionError) {
                console.error(event.sessionError);
                switch (event.sessionError.code) {
                    case 'unknown':
                        console.error('Unknown error - likely merchant validation issue');
                        console.error('This usually means:');
                        console.error('1. Merchant certificate is invalid or expired');
                        console.error('2. Merchant identifier mismatch');
                        console.error('3. Backend validation endpoint issues');
                        break;
                    case 'invalidMerchantSession':
                        console.error('Invalid merchant session provided');
                        console.error('Check that the merchant session from backend is valid');
                        break;
                    case 'userCancel':
                        console.error('User cancelled the payment');
                        break;
                    default:
                        console.error('Other error code:', event.sessionError.code);
                }
            }
            this.currentSession = undefined;
            this.currentPaymentRequest = undefined;
            reject({
                success: false,
                error: {
                    code: ApplePayServiceErrorCode.USER_CANCELLED,
                    message: 'User cancelled the Apple Pay session',
                },
            });
        };
        if ('onerror' in this.currentSession) {
            this.currentSession.onerror = (error) => {
                console.error('=== APPLE PAY SESSION ERROR ===');
                console.error('Session error:', error);
                this.currentSession = undefined;
                this.currentPaymentRequest = undefined;
                reject({
                    success: false,
                    error: {
                        code: ApplePayServiceErrorCode.SESSION_ERROR,
                        message: 'Apple Pay session error occurred',
                    },
                });
            };
        }
    }
    /**
     * Create a basic payment request
     */
    static createPaymentRequest(amount, label, countryCode = 'US', currencyCode = 'USD') {
        return {
            countryCode,
            currencyCode,
            merchantCapabilities: ApplePayHelpers.getDefaultMerchantCapabilities(),
            supportedNetworks: ApplePayHelpers.getDefaultSupportedNetworks(),
            total: ApplePayHelpers.createLineItem(label, amount),
        };
    }
    /**
     * Get current configuration
     */
    getApplePayConfig() {
        return this.applePayConfig;
    }
}

const ApplePaySkeleton = (props) => {
    const { isLoading } = props;
    if (!isLoading) {
        return null;
    }
    return (h("div", { class: 'container-fluid p-0' }, h("div", { class: 'row mb-3' }, h("div", { class: 'col-12 align-content-center' }, h(Skeleton, { height: '44px', width: '100%', styles: { borderRadius: "8px" } })))));
};

const ProcessingSpinner = () => (h("div", { class: 'processing-overlay' }, h("div", { class: 'spinner' }), h("span", null, "Processing...")));
const ApplePayButton = (props) => {
    const getApplePayButtonClass = () => {
        let classes = "apple-pay-button";
        switch (props.buttonStyle) {
            case ApplePayButtonStyle.WHITE:
                classes += " apple-pay-button-white";
                break;
            case ApplePayButtonStyle.WHITE_OUTLINE:
                classes += " apple-pay-button-white-outline";
                break;
            case ApplePayButtonStyle.BLACK:
            default:
                classes += " apple-pay-button-black";
                break;
        }
        switch (props.buttonType) {
            case ApplePayButtonType.BUY:
                classes += " apple-pay-button-type-buy";
                break;
            case ApplePayButtonType.DONATE:
                classes += " apple-pay-button-type-donate";
                break;
            case ApplePayButtonType.PLAIN:
            default:
                classes += " apple-pay-button-type-plain";
                break;
        }
        if (props.disabled || props.isProcessing || !props.isAvailable) {
            classes += " disabled";
        }
        return classes;
    };
    const handleClick = () => {
        if (!props.disabled &&
            !props.isProcessing &&
            props.isAvailable &&
            props.clickHandler) {
            props.clickHandler();
        }
    };
    return (h("div", { class: 'apple-pay-button-container' }, h("button", Object.assign({ class: getApplePayButtonClass(), style: {
            width: props.width,
            height: props.height,
        }, onClick: handleClick, disabled: props.disabled || props.isProcessing || !props.isAvailable, "aria-label": 'Pay with Apple Pay', type: 'button' }, props), props.isProcessing && ProcessingSpinner()), h("style", null, `
          .apple-pay-button-container {
            display: block;
            position: relative;
            width: 100%;
          }

          /* Apple Pay CSS classes - these are the official Apple Pay button styles */
          .apple-pay-button {
            display: inline-block;
            -webkit-appearance: -apple-pay-button;
            -apple-pay-button-type: plain; /* default */
            -apple-pay-button-style: black; /* default */
            border-radius: 8px;
            cursor: pointer;
            border: none;
            outline: none;
            transition: opacity 0.2s ease;
            position: relative;
          }

          /* Button styles */
          .apple-pay-button.apple-pay-button-black {
            -apple-pay-button-style: black;
          }

          .apple-pay-button.apple-pay-button-white {
            -apple-pay-button-style: white;
          }

          .apple-pay-button.apple-pay-button-white-outline {
            -apple-pay-button-style: white-outline;
          }

          /* Button types */
          .apple-pay-button.apple-pay-button-type-plain {
            -apple-pay-button-type: plain;
          }

          .apple-pay-button.apple-pay-button-type-buy {
            -apple-pay-button-type: buy;
          }

          .apple-pay-button.apple-pay-button-type-donate {
            -apple-pay-button-type: donate;
          }

          /* Hover and disabled states */
          .apple-pay-button:hover:not(.disabled) {
            opacity: 0.9;
          }

          .apple-pay-button.disabled {
            opacity: 0.5;
            cursor: not-allowed;
          }

          /* Processing overlay */
          .processing-overlay {
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 8px;
            background: rgba(0, 0, 0, 0.8);
            color: white;
            border-radius: 8px;
            font-size: 14px;
            font-weight: 500;
          }

          .spinner {
            width: 16px;
            height: 16px;
            border: 2px solid rgba(255, 255, 255, 0.3);
            border-top: 2px solid #fff;
            border-radius: 50%;
            animation: spin 1s linear infinite;
          }

          @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
          }

          /* Responsive design */
          @media (max-width: 480px) {
            .apple-pay-button {
              width: 100% !important;
              min-width: 200px;
            }
          }
        `)));
};

const JustifiApplePay = /*@__PURE__*/ proxyCustomElement(class JustifiApplePay extends HTMLElement {
    constructor(registerHost) {
        super();
        if (registerHost !== false) {
            this.__registerHost();
        }
        this.__attachShadow();
        this.applePayStarted = createEvent(this, "applePayStarted", 7);
        this.applePayCompleted = createEvent(this, "applePayCompleted", 7);
        this.applePayCancelled = createEvent(this, "applePayCancelled", 7);
        this.applePayError = createEvent(this, "applePayError", 7);
        this.sdkLoaded = false;
        this.countryCode = "US";
        this.merchantIdentifier = "merchant.com.staging-justifi.checkout-dev";
        this.merchantDisplayName = "JustiFi Checkout";
        this.initiativeContext = "dev-checkout.justifi-staging.com";
        this.buttonType = ApplePayButtonType.PLAIN;
        this.buttonStyle = ApplePayButtonStyle.BLACK;
        this.disabled = false;
        this.width = "100%";
        this.height = "48px";
        this.isLoading = true;
        this.isProcessing = false;
        this.isAvailable = false;
        this.canMakePayments = false;
        this.isConfigValid = true;
        this.error = null;
        this.handleApplePayClick = async () => {
            var _a, _b, _c;
            if (this.isProcessing || this.disabled || !this.isAvailable) {
                return;
            }
            try {
                this.isProcessing = true;
                this.error = null;
                this.applePayStarted.emit();
                const paymentRequest = {
                    countryCode: this.countryCode,
                    currencyCode: checkoutStore.paymentCurrency,
                    merchantCapabilities: [
                        ApplePayMerchantCapability.SUPPORTS_3DS,
                        ApplePayMerchantCapability.SUPPORTS_CREDIT,
                        ApplePayMerchantCapability.SUPPORTS_DEBIT,
                    ],
                    supportedNetworks: ApplePayHelpers.getDefaultSupportedNetworks(),
                    total: ApplePayHelpers.createLineItem(checkoutStore.paymentDescription, checkoutStore.paymentAmount),
                };
                const result = await this.applePayService.startPaymentSession(paymentRequest, checkoutStore.authToken, checkoutStore.accountId);
                if (result.success) {
                    this.applePayCompleted.emit({
                        success: true,
                        token: result.token,
                        paymentMethodId: result.paymentMethodId,
                    });
                }
                else {
                    this.applePayCompleted.emit({
                        success: false,
                        error: result.error,
                    });
                    this.applePayError.emit({
                        error: ((_a = result.error) === null || _a === void 0 ? void 0 : _a.message) || "Payment failed",
                        code: ((_b = result.error) === null || _b === void 0 ? void 0 : _b.code) || JustifiApplePay.ErrorCode.PAYMENT_FAILED,
                    });
                }
            }
            catch (error) {
                if (((_c = error === null || error === void 0 ? void 0 : error.error) === null || _c === void 0 ? void 0 : _c.code) === ApplePayServiceErrorCode.USER_CANCELLED) {
                    this.applePayCancelled.emit();
                }
                else {
                    const errorMessage = error instanceof Error ? error.message : "Payment failed";
                    this.error = errorMessage;
                    this.applePayError.emit({ error: errorMessage, code: JustifiApplePay.ErrorCode.PAYMENT_FAILED });
                    this.applePayCompleted.emit({
                        success: false,
                        error: errorMessage,
                    });
                }
            }
            finally {
                this.isProcessing = false;
            }
        };
    }
    componentWillLoad() {
        this.isAvailable = ApplePayHelpers.isApplePaySupported();
        if (!this.isAvailable) {
            this.isLoading = false;
            return;
        }
        if (checkoutStore.checkoutLoaded) {
            this.loadApplePaySDK();
        }
        else {
            onChange('checkoutLoaded', (loaded) => {
                if (loaded)
                    this.loadApplePaySDK();
            });
        }
    }
    loadApplePaySDK() {
        if (this.sdkLoaded)
            return;
        this.sdkLoaded = true;
        const script = document.createElement('script');
        script.src = 'https://applepay.cdn-apple.com/jsapi/1.latest/apple-pay-sdk.js';
        script.async = true;
        script.onload = () => this.initializeApplePay();
        document.head.appendChild(script);
    }
    async initializeApplePay() {
        try {
            this.isLoading = true;
            this.error = null;
            this.isConfigValid = true;
            const hasRequiredConfig = Boolean(checkoutStore.paymentAmount) &&
                Boolean(checkoutStore.paymentCurrency) &&
                Boolean(checkoutStore.authToken);
            if (!hasRequiredConfig) {
                this.error = "Missing required Apple Pay configuration";
                this.isConfigValid = false;
                this.applePayError.emit({ error: this.error, code: JustifiApplePay.ErrorCode.CONFIG_ERROR });
                this.isLoading = false;
                return;
            }
            this.isAvailable = ApplePayHelpers.isApplePaySupported();
            this.canMakePayments = ApplePayHelpers.canMakePayments();
            if (!this.isAvailable) {
                this.error = "Apple Pay is not supported on this device";
                this.applePayError.emit({ error: this.error, code: JustifiApplePay.ErrorCode.NOT_SUPPORTED });
                this.isLoading = false;
                return;
            }
            if (!this.canMakePayments) {
                this.error = "Apple Pay is not available";
                this.applePayError.emit({ error: this.error, code: JustifiApplePay.ErrorCode.NOT_AVAILABLE });
                this.isLoading = false;
                return;
            }
            const applePayConfig = {
                merchantIdentifier: this.merchantIdentifier,
                displayName: this.merchantDisplayName,
                initiative: "web",
                initiativeContext: this.initiativeContext,
                buttonType: this.buttonType,
                buttonStyle: this.buttonStyle,
            };
            this.applePayService = new ApplePayService();
            this.applePayService.initialize(applePayConfig);
            const hasActiveCard = await this.applePayService.canMakePaymentsWithActiveCard();
            if (!hasActiveCard) {
                console.warn("No Apple Pay cards available, but continuing...");
            }
        }
        catch (error) {
            this.error =
                error instanceof Error
                    ? error.message
                    : "Failed to initialize Apple Pay";
            this.applePayError.emit({ error: this.error, code: JustifiApplePay.ErrorCode.INITIALIZATION_ERROR });
        }
        finally {
            this.isLoading = false;
        }
    }
    async isSupported() {
        return this.isAvailable && this.canMakePayments;
    }
    async getPaymentMethods() {
        if (!this.isAvailable) {
            return [];
        }
        return ApplePayHelpers.getDefaultSupportedNetworks();
    }
    async abort() {
        var _a;
        (_a = this.applePayService) === null || _a === void 0 ? void 0 : _a.abortPaymentSession();
        this.isProcessing = false;
        this.applePayCancelled.emit();
    }
    render() {
        if (!checkoutStore.applePayEnabled) {
            // Render nothing when Apple Pay is disabled at the checkout settings level
            return null;
        }
        if (!this.isAvailable) {
            return null;
        }
        const isReady = !this.isLoading &&
            this.isAvailable &&
            this.canMakePayments &&
            this.isConfigValid;
        return (h(StyledHost, null, h("div", { class: 'apple-pay-container' }, h(ApplePaySkeleton, { isLoading: this.isLoading }), isReady && (h(ApplePayButton, { buttonType: this.buttonType, buttonStyle: this.buttonStyle, disabled: this.disabled, isProcessing: this.isProcessing, isAvailable: this.isAvailable, clickHandler: this.handleApplePayClick, width: this.width, height: this.height }))), h("style", null, `
            .apple-pay-container {
              width: 100%;
            }
          `)));
    }
}, [257, "justifi-apple-pay", {
        "countryCode": [1, "country-code"],
        "merchantIdentifier": [1, "merchant-identifier"],
        "merchantDisplayName": [1, "merchant-display-name"],
        "initiativeContext": [1, "initiative-context"],
        "buttonType": [1, "button-type"],
        "buttonStyle": [1, "button-style"],
        "disabled": [4],
        "width": [1],
        "height": [1],
        "isLoading": [32],
        "isProcessing": [32],
        "isAvailable": [32],
        "canMakePayments": [32],
        "isConfigValid": [32],
        "error": [32],
        "isSupported": [64],
        "getPaymentMethods": [64],
        "abort": [64]
    }]);
// Centralized error codes for the Apple Pay component layer
JustifiApplePay.ErrorCode = {
    CONFIG_ERROR: 'CONFIG_ERROR',
    NOT_SUPPORTED: 'NOT_SUPPORTED',
    NOT_AVAILABLE: 'NOT_AVAILABLE',
    INITIALIZATION_ERROR: 'INITIALIZATION_ERROR',
    PAYMENT_FAILED: 'PAYMENT_FAILED',
};
function defineCustomElement() {
    if (typeof customElements === "undefined") {
        return;
    }
    const components = ["justifi-apple-pay"];
    components.forEach(tagName => { switch (tagName) {
        case "justifi-apple-pay":
            if (!customElements.get(tagName)) {
                customElements.define(tagName, JustifiApplePay);
            }
            break;
    } });
}
defineCustomElement();

export { JustifiApplePay as J, defineCustomElement as d };
