import { proxyCustomElement, HTMLElement, createEvent, h } from '@stencil/core/internal/client';
import { S as StyledHost } from './styled-host.js';
import './justifi-details2.js';
import './event-types.js';
import './justifi-radio-list-item2.js';
import { c as checkPkgVersion } from './check-pkg-version.js';
import { J as JustifiAnalytics } from './Analytics.js';
import './config-state.js';
import './dinero.js';
import { a as ComponentErrorCodes, C as ComponentErrorSeverity } from './Plaid.js';
import './Pagination.js';
import './Business.js';
import './ApplePay.js';
import { c as checkoutStore } from './checkout.store.js';
import { P as PAYMENT_METHODS } from './ModularCheckout.js';
import { d as defineCustomElement$i } from './bank-account-billing-form-simple2.js';
import { d as defineCustomElement$h } from './bank-account-form2.js';
import { d as defineCustomElement$g } from './billing-form2.js';
import { d as defineCustomElement$f } from './billing-form-full2.js';
import { d as defineCustomElement$e } from './card-billing-form-simple2.js';
import { d as defineCustomElement$d } from './card-form2.js';
import { d as defineCustomElement$c } from './custom-popper2.js';
import { d as defineCustomElement$b } from './form-control-checkbox2.js';
import { d as defineCustomElement$a } from './form-control-help-text3.js';
import { d as defineCustomElement$9 } from './form-control-radio2.js';
import { d as defineCustomElement$8 } from './form-control-select2.js';
import { d as defineCustomElement$7 } from './form-control-text2.js';
import { d as defineCustomElement$6 } from './form-control-tooltip2.js';
import { d as defineCustomElement$5 } from './hidden-input2.js';
import { d as defineCustomElement$4 } from './iframe-input2.js';
import { d as defineCustomElement$3 } from './internal-button2.js';
import { d as defineCustomElement$2 } from './radio-list-item2.js';
import { d as defineCustomElement$1 } from './save-new-payment-method2.js';

