import { Host, h } from "@stencil/core";
import { ComponentErrorCodes, ComponentErrorSeverity } from "../../../../api/ComponentError";
import { makeGetBusiness, makePatchBusiness } from "../payment-provisioning-actions";
import { BusinessService } from "../../../../api/services/business.service";
import { Button } from "../../../../ui-components";
import { heading2, alert } from "../../../../styles/parts";
import { PaymentProvisioningLoading } from "../payment-provisioning-loading";
import { BusinessFormClickActions, BusinessFormStep } from "../../utils/event-types";
import { Representative } from "../../../../api/Identity";
export class BusinessOwnersFormStep {
    constructor() {
        this.ownersPayload = [];
        this.refs = [];
        this.isLoading = false;
        this.representativeIsOwner = null;
        this.matchRef = (ref, ownerId) => {
            if (ref === null)
                return;
            const ownerIndex = this.ownersPayload.findIndex(owner => owner.id === ownerId);
            if (ownerIndex !== -1) {
                // Ensure refs array is properly sized before setting ref
                if (this.refs.length !== this.ownersPayload.length) {
                    this.manageRefs();
                }
                this.refs[ownerIndex] = ref;
            }
        };
        this.getData = () => {
            this.formLoading.emit(true);
            this.isLoading = true;
            this.getBusiness({
                onSuccess: (response) => {
                    this.representative = new Representative(response.data.representative || {});
                    if (response.data.owners.length) {
                        this.ownersPayload = response.data.owners.map(owner => ({ id: owner.id }));
                    }
                    else {
                        this.addOwnerForm();
                    }
                },
                onError: ({ error, code, severity }) => {
                    this.errorEvent.emit({
                        message: error,
                        errorCode: code,
                        severity: severity
                    });
                },
                final: () => {
                    this.formLoading.emit(false);
                    this.isLoading = false;
                    this.manageRefs();
                }
            });
        };
        this.sendData = async (onSuccess) => {
            let submittedData;
            this.formLoading.emit(true);
            this.patchBusiness({
                payload: { owners: this.ownersPayload },
                onSuccess: (response) => {
                    submittedData = response;
                    onSuccess();
                },
                onError: ({ error, code, severity }) => {
                    submittedData = error;
                    this.errorEvent.emit({
                        message: error,
                        errorCode: code,
                        severity: severity
                    });
                },
                final: () => {
                    this.stepCompleteEvent.emit({ response: submittedData, formStep: BusinessFormStep.owners });
                    this.formLoading.emit(false);
                }
            });
        };
        this.addOwnerForm = (fireClick) => {
            this.newFormOpen = true;
            this.ownersPayload = [...this.ownersPayload, { id: '' }];
            fireClick && this.clickEvent.emit({ name: BusinessFormClickActions.addOwnerForm });
        };
        this.removeOwnerForm = (id) => {
            this.ownersPayload = this.ownersPayload.filter(owner => owner.id !== id);
            this.newFormOpen && (this.newFormOpen = false);
        };
        this.handleRepresentativeIsOwnerChange = (value) => {
            this.representativeIsOwner = value;
            if (this.representativeIsOwner) {
                this.formLoading.emit(true);
                this.isLoading = true;
                this.ownersPayload = this.ownersPayload.filter(owner => owner.id !== '');
                this.patchBusiness({
                    payload: {
                        representative: { is_owner: true },
                        owners: [{ id: this.representative.id }, ...this.ownersPayload],
                    },
                    onSuccess: () => {
                        this.getData();
                        this.newFormOpen = false;
                    },
                    finally: () => {
                        this.isLoading = false;
                        this.formLoading.emit(false);
                    }
                });
            }
        };
    }
    propChanged() {
        this.initializeApi();
    }
    get showAddOwnerButton() {
        return this.ownersPayload.length < 4 && !this.newFormOpen;
    }
    manageRefs() {
        this.refs = this.ownersPayload.map((owner) => { return owner.id; });
    }
    async validateAndSubmit({ onSuccess }) {
        const formValidations = this.refs.map(ref => ref.validate());
        const formsValid = (await Promise.all(formValidations)).every(result => result);
        if (!formsValid) {
            return;
        }
        if (!this.allowOptionalFields) {
            const percentages = await Promise.all(this.refs.map(ref => ref.getOwnershipPercentage()));
            const total = percentages.reduce((sum, p) => sum + (parseFloat(p) || 0), 0);
            if (total > 100) {
                await Promise.all(this.refs.map(ref => ref.setOwnershipPercentageError('Ownership percentages cannot exceed 100%')));
                return;
            }
        }
        const formSubmissions = this.refs.map(ref => ref.submit());
        const submissionsValid = (await Promise.all(formSubmissions)).every(result => result);
        if (!submissionsValid) {
            return;
        }
        this.sendData(onSuccess);
    }
    componentWillLoad() {
        this.initializeApi();
        if (this.getBusiness) {
            this.getData();
        }
    }
    initializeApi() {
        if (this.authToken && this.businessId) {
            this.getBusiness = makeGetBusiness({
                authToken: this.authToken,
                businessId: this.businessId,
                service: new BusinessService()
            });
            this.patchBusiness = makePatchBusiness({
                authToken: this.authToken,
                businessId: this.businessId,
                service: new BusinessService()
            });
        }
        else {
            this.errorEvent.emit({
                message: 'Missing required props',
                errorCode: ComponentErrorCodes.MISSING_PROPS,
                severity: ComponentErrorSeverity.ERROR,
            });
        }
    }
    ownersWatcher() {
        this.manageRefs();
    }
    handleOwnerSubmit(event) {
        const submittedOwner = event.detail;
        const updatedOwners = this.ownersPayload.map(owner => owner.id === submittedOwner.id ? submittedOwner : owner);
        if (!updatedOwners.includes(submittedOwner)) {
            const newOwnerIndex = this.ownersPayload.findIndex(owner => !owner.id);
            updatedOwners[newOwnerIndex] = submittedOwner;
            this.newFormOpen && (this.newFormOpen = false);
        }
        this.ownersPayload = updatedOwners;
    }
    render() {
        if (this.isLoading) {
            return (h(Host, null, h(PaymentProvisioningLoading, null)));
        }
        const isRepresentativeOwner = this.ownersPayload.some(owner => owner.id === this.representative.id);
        const shouldShowRepresentativeIsOwner = this.representativeIsOwner === null && !isRepresentativeOwner;
        return (h(Host, null, h("div", null, h("div", { class: "d-flex align-items-center gap-2" }, h("legend", { class: "mb-0", part: heading2 }, "Owners"), h("form-control-tooltip", { helpText: "For partnerships, LLCs or privately held corporations, the business is required to apply with all individuals with 25% or more ownership to the application. For charities and registered non-profits, the business is required to apply with 1 individual with substantial control over the entity, such as a board member or director." })), h("hr", { class: "mt-2" }), shouldShowRepresentativeIsOwner && (h("div", { class: `alert alert-warning mb-3`, part: alert }, h("div", { class: "card-body" }, h("div", { class: "d-flex align-items-center mb-3" }, h("strong", null, "Is the representative of this business also an owner?")), h("div", { class: "d-flex gap-2" }, h(Button, { variant: 'primary', onClick: () => this.handleRepresentativeIsOwnerChange(true) }, "Yes"), h(Button, { variant: 'secondary', onClick: () => this.handleRepresentativeIsOwnerChange(false) }, "No"))))), h("div", { class: 'row gy-3' }, this.ownersPayload.map((owner) => {
            return (h("owner-form", { key: owner.id, authToken: this.authToken, businessId: this.businessId, ownerId: owner.id, removeOwner: this.removeOwnerForm, newFormOpen: this.newFormOpen, ownersLength: this.ownersPayload.length, country: this.country, allowOptionalFields: this.allowOptionalFields, ref: (ref) => this.matchRef(ref, owner.id) }));
        })), h("div", { class: 'd-flex justify-content-start' }, h("div", { class: 'gap-2' }, h(Button, { variant: 'primary', onClick: () => this.addOwnerForm(true), hidden: !this.showAddOwnerButton }, "Add Owner"))))));
    }
    static get is() { return "business-owners-form-step"; }
    static get properties() {
        return {
            "authToken": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": true,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "auth-token"
            },
            "businessId": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": true,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "business-id"
            },
            "allowOptionalFields": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "allow-optional-fields"
            },
            "country": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "CountryCode",
                    "resolved": "CountryCode.CAN | CountryCode.USA",
                    "references": {
                        "CountryCode": {
                            "location": "import",
                            "path": "../../../../utils/country-codes",
                            "id": "src/utils/country-codes.ts::CountryCode"
                        }
                    }
                },
                "required": true,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "country"
            }
        };
    }
    static get states() {
        return {
            "getBusiness": {},
            "patchBusiness": {},
            "ownersPayload": {},
            "refs": {},
            "newFormOpen": {},
            "isLoading": {},
            "representativeIsOwner": {},
            "representative": {}
        };
    }
    static get events() {
        return [{
                "method": "clickEvent",
                "name": "click-event",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "complexType": {
                    "original": "ComponentClickEvent",
                    "resolved": "ComponentClickEvent",
                    "references": {
                        "ComponentClickEvent": {
                            "location": "import",
                            "path": "../../../../api/ComponentEvents",
                            "id": "src/api/ComponentEvents.ts::ComponentClickEvent"
                        }
                    }
                }
            }, {
                "method": "stepCompleteEvent",
                "name": "complete-form-step-event",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "complexType": {
                    "original": "ComponentFormStepCompleteEvent",
                    "resolved": "ComponentFormStepCompleteEvent",
                    "references": {
                        "ComponentFormStepCompleteEvent": {
                            "location": "import",
                            "path": "../../../../api/ComponentEvents",
                            "id": "src/api/ComponentEvents.ts::ComponentFormStepCompleteEvent"
                        }
                    }
                }
            }, {
                "method": "errorEvent",
                "name": "error-event",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "complexType": {
                    "original": "ComponentErrorEvent",
                    "resolved": "ComponentErrorEvent",
                    "references": {
                        "ComponentErrorEvent": {
                            "location": "import",
                            "path": "../../../../api/ComponentEvents",
                            "id": "src/api/ComponentEvents.ts::ComponentErrorEvent"
                        }
                    }
                }
            }, {
                "method": "formLoading",
                "name": "formLoading",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                }
            }];
    }
    static get methods() {
        return {
            "validateAndSubmit": {
                "complexType": {
                    "signature": "({ onSuccess }: { onSuccess: any; }) => Promise<void>",
                    "parameters": [{
                            "name": "__0",
                            "type": "{ onSuccess: any; }",
                            "docs": ""
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "",
                    "tags": []
                }
            }
        };
    }
    static get watchers() {
        return [{
                "propName": "authToken",
                "methodName": "propChanged"
            }, {
                "propName": "businessId",
                "methodName": "propChanged"
            }, {
                "propName": "ownersPayload",
                "methodName": "ownersWatcher"
            }];
    }
    static get listeners() {
        return [{
                "name": "ownerSubmitted",
                "method": "handleOwnerSubmit",
                "target": undefined,
                "capture": false,
                "passive": false
            }];
    }
}
