import { GraphQLError } from 'graphql';
import { EMPTY_UUID } from '../../../../../shared/constants.js';
import { AdminContextProvider } from '../../../../admin-context/providers/admin-context.provider.js';
import { calculateDepreciationAmount } from '../../../../reports/helpers/depreciation-report.helper.js';
import { storeInitialGeneratedRecords } from '../../../helpers/ledgrer-storage.helper.js';
import { generateMiscExpensesLedger } from '../../../helpers/misc-expenses-ledger.helper.js';
import { ledgerProtoToRecordsConverter } from '../../../helpers/utils.helper.js';
export const generateLedgerRecordsForDepreciationExpenses = async (charge, { insertLedgerRecordsIfNotExists }, { injector }) => {
    try {
        const { defaultLocalCurrency, depreciation: { accumulatedDepreciationTaxCategoryId, rndDepreciationExpensesTaxCategoryId, gnmDepreciationExpensesTaxCategoryId, marketingDepreciationExpensesTaxCategoryId, }, } = await injector.get(AdminContextProvider).getVerifiedAdminContext();
        if (!charge.user_description) {
            return {
                __typename: 'CommonError',
                message: `Depreciation expenses charge must include user description with designated year`,
            };
        }
        // get revaluation date - search for "yyyy-mm-dd" in description
        const dateRegex = /\b(\d{4})\b/;
        const matches = charge.user_description.match(dateRegex);
        if (!matches?.length) {
            return {
                __typename: 'CommonError',
                message: `Depreciation expenses charge description must include full year`,
            };
        }
        const stringYear = matches[0];
        const year = Number(stringYear);
        if (Number.isNaN(year) || year < 2000 || year > new Date().getFullYear()) {
            return {
                __typename: 'CommonError',
                message: `Depreciation expenses charge description must include valid year (2000 - current year)`,
            };
        }
        const { rndDepreciationYearlyAmount, gnmDepreciationYearlyAmount, marketingDepreciationYearlyAmount, totalDepreciationYearlyAmount, } = await calculateDepreciationAmount(injector, year);
        const ledgerEntries = [];
        function addLedgerEntry(amount, description, creditor, debtor) {
            if (amount === 0) {
                return;
            }
            const ledgerEntry = {
                id: EMPTY_UUID,
                invoiceDate: new Date(year, 11, 31),
                valueDate: new Date(year, 11, 31),
                currency: defaultLocalCurrency,
                isCreditorCounterparty: true,
                creditAccountID1: creditor,
                debitAccountID1: debtor,
                localCurrencyCreditAmount1: Math.abs(amount),
                localCurrencyDebitAmount1: Math.abs(amount),
                description: `${description} depreciation expenses for ${year}`,
                ownerId: charge.owner_id,
                chargeId: charge.id,
                currencyRate: 1,
            };
            ledgerEntries.push(ledgerEntry);
        }
        if (!accumulatedDepreciationTaxCategoryId) {
            throw new GraphQLError('Accumulated depreciation tax category is not defined');
        }
        if (!rndDepreciationExpensesTaxCategoryId) {
            throw new GraphQLError('R&D depreciation expenses tax category is not defined');
        }
        if (!gnmDepreciationExpensesTaxCategoryId) {
            throw new GraphQLError('G&M depreciation expenses tax category is not defined');
        }
        if (!marketingDepreciationExpensesTaxCategoryId) {
            throw new GraphQLError('Marketing depreciation expenses tax category is not defined');
        }
        addLedgerEntry(rndDepreciationYearlyAmount, 'R&D', undefined, rndDepreciationExpensesTaxCategoryId);
        addLedgerEntry(gnmDepreciationYearlyAmount, 'G&M', undefined, gnmDepreciationExpensesTaxCategoryId);
        addLedgerEntry(marketingDepreciationYearlyAmount, 'Marketing', undefined, marketingDepreciationExpensesTaxCategoryId);
        addLedgerEntry(totalDepreciationYearlyAmount, 'Accumulated', accumulatedDepreciationTaxCategoryId);
        // generate ledger from misc expenses
        await generateMiscExpensesLedger(charge, injector).then(entries => {
            entries.map(entry => {
                entry.ownerId = charge.owner_id;
                ledgerEntries.push(entry);
            });
        });
        if (insertLedgerRecordsIfNotExists) {
            await storeInitialGeneratedRecords(charge.id, ledgerEntries, injector);
        }
        return {
            records: ledgerProtoToRecordsConverter(ledgerEntries),
            charge,
            balance: {
                isBalanced: true,
                unbalancedEntities: [],
                balanceSum: 0,
                financialEntities: [],
            },
            errors: [],
        };
    }
    catch (e) {
        return {
            __typename: 'CommonError',
            message: `Failed to generate ledger records for charge ID="${charge.id}"\n${e}`,
        };
    }
};
//# sourceMappingURL=depreciation-expenses-ledger-generation.resolver.js.map