import { proxyCustomElement, HTMLElement, createEvent, h } from '@stencil/core/internal/client';
import './config-state.js';
import './dinero.js';
import { C as ComponentErrorSeverity, a as ComponentErrorCodes } from './Plaid.js';
import './Pagination.js';
import { a as CountryCode } from './Business.js';
import './ApplePay.js';
import { m as makeGetBusiness, f as makePostBankAccount } from './payment-provisioning-actions.js';
import { B as BusinessService, a as BusinessBankAccountService } from './business.service.js';
import { c as create$3, a as create$6, F as FormController } from './form.js';
import { B as accountNumberValidation, C as accountTypeValidation, i as identityNameValidation, D as nicknameValidation, E as bankNameValidation, F as numbersOnlyRegex, G as routingNumberValidation } from './schema-validations.js';
import { B as BusinessFormStep } from './event-types2.js';
import { A as buttonSecondary, a1 as buttonLink, h as heading2 } from './parts.js';
import { P as PaymentProvisioningLoading } from './payment-provisioning-loading.js';
import { B as Button } from './button.js';
import './justifi-details2.js';
import './event-types.js';
import './justifi-radio-list-item2.js';
import { d as defineCustomElement$8 } from './bank-account-form-inputs2.js';
import { d as defineCustomElement$7 } from './bank-account-form-inputs-canada2.js';
import { d as defineCustomElement$6 } from './bank-account-read-only-value2.js';
import { d as defineCustomElement$5 } from './custom-popper2.js';
import { d as defineCustomElement$4 } from './form-control-select2.js';
import { d as defineCustomElement$3 } from './form-control-text2.js';
import { d as defineCustomElement$2 } from './form-control-tooltip2.js';
import { d as defineCustomElement$1 } from './plaid-verification2.js';

class BankAccount {
    constructor(data) {
        this.id = data.id;
        this.account_owner_name = data.account_owner_name;
        this.full_name = data.full_name;
        this.account_type = data.account_type;
        this.account_number = data.account_number;
        this.acct_last_four = data.acct_last_four;
        this.account_number_last4 = data.account_number_last4;
        this.routing_number = data.routing_number;
        this.institution_number = data.institution_number;
        this.transit_number = data.transit_number;
        this.bank_name = data.bank_name;
        this.country = data.country;
        this.currency = data.currency;
        this.nickname = data.nickname;
        this.metadata = data.metadata;
        this.business_id = data.business_id;
        this.platform_account_id = data.platform_account_id;
        this.created_at = data.created_at;
        this.updated_at = data.updated_at;
    }
    get payload() {
        return {
            account_owner_name: this.account_owner_name || '',
            account_type: this.account_type || '',
            account_number: this.account_number || '',
            routing_number: this.routing_number || '',
            institution_number: this.institution_number || '',
            transit_number: this.transit_number || '',
            bank_name: this.bank_name || '',
            nickname: this.nickname || '',
            business_id: this.business_id || '',
        };
    }
}

const buildCommonFieldRules = (allowOptionalFields) => {
    if (allowOptionalFields) {
        return {
            bank_name: bankNameValidation.nullable(),
            nickname: nicknameValidation.nullable(),
            account_owner_name: identityNameValidation.nullable(),
            account_type: accountTypeValidation.nullable(),
            account_number: accountNumberValidation.nullable(),
        };
    }
    return {
        bank_name: bankNameValidation.required('Enter bank name'),
        nickname: nicknameValidation.required('Enter nickname'),
        account_owner_name: identityNameValidation.required('Enter account owner name'),
        account_type: accountTypeValidation.required('Select account type'),
        account_number: accountNumberValidation.required('Enter account number'),
    };
};
const buildUSARules = (allowOptionalFields) => {
    if (allowOptionalFields) {
        return { routing_number: routingNumberValidation.nullable() };
    }
    return { routing_number: routingNumberValidation.required('Enter routing number') };
};
const buildCANRules = (allowOptionalFields) => {
    const institutionNumberValidation = create$6()
        .length(3, 'Institution number must be 3 digits')
        .matches(numbersOnlyRegex, 'Enter valid institution number');
    const transitNumberValidation = create$6()
        .length(5, 'Transit number must be 5 digits')
        .matches(numbersOnlyRegex, 'Enter valid transit number');
    if (allowOptionalFields) {
        return {
            institution_number: institutionNumberValidation.nullable(),
            transit_number: transitNumberValidation.nullable(),
        };
    }
    return {
        institution_number: institutionNumberValidation.required('Enter institution number'),
        transit_number: transitNumberValidation.required('Enter transit number'),
    };
};
const businessBankAccountSchemaUSA = (allowOptionalFields) => {
    const shape = Object.assign(Object.assign({}, buildCommonFieldRules(allowOptionalFields)), buildUSARules(allowOptionalFields));
    return create$3().shape(shape);
};
const businessBankAccountSchemaCAN = (allowOptionalFields) => {
    const shape = Object.assign(Object.assign({}, buildCommonFieldRules(allowOptionalFields)), buildCANRules(allowOptionalFields));
    return create$3().shape(shape);
};
const bankAccountSchemaByCountry = {
    [CountryCode.USA]: (allowOptionalFields) => businessBankAccountSchemaUSA(allowOptionalFields),
    [CountryCode.CAN]: (allowOptionalFields) => businessBankAccountSchemaCAN(allowOptionalFields),
};