// Constants
const PAYMENT_METHOD_TYPE_LABELS = {
    [PAYMENT_METHODS.NEW_BANK_ACCOUNT]: 'New bank account',
    [PAYMENT_METHODS.NEW_CARD]: 'New credit or debit card',
};
const ERROR_MESSAGES = {
    AUTH_TOKEN_REQUIRED: 'Auth token is required when using the tokenize-payment-method component not slotted in justifi-modular-checkout',
    ACCOUNT_ID_REQUIRED: 'Account ID is required when using the tokenize-payment-method component not slotted in justifi-modular-checkout',
    FORM_NOT_READY: 'Payment form not ready',
    VALIDATION_ERROR: 'Validation error',
};
const JustifiTokenizePaymentMethod = /*@__PURE__*/ proxyCustomElement(class JustifiTokenizePaymentMethod extends HTMLElement {
    constructor(registerHost) {
        super();
        if (registerHost !== false) {
            this.__registerHost();
        }
        this.__attachShadow();
        this.errorEvent = createEvent(this, "error-event", 7);
        this.submitEvent = createEvent(this, "submit-event", 7);
        this.computedHideSubmitButton = false;
        this.isLoading = false;
        this.submitButtonText = 'Submit';
    }
    paymentMethodsChanged() {
        this.setDefaultSelectedPaymentMethod();
    }
    connectedCallback() {
        this.setDefaultSelectedPaymentMethod();
        this.setComputedHideSubmitButton();
    }
    disconnectedCallback() {
        var _a;
        (_a = this.analytics) === null || _a === void 0 ? void 0 : _a.cleanup();
        if (this.unsubscribeFromStore) {
            this.unsubscribeFromStore();
        }
    }
    componentWillLoad() {
        checkPkgVersion();
        this.analytics = new JustifiAnalytics(this);
    }
    handleRadioClick(event) {
        this.selectedPaymentMethod = event.detail;
        checkoutStore.selectedPaymentMethod = { type: event.detail };
    }
    async tokenizePaymentMethod(event) {
        event === null || event === void 0 ? void 0 : event.preventDefault();
        this.validateRequiredProps();
        this.isLoading = true;
        try {
            const validation = await this.validate();
            if (!validation.isValid) {
                this.errorEvent.emit({
                    errorCode: ComponentErrorCodes.TOKENIZE_ERROR,
                    message: ERROR_MESSAGES.VALIDATION_ERROR,
                });
                this.isLoading = false;
                return;
            }
            const tokenizeResponse = await this.resolvePaymentMethod({ isValid: true });
            if (tokenizeResponse.error) {
                this.emitError({
                    errorCode: tokenizeResponse.error.code,
                    message: tokenizeResponse.error.message,
                });
            }
            this.submitEvent.emit({ response: tokenizeResponse });
            return tokenizeResponse;
        }
        catch (error) {
            const errorResponse = this.createErrorResponse(ComponentErrorCodes.TOKENIZE_ERROR, error.message);
            this.emitError({
                errorCode: ComponentErrorCodes.TOKENIZE_ERROR,
                message: error.message,
            });
            this.submitEvent.emit({ response: errorResponse });
            return errorResponse;
        }
        finally {
            this.isLoading = false;
        }
    }
    async fillBillingForm(fields) {
        checkoutStore.billingFormFields = fields;
    }
    async validate() {
        if (!this.areFormsReady()) {
            return { isValid: false, errors: { general: ERROR_MESSAGES.FORM_NOT_READY } };
        }
        const [billingValidation, paymentMethodValidation] = await Promise.all([
            this.billingFormRef.validate(),
            this.paymentMethodFormRef.validate(),
        ]);
        const result = {
            isValid: billingValidation.isValid && paymentMethodValidation.isValid,
            errors: Object.assign(Object.assign({}, billingValidation.errors), paymentMethodValidation.errors),
        };
        return result;
    }
    async getValues() {
        return this.billingFormRef.getValues();
    }
    async tokenize() {
        try {
            const billingFormFieldValues = await this.billingFormRef.getValues();
            const config = {
                clientId: this.authToken || checkoutStore.authToken,
                account: this.accountId || checkoutStore.accountId,
                paymentMethodMetadata: this.buildPaymentMethodMetadata(billingFormFieldValues),
            };
            const result = await this.paymentMethodFormRef.tokenize(config);
            return result;
        }
        catch (error) {
            return error;
        }
    }
    // 9. Local methods
    validateRequiredProps() {
        if (!this.authToken && !checkoutStore.authToken) {
            this.emitError({
                errorCode: ComponentErrorCodes.TOKENIZE_ERROR,
                message: ERROR_MESSAGES.AUTH_TOKEN_REQUIRED,
            });
        }
        if (!this.accountId && !checkoutStore.accountId) {
            this.emitError({
                errorCode: ComponentErrorCodes.TOKENIZE_ERROR,
                message: ERROR_MESSAGES.ACCOUNT_ID_REQUIRED,
            });
        }
    }
    setDefaultSelectedPaymentMethod() {
        if (this.selectedPaymentMethod) {
            return;
        }
        if (!this.disableCreditCard) {
            this.selectedPaymentMethod = PAYMENT_METHODS.NEW_CARD;
            checkoutStore.selectedPaymentMethod = { type: PAYMENT_METHODS.NEW_CARD };
        }
        else if (!this.disableBankAccount &&
            (!checkoutStore.checkoutLoaded || checkoutStore.achPaymentsEnabled)) {
            this.selectedPaymentMethod = PAYMENT_METHODS.NEW_BANK_ACCOUNT;
            checkoutStore.selectedPaymentMethod = { type: PAYMENT_METHODS.NEW_BANK_ACCOUNT };
        }
    }
    setComputedHideSubmitButton() {
        // If hideSubmitButton prop is explicitly set, use that value
        if (this.hideSubmitButton !== undefined) {
            this.computedHideSubmitButton = this.hideSubmitButton;
            return;
        }
        // Otherwise, auto-detect if component is slotted within modular-checkout
        const isWithinModularCheckout = this.isSlottedWithinModularCheckout();
        this.computedHideSubmitButton = isWithinModularCheckout;
    }
    isSlottedWithinModularCheckout() {
        var _a;
        let parent = (_a = this.host) === null || _a === void 0 ? void 0 : _a.parentElement;
        while (parent) {
            if (parent.tagName === 'JUSTIFI-MODULAR-CHECKOUT') {
                return true;
            }
            parent = parent.parentElement;
        }
        return false;
    }
    get availablePaymentMethods() {
        const methods = [];
        const achAllowedForCheckout = !checkoutStore.checkoutLoaded || checkoutStore.achPaymentsEnabled;
        if (!this.disableCreditCard) {
            methods.push(PAYMENT_METHODS.NEW_CARD);
        }
        if (!this.disableBankAccount && achAllowedForCheckout) {
            methods.push(PAYMENT_METHODS.NEW_BANK_ACCOUNT);
        }
        return methods;
    }
    areFormsReady() {
        return !!(this.billingFormRef && this.paymentMethodFormRef);
    }
    emitError(errorData) {
        this.errorEvent.emit(Object.assign(Object.assign({}, errorData), { severity: ComponentErrorSeverity.ERROR }));
    }
    createErrorResponse(code, message) {
        return {
            error: {
                code: code,
                message,
                decline_code: undefined,
            },
        };
    }
    async resolvePaymentMethod(insuranceValidation) {
        if (!this.areFormsReady()) {
            return this.createErrorResponse('form_not_ready', ERROR_MESSAGES.FORM_NOT_READY);
        }
        try {
            const validation = await this.validate();
            if (!validation.isValid || !insuranceValidation.isValid) {
                const errorMessage = Object.values(validation.errors)[0] || ERROR_MESSAGES.VALIDATION_ERROR;
                return {
                    validationError: true,
                    error: {
                        code: 'validation_error',
                        message: String(errorMessage),
                        decline_code: undefined,
                    },
                };
            }
            const result = await this.performTokenization();
            return result;
        }
        catch (error) {
            return { error };
        }
    }
    async performTokenization() {
        var _a, _b;
        const tokenizeResponse = await this.tokenize();
        if (tokenizeResponse.error) {
            return { error: tokenizeResponse.error };
        }
        const tokenizeResponseData = tokenizeResponse.data;
        const result = {
            token: ((_a = tokenizeResponseData.card) === null || _a === void 0 ? void 0 : _a.token) || ((_b = tokenizeResponseData.bank_account) === null || _b === void 0 ? void 0 : _b.token),
            data: tokenizeResponseData,
        };
        return result;
    }
    buildPaymentMethodMetadata(billingFormFieldValues) {
        return this.shouldSavePaymentMethod
            ? Object.assign(Object.assign({}, billingFormFieldValues), { payment_method_group_id: this.paymentMethodGroupID }) : Object.assign({}, billingFormFieldValues);
    }
    get paymentMethodGroupID() {
        return this.paymentMethodGroupId || checkoutStore.paymentMethodGroupId;
    }
    get shouldSavePaymentMethod() {
        return !!(this.paymentMethodGroupId || checkoutStore.savePaymentMethod);
    }
    get shouldHideRadioInput() {
        return this.disableCreditCard || this.disableBankAccount;
    }
    renderPaymentMethodOption(paymentMethodType) {
        const isSelected = this.selectedPaymentMethod === paymentMethodType && checkoutStore.selectedPaymentMethod.id === undefined;
        return (h("div", { class: "payment-method" }, h("radio-list-item", { name: "paymentMethodType", value: paymentMethodType, checked: isSelected, label: PAYMENT_METHOD_TYPE_LABELS[paymentMethodType], hidden: this.shouldHideRadioInput }), isSelected && this.renderSelectedPaymentMethodForm(paymentMethodType)));
    }
    renderSelectedPaymentMethodForm(paymentMethodType) {
        return (h("div", { class: "mt-4 pb-4" }, this.renderPaymentMethodForm(paymentMethodType), h("div", { class: "mt-4" }, h("billing-form", { ref: (el) => {
                if (el)
                    this.billingFormRef = el;
            }, hideCardBillingForm: this.hideCardBillingForm, hideBankAccountBillingForm: this.hideBankAccountBillingForm, paymentMethodType: paymentMethodType })), h("div", { class: "mt-4" }, h("save-new-payment-method", { hidden: !this.paymentMethodGroupID, label: this.savePaymentMethodLabel }))));
    }
    renderPaymentMethodForm(paymentMethodType) {
        return paymentMethodType === PAYMENT_METHODS.NEW_CARD ? (h("card-form", { ref: (el) => {
                if (el)
                    this.paymentMethodFormRef = el;
            } })) : (h("bank-account-form", { ref: (el) => {
                if (el)
                    this.paymentMethodFormRef = el;
            } }));
    }
    render() {
        return (h(StyledHost, { key: 'bc76697688be332ef84db56e61b6b455a6d1e986' }, h("form", { key: '8f64f55f945d4ff4ed0f144c724dbd71278ec771' }, h("fieldset", { key: '15b6d388117738391089cf91f999247cddb29714' }, h("div", { key: 'a4e23f7808b446dff6f7da437dba3cb57d2d62aa', class: "row gy-3" }, h("div", { key: '63b0584d217d9bb50036eb7d5837e7287be58760', class: "col-12" }, this.availablePaymentMethods.map((method) => this.renderPaymentMethodOption(method))), h("div", { key: 'c9345be3429cd8ab01a84e8584270938feceba39', class: "col-12" }, h("internal-button", { key: 'aa56df7b6b1250e9b81fbc281b969d2a37a05428', text: this.submitButtonText, variant: "primary", type: "submit", clickHandler: (e) => this.tokenizePaymentMethod(e), isLoading: this.isLoading, "data-testid": "submit-button", hidden: this.computedHideSubmitButton })))))));
    }
    get host() { return this; }
    static get watchers() { return {
        "disableCreditCard": ["paymentMethodsChanged"],
        "disableBankAccount": ["paymentMethodsChanged"]
    }; }
}, [257, "justifi-tokenize-payment-method", {
        "accountId": [1, "account-id"],
        "authToken": [1, "auth-token"],
        "disableBankAccount": [4, "disable-bank-account"],
        "disableCreditCard": [4, "disable-credit-card"],
        "hideBankAccountBillingForm": [4, "hide-bank-account-billing-form"],
        "hideCardBillingForm": [4, "hide-card-billing-form"],
        "hideSubmitButton": [4, "hide-submit-button"],
        "paymentMethodGroupId": [1, "payment-method-group-id"],
        "submitButtonText": [1, "submit-button-text"],
        "savePaymentMethodLabel": [1, "save-payment-method-label"],
        "computedHideSubmitButton": [32],
        "isLoading": [32],
        "selectedPaymentMethod": [32],
        "tokenizePaymentMethod": [64],
        "fillBillingForm": [64],
        "validate": [64],
        "getValues": [64],
        "tokenize": [64]
    }, [[0, "radio-click", "handleRadioClick"]], {
        "disableCreditCard": ["paymentMethodsChanged"],
        "disableBankAccount": ["paymentMethodsChanged"]
    }]);
