import { proxyCustomElement, HTMLElement, createEvent, h } from '@stencil/core/internal/client';
import './config-state.js';
import './dinero.js';
import { f as EntityDocument, 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, e as makePostDocumentRecord } from './payment-provisioning-actions.js';
import { B as BusinessService, D as DocumentRecordService } from './business.service.js';
import { B as BusinessFormStep } from './event-types2.js';
import { h as heading2 } from './parts.js';
import { P as PaymentProvisioningLoading } from './payment-provisioning-loading.js';
import { d as defineCustomElement$6 } from './business-documents-on-file2.js';
import { d as defineCustomElement$5 } from './custom-popper2.js';
import { d as defineCustomElement$4 } from './document-upload-list2.js';
import { d as defineCustomElement$3 } from './form-control-file2.js';
import { d as defineCustomElement$2 } from './form-control-select2.js';
import { d as defineCustomElement$1 } from './form-control-tooltip2.js';

const businessDocumentOptions = [
    { label: 'Select a document type', value: '' },
    { label: 'Articles of Incorporation', value: 'articles_of_incorporation' },
    { label: 'Business Registration', value: 'business_registration' },
];
const financialDocumentOptions = [
    { label: 'Select a document type', value: '' },
    { label: 'Voided Check', value: 'voided_check' },
    { label: 'Bank Statement', value: 'bank_statement' },
];
const financialDocumentOptionsCAN = [
    { label: 'Select a document type', value: '' },
    { label: 'Voided Check', value: 'voided_check' },
    { label: 'Bank Letter', value: 'bank_statement' },
];
const personalDocGroup1Options = [
    { label: 'Select a document type', value: '' },
    { label: 'Canadian Passport', value: 'passport' },
    { label: 'Canadian Driver\'s License', value: 'driver_license' },
    { label: 'Canadian Government Issued ID Card', value: 'government_id' },
    { label: 'Permanent Resident Card', value: 'resident_card' },
    { label: 'Certificate of Indian Status', value: 'status_card' },
    { label: 'US State Issued Driver\'s License', value: 'driver_license' },
];
const personalDocGroup2Options = [
    { label: 'Select a document type', value: '' },
    { label: 'Nexus Card (Photo ID)', value: 'nexus_card' },
    { label: 'Canadian Citizenship/Naturalization Card or Certificate', value: 'citizenship_card' },
    { label: 'Foreign Passport', value: 'foreign_passport' },
    { label: 'Canadian Birth Certificate', value: 'birth_certificate' },
    { label: 'Social Insurance Number (SIN) Card', value: 'sin_card' },
    { label: 'Social Security Number (SSN) Card', value: 'ssn_card' },
];
function buildStaticCategories(country) {
    const financialOptions = country === CountryCode.CAN
        ? financialDocumentOptionsCAN
        : financialDocumentOptions;
    return [
        {
            label: 'Business Document',
            value: 'business_document',
            docTypeOptions: businessDocumentOptions,
        },
        {
            label: 'Financial Document',
            value: 'financial_document',
            docTypeOptions: financialOptions,
        },
    ];
}
function buildPersonalDocumentCategories() {
    return [
        {
            label: 'Identity Document - Group 1',
            value: 'personal_group1',
            docTypeOptions: personalDocGroup1Options,
        },
        {
            label: 'Identity Document - Group 2',
            value: 'personal_group2',
            docTypeOptions: personalDocGroup2Options,
        },
    ];
}
const financialOnlyCategories = [
    {
        label: 'Financial Document',
        value: 'financial_document',
        docTypeOptions: financialDocumentOptions,
    },
];
function buildAllCategories(country) {
    if (country === CountryCode.USA) {
        return financialOnlyCategories;
    }
    return [...buildStaticCategories(country), ...buildPersonalDocumentCategories()];
}
const personalDocGroup1Types = new Set(personalDocGroup1Options.filter(o => o.value).map(o => o.value));
const personalDocGroup2Types = new Set(personalDocGroup2Options.filter(o => o.value).map(o => o.value));