const BusinessBankAccountFormStep = /*@__PURE__*/ proxyCustomElement(class BusinessBankAccountFormStep extends HTMLElement {
    constructor(registerHost) {
        super();
        if (registerHost !== false) {
            this.__registerHost();
        }
        this.errorEvent = createEvent(this, "error-event", 7);
        this.stepCompleteEvent = createEvent(this, "complete-form-step-event", 7);
        this.formLoading = createEvent(this, "formLoading", 7);
        this.errors = {};
        this.bankAccount = {};
        this.isLoading = false;
        this.viewMode = 'manual';
        this.bankAccountVerification = false;
        this.platformAccountId = null;
        this.getSchema = () => {
            const schema = bankAccountSchemaByCountry[this.country];
            return schema(this.allowOptionalFields);
        };
        this.initializeFormController = () => {
            this.formController = new FormController(this.getSchema());
            if (this.viewMode === 'readonly') {
                this.formController.setInitialValues(Object.assign({}, this.bankAccount));
            }
            else {
                this.formController.setInitialValues({ business_id: this.businessId });
            }
            this.formController.errors.subscribe(errors => {
                this.errors = Object.assign({}, errors);
            });
        };
        this.inputHandler = (name, value) => {
            this.formController.setValues(Object.assign(Object.assign({}, this.formController.values.getValue()), { [name]: value }));
        };
        this.getData = () => {
            this.isLoading = true;
            this.getBusiness({
                onSuccess: (response) => {
                    this.processBusinessResponse(response.data);
                    this.determineViewMode();
                },
                onError: ({ error, code, severity }) => {
                    this.errorEvent.emit({
                        message: error,
                        errorCode: code,
                        severity: severity
                    });
                },
                final: () => {
                    this.initializeFormController();
                    this.isLoading = false;
                }
            });
        };
        this.handleChangeBankAccount = () => {
            this.viewMode = this.plaidAvailable ? 'plaid' : 'manual';
            this.initializeFormController();
        };
        this.handleCancel = () => {
            this.viewMode = this.existingBankAccount ? 'readonly' : 'plaid';
            this.initializeFormController();
        };
        this.handleToggleToManualEntry = () => {
            this.viewMode = 'manual';
        };
        this.handleToggleToPlaidVerification = () => {
            this.viewMode = 'plaid';
        };
        this.handleSaveBankAccount = async () => {
            this.formController.validateAndSubmit(() => {
                this.sendData(() => {
                    // Success callback - form will refresh automatically
                });
            });
        };
    }
    propChanged() {
        this.initializeApi();
    }
    watchHandler(newValue) {
        this.formLoading.emit(newValue);
    }
    async validateAndSubmit({ onSuccess }) {
        if (this.viewMode === 'readonly') {
            this.sendData(onSuccess);
        }
        else {
            this.formController.validateAndSubmit(() => this.sendData(onSuccess));
        }
    }
    componentWillLoad() {
        this.initializeApi();
        if (this.getBusiness) {
            this.getData();
        }
        this.formController = new FormController(this.getSchema());
    }
    componentDidLoad() {
        this.formController.errors.subscribe(errors => {
            this.errors = Object.assign({}, errors);
        });
    }
    initializeApi() {
        if (this.authToken && this.businessId) {
            this.getBusiness = makeGetBusiness({
                authToken: this.authToken,
                businessId: this.businessId,
                service: new BusinessService()
            });
            this.postBankAccount = makePostBankAccount({
                authToken: this.authToken,
                service: new BusinessBankAccountService()
            });
        }
        else {
            this.errorEvent.emit({
                message: 'Missing required props',
                errorCode: ComponentErrorCodes.MISSING_PROPS,
                severity: ComponentErrorSeverity.ERROR,
            });
        }
    }
    get postPayload() {
        const values = this.formController.values.getValue();
        const formValues = new BankAccount(values).payload;
        return formValues;
    }
    get existingBankAccount() {
        var _a;
        return !!((_a = this.bankAccount) === null || _a === void 0 ? void 0 : _a.id);
    }
    get plaidAvailable() {
        return this.bankAccountVerification && !!this.platformAccountId;
    }
    get showCancel() {
        return this.bankAccountVerification || this.existingBankAccount;
    }
    processBusinessResponse(data) {
        const { bank_accounts, settings, platform_account_id } = data;
        if (bank_accounts.length > 0) {
            this.bankAccount = new BankAccount(bank_accounts[bank_accounts.length - 1]);
        }
        else {
            this.bankAccount = new BankAccount({});
            this.bankAccount.business_id = this.businessId;
        }
        this.bankAccountVerification = settings.bank_account_verification === true;
        this.platformAccountId = platform_account_id;
    }
    determineViewMode() {
        if (this.existingBankAccount) {
            this.viewMode = 'readonly';
        }
        else if (this.plaidAvailable) {
            this.viewMode = 'plaid';
        }
        else {
            this.viewMode = 'manual';
        }
    }
    async sendData(onSuccess) {
        try {
            if (this.viewMode === 'manual') {
                const bankAccountPosted = await this.postBankAccountData();
                if (!bankAccountPosted)
                    return;
                this.viewMode = 'readonly';
                await this.refreshBankAccountData();
            }
            onSuccess();
        }
        catch (error) {
            this.errorEvent.emit({
                message: error,
                errorCode: ComponentErrorCodes.POST_ERROR,
                severity: ComponentErrorSeverity.ERROR
            });
        }
    }
    async postBankAccountData() {
        let submittedData;
        this.isLoading = true;
        return new Promise((resolve) => {
            let success = false;
            this.postBankAccount({
                payload: this.postPayload,
                onSuccess: (response) => {
                    submittedData = response;
                    success = true;
                },
                onError: ({ error, code, severity }) => {
                    success = false;
                    this.errorEvent.emit({
                        message: error,
                        errorCode: code,
                        severity: severity
                    });
                },
                final: () => {
                    this.stepCompleteEvent.emit({ response: submittedData, formStep: BusinessFormStep.bankAccount });
                    this.isLoading = false;
                    resolve(success);
                }
            });
        });
    }
    async refreshBankAccountData() {
        return new Promise((resolve) => {
            this.isLoading = true;
            this.getBusiness({
                onSuccess: (response) => {
                    this.processBusinessResponse(response.data);
                    this.determineViewMode();
                    this.initializeFormController();
                },
                onError: ({ error, code, severity }) => {
                    this.errorEvent.emit({
                        message: error,
                        errorCode: code,
                        severity: severity
                    });
                },
                final: () => {
                    this.isLoading = false;
                    resolve();
                }
            });
        });
    }
    renderBankAccountInputs(disabled) {
        const defaultValue = this.formController.getInitialValues();
        return this.country === CountryCode.CAN ? (h("bank-account-form-inputs-canada", { defaultValue: defaultValue, errors: this.errors, inputHandler: this.inputHandler, formDisabled: disabled })) : (h("bank-account-form-inputs", { defaultValue: defaultValue, errors: this.errors, inputHandler: this.inputHandler, formDisabled: disabled }));
    }
    renderReadonlyView() {
        return (h("div", null, this.renderBankAccountInputs(true), h("div", { class: "mt-3" }, h(Button, { variant: "secondary", type: "button", onClick: this.handleChangeBankAccount, disabled: this.isLoading, part: buttonSecondary }, "Change Bank Account"))));
    }
    renderPlaidView() {
        return (h("div", { class: "mt-3" }, h("plaid-verification", { authToken: this.authToken, accountId: this.platformAccountId, businessId: this.businessId, onPlaidVerificationSuccess: () => {
                this.viewMode = 'readonly';
                this.refreshBankAccountData();
            } }), h("div", { class: "mt-3" }, h(Button, { type: "button", variant: "link", className: "p-0", onClick: this.handleToggleToManualEntry, disabled: this.isLoading, part: buttonLink }, "Enter bank details manually (document upload required)"))));
    }
    renderManualEntryView() {
        return (h("div", null, this.plaidAvailable && (h("div", { class: "mb-3" }, h(Button, { type: "button", variant: "secondary", onClick: this.handleToggleToPlaidVerification, disabled: this.isLoading, part: buttonSecondary }, "Link bank account with Plaid instead"))), this.renderBankAccountInputs(false), h("div", { class: "mt-3 d-flex gap-2" }, this.showCancel && (h(Button, { variant: "secondary", type: "button", onClick: this.handleCancel, disabled: this.isLoading, part: buttonSecondary }, "Cancel")), h(Button, { variant: "primary", type: "button", onClick: this.handleSaveBankAccount, disabled: this.isLoading, isLoading: this.isLoading }, "Save Bank Account"))));
    }
    render() {
        if (this.isLoading) {
            return h(PaymentProvisioningLoading, null);
        }
        return (h("form", null, h("fieldset", { class: "mb-4" }, h("div", { class: "d-flex align-items-center gap-2" }, h("legend", { class: "mb-0", part: heading2 }, "Bank Account Info"), h("form-control-tooltip", { helpText: "This direct deposit account is the designated bank account where incoming funds will be deposited. The name of this account must match the registered business name exactly. We are not able to accept personal accounts unless your business is a registered sole proprietorship." })), h("hr", { class: "mt-2" }), this.viewMode === 'readonly' && this.renderReadonlyView(), this.viewMode === 'plaid' && this.renderPlaidView(), this.viewMode === 'manual' && this.renderManualEntryView())));
    }
    static get watchers() { return {
        "authToken": ["propChanged"],
        "businessId": ["propChanged"],
        "isLoading": ["watchHandler"]
    }; }
}, [256, "business-bank-account-form-step", {
        "authToken": [1, "auth-token"],
        "businessId": [1, "business-id"],
        "allowOptionalFields": [4, "allow-optional-fields"],
        "country": [1],
        "formController": [32],
        "errors": [32],
        "bankAccount": [32],
        "isLoading": [32],
        "viewMode": [32],
        "getBusiness": [32],
        "postBankAccount": [32],
        "bankAccountVerification": [32],
        "platformAccountId": [32],
        "validateAndSubmit": [64]
    }, undefined, {
        "authToken": ["propChanged"],
        "businessId": ["propChanged"],
        "isLoading": ["watchHandler"]
    }]);