function defineCustomElement() {
    if (typeof customElements === "undefined") {
        return;
    }
    const components = ["justifi-tokenize-payment-method", "bank-account-billing-form-simple", "bank-account-form", "billing-form", "billing-form-full", "card-billing-form-simple", "card-form", "custom-popper", "form-control-checkbox", "form-control-help-text", "form-control-radio", "form-control-select", "form-control-text", "form-control-tooltip", "hidden-input", "iframe-input", "internal-button", "radio-list-item", "save-new-payment-method"];
    components.forEach(tagName => { switch (tagName) {
        case "justifi-tokenize-payment-method":
            if (!customElements.get(tagName)) {
                customElements.define(tagName, JustifiTokenizePaymentMethod);
            }
            break;
        case "bank-account-billing-form-simple":
            if (!customElements.get(tagName)) {
                defineCustomElement$i();
            }
            break;
        case "bank-account-form":
            if (!customElements.get(tagName)) {
                defineCustomElement$h();
            }
            break;
        case "billing-form":
            if (!customElements.get(tagName)) {
                defineCustomElement$g();
            }
            break;
        case "billing-form-full":
            if (!customElements.get(tagName)) {
                defineCustomElement$f();
            }
            break;
        case "card-billing-form-simple":
            if (!customElements.get(tagName)) {
                defineCustomElement$e();
            }
            break;
        case "card-form":
            if (!customElements.get(tagName)) {
                defineCustomElement$d();
            }
            break;
        case "custom-popper":
            if (!customElements.get(tagName)) {
                defineCustomElement$c();
            }
            break;
        case "form-control-checkbox":
            if (!customElements.get(tagName)) {
                defineCustomElement$b();
            }
            break;
        case "form-control-help-text":
            if (!customElements.get(tagName)) {
                defineCustomElement$a();
            }
            break;
        case "form-control-radio":
            if (!customElements.get(tagName)) {
                defineCustomElement$9();
            }
            break;
        case "form-control-select":
            if (!customElements.get(tagName)) {
                defineCustomElement$8();
            }
            break;
        case "form-control-text":
            if (!customElements.get(tagName)) {
                defineCustomElement$7();
            }
            break;
        case "form-control-tooltip":
            if (!customElements.get(tagName)) {
                defineCustomElement$6();
            }
            break;
        case "hidden-input":
            if (!customElements.get(tagName)) {
                defineCustomElement$5();
            }
            break;
        case "iframe-input":
            if (!customElements.get(tagName)) {
                defineCustomElement$4();
            }
            break;
        case "internal-button":
            if (!customElements.get(tagName)) {
                defineCustomElement$3();
            }
            break;
        case "radio-list-item":
            if (!customElements.get(tagName)) {
                defineCustomElement$2();
            }
            break;
        case "save-new-payment-method":
            if (!customElements.get(tagName)) {
                defineCustomElement$1();
            }
            break;
    } });
}
defineCustomElement();

export { JustifiTokenizePaymentMethod as J, defineCustomElement as d };