const DocumentUploadFormStep = /*@__PURE__*/ proxyCustomElement(class DocumentUploadFormStep 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.owners = [];
        this.existingDocuments = [];
        this.selectedCategory = '';
        this.selectedDocType = '';
        this.uploadQueue = [];
        this.isLoading = false;
        this.errors = {};
        this.fileInputKey = 0;
        this.categories = [];
        this.getData = () => {
            this.isLoading = true;
            this.getBusiness({
                onSuccess: (response) => {
                    const { owners, documents } = response.data;
                    this.owners = owners || [];
                    this.existingDocuments = documents || [];
                    this.categories = buildAllCategories(this.country);
                },
                onError: ({ error, code, severity }) => {
                    this.errorEvent.emit({
                        message: error,
                        errorCode: code,
                        severity: severity,
                    });
                },
                final: () => {
                    this.isLoading = false;
                }
            });
        };
        this.handleCategoryChange = (_name, value) => {
            this.selectedCategory = value;
            this.selectedDocType = '';
        };
        this.handleDocTypeChange = (_name, value) => {
            if (value.startsWith('_') && value.endsWith('_header'))
                return;
            this.selectedDocType = value;
        };
        this.handleFileSelected = async (e) => {
            const fileList = Array.from(e.detail.fileList);
            const category = this.categories.find(c => c.value === this.selectedCategory);
            if (!category)
                return;
            const docTypeOption = category.docTypeOptions.find(o => o.value === this.selectedDocType);
            const docTypeLabel = (docTypeOption === null || docTypeOption === void 0 ? void 0 : docTypeOption.label) || this.selectedDocType;
            const newEntries = fileList.map(file => ({
                categoryLabel: category.label,
                categoryValue: category.value,
                docTypeLabel,
                docTypeValue: this.selectedDocType,
                fileName: file.name,
                file,
                status: 'uploading',
            }));
            const startIndex = this.uploadQueue.length;
            this.uploadQueue = [...this.uploadQueue, ...newEntries];
            this.selectedCategory = '';
            this.selectedDocType = '';
            this.fileInputKey++;
            await Promise.all(newEntries.map(async (entry, i) => {
                const index = startIndex + i;
                try {
                    const docData = new EntityDocument({ file: entry.file, document_type: entry.docTypeValue }, this.businessId);
                    const recordCreated = await this.postDocumentRecordData(docData);
                    if (!recordCreated) {
                        this.uploadQueue = this.uploadQueue.map((e, j) => j === index ? Object.assign(Object.assign({}, e), { status: 'error' }) : e);
                        return;
                    }
                    const uploaded = await this.uploadDocument(docData);
                    this.uploadQueue = this.uploadQueue.map((e, j) => j === index ? Object.assign(Object.assign({}, e), { status: uploaded ? 'uploaded' : 'error' }) : e);
                }
                catch (_a) {
                    this.uploadQueue = this.uploadQueue.map((e, j) => j === index ? Object.assign(Object.assign({}, e), { status: 'error' }) : e);
                }
            }));
        };
        this.postDocumentRecordData = async (docData) => {
            const payload = docData.record_data;
            return new Promise((resolve) => {
                this.postDocumentRecord({
                    payload,
                    onSuccess: (response) => {
                        resolve(this.handleDocRecordResponse(docData, response));
                    },
                    onError: ({ error, code, severity }) => {
                        this.errorEvent.emit({
                            message: error,
                            errorCode: code,
                            severity: severity,
                        });
                        resolve(false);
                    },
                });
            });
        };
        this.handleDocRecordResponse = (docData, response) => {
            if (response.error) {
                this.errorEvent.emit({
                    errorCode: ComponentErrorCodes.POST_ERROR,
                    message: response.error.message,
                    severity: ComponentErrorSeverity.ERROR,
                    data: response.error,
                });
                return false;
            }
            else {
                docData.setPresignedUrl(response.data.presigned_url);
                return true;
            }
        };
        this.uploadDocument = async (docData) => {
            if (!docData.presigned_url) {
                throw new Error('Presigned URL is not set');
            }
            const fileData = await docData.getFileData();
            const response = await fetch(docData.presigned_url, {
                method: 'PUT',
                body: fileData,
            });
            if (!response.ok) {
                this.errorEvent.emit({
                    errorCode: ComponentErrorCodes.POST_ERROR,
                    message: 'Failed to upload document',
                    severity: ComponentErrorSeverity.ERROR,
                });
                return false;
            }
            return true;
        };
    }
    propChanged() {
        this.initializeApi();
    }
    watchHandler(newValue) {
        this.formLoading.emit(newValue);
    }
    async validateAndSubmit({ onSuccess }) {
        const validationErrors = this.validate();
        if (Object.keys(validationErrors).length > 0) {
            this.errors = validationErrors;
            return;
        }
        this.errors = {};
        this.stepCompleteEvent.emit({ response: null, formStep: BusinessFormStep.documentUpload });
        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.postDocumentRecord = makePostDocumentRecord({
                authToken: this.authToken,
                service: new DocumentRecordService()
            });
        }
        else {
            this.errorEvent.emit({
                message: 'Missing required props',
                errorCode: ComponentErrorCodes.MISSING_PROPS,
                severity: ComponentErrorSeverity.ERROR,
            });
        }
    }
    get categoryOptions() {
        return [
            { label: 'Select a category', value: '' },
            ...this.categories.map(c => ({ label: c.label, value: c.value })),
        ];
    }
    get docTypeOptions() {
        if (!this.selectedCategory) {
            return [{ label: 'Select a category first', value: '' }];
        }
        const category = this.categories.find(c => c.value === this.selectedCategory);
        return (category === null || category === void 0 ? void 0 : category.docTypeOptions) || [{ label: 'Select a category first', value: '' }];
    }
    validate() {
        if (this.allowOptionalFields)
            return {};
        const errors = {};
        const financialDocTypes = ['voided_check', 'bank_statement'];
        const hasExistingDoc = (types) => this.existingDocuments.some(doc => types.includes(doc.document_type));
        const hasUploadedDoc = (categoryValue) => this.uploadQueue.some(entry => entry.categoryValue === categoryValue && entry.status === 'uploaded');
        if (!hasUploadedDoc('financial_document') && !hasExistingDoc(financialDocTypes)) {
            errors['financial_document'] = 'Please upload a financial document';
        }
        if (this.country === CountryCode.CAN) {
            const businessDocTypes = ['articles_of_incorporation', 'business_registration'];
            if (!hasUploadedDoc('business_document') && !hasExistingDoc(businessDocTypes)) {
                errors['business_document'] = 'Please upload a business document';
            }
            const requiredCount = this.owners.length;
            const group1Uploaded = this.uploadQueue.filter(entry => entry.categoryValue === 'personal_group1' && entry.status === 'uploaded').length;
            const group1Existing = this.existingDocuments.filter(doc => personalDocGroup1Types.has(doc.document_type)).length;
            if (group1Uploaded + group1Existing < requiredCount) {
                errors['personal_group1'] =
                    `Please upload ${requiredCount} Group 1 identity document(s) (${group1Uploaded + group1Existing} of ${requiredCount} provided)`;
            }
            const group2Uploaded = this.uploadQueue.filter(entry => entry.categoryValue === 'personal_group2' && entry.status === 'uploaded').length;
            const group2Existing = this.existingDocuments.filter(doc => personalDocGroup2Types.has(doc.document_type)).length;
            if (group2Uploaded + group2Existing < requiredCount) {
                errors['personal_group2'] =
                    `Please upload ${requiredCount} Group 2 identity document(s) (${group2Uploaded + group2Existing} of ${requiredCount} provided)`;
            }
        }
        return errors;
    }
    render() {
        if (this.isLoading) {
            return h(PaymentProvisioningLoading, null);
        }
        return (h("form", null, h("fieldset", null, h("legend", { class: "mb-0", part: heading2 }, "Document Uploads"), h("hr", { class: "mt-2" }), h("business-documents-on-file", { documents: this.existingDocuments, isLoading: this.isLoading })), this.country === CountryCode.CAN && this.owners.length > 0 && (h("div", { class: "alert alert-info mt-3" }, "One document from each group (Group 1 and Group 2) is required for each owner (", this.owners.length, " owner(s)).")), h("fieldset", { class: "mt-4" }, h("div", { class: "d-flex align-items-center gap-2" }, h("legend", { class: "mb-0", part: heading2 }, "Add Document"), h("form-control-tooltip", { helpText: "Upload documents one at a time. Select the category and type, then choose a file. For Canadian businesses, one Group 1 and one Group 2 identity document is required for each owner." })), h("hr", { class: "mt-2" }), h("div", { class: "row gy-3" }, h("div", { class: "col-12 col-md-6" }, h("form-control-select", { name: "document_category", label: "Document Category", options: this.categoryOptions, defaultValue: this.selectedCategory, inputHandler: this.handleCategoryChange })), h("div", { class: "col-12 col-md-6" }, h("form-control-select", { name: "document_type", label: "Document Type", options: this.docTypeOptions, defaultValue: this.selectedDocType, inputHandler: this.handleDocTypeChange, disabled: !this.selectedCategory })), h("div", { class: "col-12" }, h("form-control-file", { key: this.fileInputKey, name: "document_file", label: "Upload Document", documentType: this.selectedDocType, onFileSelected: this.handleFileSelected, disabled: !this.selectedDocType, multiple: false })))), h("document-upload-list", { documents: this.uploadQueue }), Object.keys(this.errors).length > 0 && (h("div", { class: "alert alert-danger mt-3" }, h("ul", { class: "mb-0" }, Object.values(this.errors).map(err => h("li", null, err)))))));
    }
    static get watchers() { return {
        "authToken": ["propChanged"],
        "businessId": ["propChanged"],
        "isLoading": ["watchHandler"]
    }; }
}, [256, "document-upload-form-step", {
        "authToken": [1, "auth-token"],
        "businessId": [1, "business-id"],
        "allowOptionalFields": [4, "allow-optional-fields"],
        "country": [1],
        "owners": [32],
        "existingDocuments": [32],
        "selectedCategory": [32],
        "selectedDocType": [32],
        "uploadQueue": [32],
        "isLoading": [32],
        "errors": [32],
        "fileInputKey": [32],
        "getBusiness": [32],
        "postDocumentRecord": [32],
        "validateAndSubmit": [64]
    }, undefined, {
        "authToken": ["propChanged"],
        "businessId": ["propChanged"],
        "isLoading": ["watchHandler"]
    }]);
function defineCustomElement() {
    if (typeof customElements === "undefined") {
        return;
    }
    const components = ["document-upload-form-step", "business-documents-on-file", "custom-popper", "document-upload-list", "form-control-file", "form-control-select", "form-control-tooltip"];
    components.forEach(tagName => { switch (tagName) {
        case "document-upload-form-step":
            if (!customElements.get(tagName)) {
                customElements.define(tagName, DocumentUploadFormStep);
            }
            break;
        case "business-documents-on-file":
            if (!customElements.get(tagName)) {
                defineCustomElement$6();
            }
            break;
        case "custom-popper":
            if (!customElements.get(tagName)) {
                defineCustomElement$5();
            }
            break;
        case "document-upload-list":
            if (!customElements.get(tagName)) {
                defineCustomElement$4();
            }
            break;
        case "form-control-file":
            if (!customElements.get(tagName)) {
                defineCustomElement$3();
            }
            break;
        case "form-control-select":
            if (!customElements.get(tagName)) {
                defineCustomElement$2();
            }
            break;
        case "form-control-tooltip":
            if (!customElements.get(tagName)) {
                defineCustomElement$1();
            }
            break;
    } });
}
defineCustomElement();

export { DocumentUploadFormStep as D, defineCustomElement as d };
