import { __decorate, __metadata } from "tslib";
import { GraphQLError } from 'graphql';
import { Injectable, Scope } from 'graphql-modules';
import { parseUniformFormatFiles } from '../../../../../shaam-uniform-format-generator/src/index.js';
import { CountryCode } from '../../../shared/enums.js';
import { TenantAwareDBClient } from '../../app-providers/tenant-db-client.js';
import { BusinessesProvider } from '../../financial-entities/providers/businesses.provider.js';
import { FinancialEntitiesProvider } from '../../financial-entities/providers/financial-entities.provider.js';
import { greenInvoiceCountryToCountryCode } from '../../green-invoice/helpers/green-invoice.helper.js';
import { SortCodesProvider } from '../../sort-codes/providers/sort-codes.provider.js';
let ShaamImportProvider = class ShaamImportProvider {
    db;
    sortCodesProvider;
    businessProvider;
    financialEntitiesProvider;
    constructor(db, sortCodesProvider, businessProvider, financialEntitiesProvider) {
        this.db = db;
        this.sortCodesProvider = sortCodesProvider;
        this.businessProvider = businessProvider;
        this.financialEntitiesProvider = financialEntitiesProvider;
    }
    async importShaamFile(ownerId, bkmvdataContent, iniContent) {
        const parseResult = parseUniformFormatFiles(iniContent ?? '', bkmvdataContent, {
            validationMode: 'strict',
        });
        if (parseResult.summary.errors.some(e => e.severity === 'error')) {
            const messages = parseResult.summary.errors
                .filter(e => e.severity === 'error')
                .map(e => `[${e.recordType}] ${e.field}: ${e.message}`)
                .join('; ');
            throw new GraphQLError(`SHAAM file validation failed: ${messages}`, {
                extensions: { code: 'BAD_USER_INPUT' },
            });
        }
        const accounts = parseResult.data.accounts;
        // Collect unique sort codes by key
        const sortCodeMap = new Map();
        for (const account of accounts) {
            const key = account.sortCode.key ? parseInt(account.sortCode.key, 10) : NaN;
            if (!Number.isNaN(key) && !sortCodeMap.has(key)) {
                sortCodeMap.set(key, account.sortCode.name ?? undefined);
            }
        }
        return this.db.transaction(async (client) => {
            // Override RLS context to the target owner so inserts pass the tenant_isolation policy
            await client.query(`SELECT set_config('app.current_business_id', $1, true)`, [ownerId]);
            // Insert sort codes that don't exist yet
            const existingSortCodes = await this.sortCodesProvider.getSortCodesByOwnerIdLoader.load(ownerId);
            const existingKeys = new Set(existingSortCodes.map(sc => sc.key));
            const newSortCodes = [...sortCodeMap]
                .filter(([key]) => !existingKeys.has(key))
                .map(([key, name]) => ({ key, name: name ?? null, defaultIrsCode: null, ownerId }));
            if (newSortCodes.length > 0) {
                await this.sortCodesProvider.addSortCodes({ sortCodes: newSortCodes }, client);
            }
            const insertedSortCodesCount = newSortCodes.length;
            // Insert a business entity for each account
            let insertedBusinessesCount = 0;
            for (const account of accounts) {
                const addressStreet = account.address?.street
                    ? [account.address.street, account.address.houseNumber].filter(Boolean).join(' ')
                    : undefined;
                const financialEntity = {
                    ownerId,
                    name: account.name ?? account.id,
                    sortCode: account.sortCode?.key ? parseInt(account.sortCode.key, 10) : null,
                    type: 'business',
                    irsCode: account.accountingClassificationCode
                        ? parseInt(account.accountingClassificationCode, 10)
                        : null,
                    isActive: true,
                };
                try {
                    const [{ id: financialEntityId } = {}] = await this.financialEntitiesProvider.insertFinancialEntity(financialEntity, client);
                    if (!financialEntityId) {
                        throw new GraphQLError(`Failed to insert financial entity for account "${account.name ?? account.id}"`);
                    }
                    // if account.name includes Hebrew characters, use it as the hebrewName, otherwise leave hebrewName null
                    const hebrewName = /[\u0590-\u05FF]/.test(account.name ?? '') ? account.name : undefined;
                    let country = CountryCode.Israel;
                    if (account.countryCode) {
                        try {
                            country = greenInvoiceCountryToCountryCode(account.countryCode);
                        }
                        catch {
                            console.warn(`Unknown country code "${account.countryCode}" for account "${account.name ?? account.id}", skipping country mapping`);
                        }
                    }
                    const business = {
                        id: financialEntityId,
                        ownerId,
                        address: addressStreet,
                        city: account.address?.city ?? undefined,
                        zipCode: account.address?.zip ?? undefined,
                        email: null,
                        exemptDealer: false,
                        governmentId: account.vatId ?? undefined,
                        hebrewName,
                        phoneNumber: null,
                        website: null,
                        optionalVat: false,
                        isReceiptEnough: false,
                        isDocumentsOptional: false,
                        country,
                        suggestions: null,
                        pcn874RecordTypeOverride: null,
                    };
                    await this.businessProvider.insertBusiness(business, client);
                    insertedBusinessesCount++;
                }
                catch (e) {
                    console.error(`Error ensuring business for entity ${financialEntity.name}`, e);
                    throw new GraphQLError(`Error ensuring business for account "${financialEntity.name}": ${e?.message ?? 'Unknown error'}`);
                }
            }
            return { insertedSortCodesCount, insertedBusinessesCount };
        });
    }
};
ShaamImportProvider = __decorate([
    Injectable({ scope: Scope.Operation }),
    __metadata("design:paramtypes", [TenantAwareDBClient,
        SortCodesProvider,
        BusinessesProvider,
        FinancialEntitiesProvider])
], ShaamImportProvider);
export { ShaamImportProvider };
//# sourceMappingURL=shaam-import.provider.js.map