function defineCustomElement() {
    if (typeof customElements === "undefined") {
        return;
    }
    const components = ["business-bank-account-form-step", "bank-account-form-inputs", "bank-account-form-inputs-canada", "bank-account-read-only-value", "custom-popper", "form-control-select", "form-control-text", "form-control-tooltip", "plaid-verification"];
    components.forEach(tagName => { switch (tagName) {
        case "business-bank-account-form-step":
            if (!customElements.get(tagName)) {
                customElements.define(tagName, BusinessBankAccountFormStep);
            }
            break;
        case "bank-account-form-inputs":
            if (!customElements.get(tagName)) {
                defineCustomElement$8();
            }
            break;
        case "bank-account-form-inputs-canada":
            if (!customElements.get(tagName)) {
                defineCustomElement$7();
            }
            break;
        case "bank-account-read-only-value":
            if (!customElements.get(tagName)) {
                defineCustomElement$6();
            }
            break;
        case "custom-popper":
            if (!customElements.get(tagName)) {
                defineCustomElement$5();
            }
            break;
        case "form-control-select":
            if (!customElements.get(tagName)) {
                defineCustomElement$4();
            }
            break;
        case "form-control-text":
            if (!customElements.get(tagName)) {
                defineCustomElement$3();
            }
            break;
        case "form-control-tooltip":
            if (!customElements.get(tagName)) {
                defineCustomElement$2();
            }
            break;
        case "plaid-verification":
            if (!customElements.get(tagName)) {
                defineCustomElement$1();
            }
            break;
    } });
}
defineCustomElement();

export { BusinessBankAccountFormStep as B, defineCustomElement as d };
