import { GraphQLError } from 'graphql';
import { AccountingMethod, AccountingSystem, AuditOpinionType, BALANCE_SHEET_CODE_NAMES, BusinessType, CurrencyType, IFRSReportingOption, IndividualOrCompanyEnum, NEGATIVE_ALLOWED_BALANCE_SHEET_CODES, PROFIT_LOSS_CODE_NAMES, ReportingMethod, SECTION_1_1, SECTION_1_4, SECTION_1_9, SECTION_1_10, SECTION_1_11, SECTION_1_12, SECTION_1_14, SECTION_1_15, SECTION_1_16, SECTION_1_21, SECTION_1_27, SECTION_1_28, SECTION_1_30, SECTION_1_32, SECTION_1_33, SECTION_1_36, SECTION_1_37, SECTION_1_38, SECTION_1_39, SECTION_1_40, SECTION_1_41, SECTION_1_43, SECTION_1_44, SECTION_1_45, SECTION_1_46, SECTION_1_48, SECTION_1_50, SECTION_1_51, TAX_ADJUSTMENT_CODE_NAMES, YesNo, } from '../../../../../shaam6111-generator/src/index.js';
import { AdminContextProvider } from '../../admin-context/providers/admin-context.provider.js';
import { BusinessesProvider } from '../../financial-entities/providers/businesses.provider.js';
import { FinancialEntitiesProvider } from '../../financial-entities/providers/financial-entities.provider.js';
import { LedgerProvider } from '../../ledger/providers/ledger.provider.js';
import { amountByFinancialEntityIdAndSortCodeValidations } from './misc.helper.js';
import { decorateLedgerRecords, getProfitLossReportAmounts, } from './profit-and-loss.helper.js';
import { calculateCumulativeRnDExpenses, calculateTaxAmounts } from './tax.helper.js';
function cumulativeCodeFormula(code, sectionCodes, subtractSectionCodes) {
    return (map) => {
        const sectionCodeAmounts = sectionCodes
            .filter(sectionCode => sectionCode !== code)
            .map(sectionCode => map.get(sectionCode)?.amount || 0)
            .reduce((a, b) => a + b, 0);
        const subtractSectionCodeAmounts = subtractSectionCodes?.length
            ? subtractSectionCodes
                .filter(sectionCode => sectionCode !== code)
                .map(sectionCode => map.get(sectionCode)?.amount || 0)
                .reduce((a, b) => a + b, 0)
            : 0;
        return sectionCodeAmounts - subtractSectionCodeAmounts;
    };
}
function getProfitAndLossEntries(decoratedLedgerRecords, financialEntitiesByIrsCodeDict) {
    const profitAndLossAmounts = amountByFinancialEntityIdAndSortCodeValidations(decoratedLedgerRecords, Object.entries(PROFIT_LOSS_CODE_NAMES).map(([code]) => {
        const codeInt = parseInt(code, 10);
        return {
            rule: financialEntityId => {
                const financialEntitiesByIrsCode = financialEntitiesByIrsCodeDict.get(codeInt) || [];
                return financialEntitiesByIrsCode.some(entity => entity.id === financialEntityId);
            },
            negate: codeInt >= 1300 && codeInt < 5100,
        };
    }));
    const profitAndLossCodesMap = new Map(Object.entries(PROFIT_LOSS_CODE_NAMES).map(([code, label], index) => [
        parseInt(code, 10),
        {
            label,
            amount: Math.round(profitAndLossAmounts[index] ?? 0),
        },
    ]));
    const rules = [
        {
            code: 1000,
            rule: cumulativeCodeFormula(1000, SECTION_1_1),
        },
        {
            code: 1300,
            rule: map => {
                return ([1306, 1308, 1307, 1310, 1320, 1330, 1340, 1350, 1360, 1371, 1372, 1390, 1400]
                    .map(code => map.get(code)?.amount || 0)
                    .reduce((a, b) => a + b, 0) - (map.get(1450)?.amount || 0));
            },
        },
        {
            code: 2000,
            rule: map => [
                2005, 2006, 2011, 2012, 2015, 2020, 2025, 2030, 2035, 2040, 2045, 2050, 2060, 2066, 2067,
                2070, 2075, 2080, 2085, 2090,
            ]
                .map(code => map.get(code)?.amount || 0)
                .reduce((a, b) => a + b, 0) -
                (map.get(2068)?.amount || 0) -
                (map.get(2095)?.amount || 0),
        },
        {
            code: 2500,
            rule: cumulativeCodeFormula(2500, SECTION_1_4),
        },
        {
            code: 3000,
            rule: map => [
                3011, 3013, 3012, 3015, 3020, 3025, 3030, 3040, 3045, 3050, 3060, 3066, 3067, 3070, 3075,
                3080, 3085, 3090, 3100, 3120, 3190,
            ]
                .map(code => map.get(code)?.amount || 0)
                .reduce((a, b) => a + b, 0) - (map.get(3068)?.amount || 0),
        },
        {
            code: 3500,
            rule: cumulativeCodeFormula(3500, [
                3511, 3513, 3512, 3515, 3520, 3530, 3535, 3540, 3545, 3550, 3560, 3566, 3567, 3570, 3575,
                3580, 3590, 3595, 3600, 3610, 3620, 3625, 3631, 3632, 3640, 3650, 3660, 3665, 3680, 3685,
                3690,
            ], [3568]),
        },
        {
            code: 5000,
            rule: cumulativeCodeFormula(5000, SECTION_1_9),
        },
        {
            code: 5100,
            rule: cumulativeCodeFormula(5100, SECTION_1_10),
        },
        {
            code: 5200,
            rule: cumulativeCodeFormula(5200, SECTION_1_11),
        },
        {
            code: 5300,
            rule: cumulativeCodeFormula(5300, SECTION_1_12),
        },
        {
            code: 5600,
            rule: cumulativeCodeFormula(5600, SECTION_1_14),
        },
        {
            code: 5700,
            rule: cumulativeCodeFormula(5700, SECTION_1_15),
        },
        {
            code: 5800,
            rule: cumulativeCodeFormula(5800, SECTION_1_16),
        },
        {
            code: 6666,
            rule: map => (map.get(1000)?.amount || 0) -
                (map.get(1300)?.amount || 0) -
                (map.get(2000)?.amount || 0) -
                (map.get(2500)?.amount || 0) -
                (map.get(3000)?.amount || 0) -
                (map.get(3500)?.amount || 0) -
                (map.get(5000)?.amount || 0) +
                (map.get(5100)?.amount || 0) +
                (map.get(5200)?.amount || 0) -
                (map.get(5300)?.amount || 0),
        },
    ];
    // Apply the rules to the tax adjustment codes map
    for (const { code, rule } of rules) {
        const entry = profitAndLossCodesMap.get(code);
        if (entry) {
            entry.amount = rule(profitAndLossCodesMap);
        }
    }
    const profitAndLoss = Array.from(profitAndLossCodesMap.entries())
        .map(([code, { amount, label }]) => ({
        code,
        label,
        amount,
    }))
        .sort((a, b) => a.code - b.code); // Sort by code
    return profitAndLoss;
}
async function getTaxAdjustmentEntries(injector, year, decoratedLedgerByYear) {
    const decoratedLedgerRecords = decoratedLedgerByYear.get(year) ?? [];
    const profitLossByYear = new Map();
    let profitAndLoss = profitLossByYear.get(year);
    if (!profitAndLoss) {
        profitAndLoss = getProfitLossReportAmounts(decoratedLedgerRecords);
        profitLossByYear.set(year, profitAndLoss);
    }
    const { profitBeforeTax, researchAndDevelopmentExpenses } = profitAndLoss;
    const adjustedResearchAndDevelopmentExpensesAmount = researchAndDevelopmentExpenses.amount * -1;
    const cumulativeResearchAndDevelopmentExpensesAmount = calculateCumulativeRnDExpenses(year, decoratedLedgerByYear, profitLossByYear);
    const taxableCumulativeResearchAndDevelopmentExpensesAmount = cumulativeResearchAndDevelopmentExpensesAmount / 3;
    const { researchAndDevelopmentExpensesForTax, fines, untaxableGifts, businessTripsExcessExpensesAmount, salaryExcessExpensesAmount, reserves, nontaxableLinkage, taxableIncomeAmount, } = await calculateTaxAmounts(injector, year, decoratedLedgerRecords, adjustedResearchAndDevelopmentExpensesAmount, taxableCumulativeResearchAndDevelopmentExpensesAmount, profitBeforeTax.amount);
    const amount190 = adjustedResearchAndDevelopmentExpensesAmount +
        researchAndDevelopmentExpensesForTax +
        fines.amount +
        untaxableGifts.amount +
        businessTripsExcessExpensesAmount +
        salaryExcessExpensesAmount +
        nontaxableLinkage.amount;
    const taxAdjustmentCodesMap = new Map(Object.entries(TAX_ADJUSTMENT_CODE_NAMES).map(([code, label]) => [
        parseInt(code, 10),
        {
            label,
            amount: 0,
        },
    ]));
    const rules = [
        {
            code: 100,
            rule: () => {
                return Math.round(profitBeforeTax.amount);
            },
        },
        {
            code: 104,
            rule: () => {
                return Math.round(profitBeforeTax.amount);
            },
        },
        {
            code: 150,
            rule: () => {
                return Math.round(reserves.amount);
            },
        },
        {
            code: 190,
            rule: () => {
                return Math.round(amount190);
            },
        },
        {
            code: 400,
            rule: () => {
                return Math.round(taxableIncomeAmount);
            },
        },
        {
            code: 510,
            rule: () => {
                return Math.round(taxableIncomeAmount);
            },
        },
        // summation rules
        {
            code: 370,
            rule: map => {
                return ([110, 120, 140, 150, 160, 181, 182, 183, 184, 190, 310, 330, 350, 360]
                    .map(code => map.get(code)?.amount || 0)
                    .reduce((a, b) => a + b, 0) -
                    [130, 135, 170, 180, 200, 300, 320]
                        .map(code => map.get(code)?.amount || 0)
                        .reduce((a, b) => a + b, 0));
            },
        },
        {
            code: 500,
            rule: map => {
                return ((map.get(400)?.amount || 0) -
                    (map.get(430)?.amount || 0) -
                    (map.get(480)?.amount || 0) +
                    (map.get(490)?.amount || 0));
            },
        },
    ];
    // Apply the rules to the tax adjustment codes map
    for (const { code, rule } of rules) {
        const entry = taxAdjustmentCodesMap.get(code);
        if (entry) {
            entry.amount = rule(taxAdjustmentCodesMap);
        }
    }
    const taxAdjustment = Array.from(taxAdjustmentCodesMap.entries())
        .map(([code, { amount, label }]) => ({
        code,
        label,
        amount,
    }))
        .sort((a, b) => a.code - b.code); // Sort by code
    return taxAdjustment;
}
function getBalanceSheetEntries(decoratedLedgerRecords, financialEntitiesByIrsCodeDict) {
    const balanceSheetAmounts = amountByFinancialEntityIdAndSortCodeValidations(decoratedLedgerRecords, Object.entries(BALANCE_SHEET_CODE_NAMES).map(([stringCode]) => {
        const code = parseInt(stringCode, 10);
        return {
            rule: financialEntityId => {
                const financialEntitiesByIrsCode = financialEntitiesByIrsCodeDict.get(code) || [];
                return financialEntitiesByIrsCode.some(entity => entity.id === financialEntityId);
            },
            negate: code >= 7000 && code < 9000,
        };
    }));
    const balanceSheetCodesMap = new Map(Object.entries(BALANCE_SHEET_CODE_NAMES).map(([code, label], index) => {
        const codeInt = parseInt(code, 10);
        let amount = Math.round(balanceSheetAmounts[index] ?? 0);
        // for codes that are not allowed to be negative, we ensure the amount is positive
        if (!NEGATIVE_ALLOWED_BALANCE_SHEET_CODES.includes(codeInt)) {
            amount = Math.abs(amount);
        }
        return [
            codeInt,
            {
                label,
                amount,
            },
        ];
    }));
    const cumulativeProfit = getProfitAndLossEntries(decoratedLedgerRecords, financialEntitiesByIrsCodeDict).find(entry => entry.code === 6666)?.amount || 0;
    // NOTE: the rules order is important here, as some codes depend on others
    // e.g. 7000 depends on 7100, 7200, etc.
    const rules = [
        {
            code: 9980,
            rule: () => cumulativeProfit,
        },
        {
            code: 7100,
            rule: cumulativeCodeFormula(7100, SECTION_1_27),
        },
        {
            code: 7200,
            rule: cumulativeCodeFormula(7200, SECTION_1_28),
        },
        {
            code: 7300,
            rule: cumulativeCodeFormula(7300, [7310, 7320, 7330, 7350, 7360, 7390], [7380]),
        },
        {
            code: 7400,
            rule: cumulativeCodeFormula(7400, SECTION_1_30),
        },
        {
            code: 7600,
            rule: cumulativeCodeFormula(7600, SECTION_1_21),
        },
        {
            code: 7700,
            rule: cumulativeCodeFormula(7700, SECTION_1_32),
        },
        {
            code: 7800,
            rule: cumulativeCodeFormula(7800, SECTION_1_33),
        },
        {
            code: 7000,
            rule: cumulativeCodeFormula(7000, [7100, 7200, 7300, 7400, 7600, 7700, 7800]),
        },
        {
            code: 8000,
            rule: cumulativeCodeFormula(8000, [8010, 8020, 8025, 8030, 8040, 8050, 8060, 8080, 8090, 8095, 8100, 8105, 8170], [8110, 8120, 8130, 8140, 8150, 8160, 8180, 8190]),
        },
        {
            code: 8200,
            rule: cumulativeCodeFormula(8200, SECTION_1_37),
        },
        {
            code: 8300,
            rule: cumulativeCodeFormula(8300, SECTION_1_38),
        },
        {
            code: 8400,
            rule: cumulativeCodeFormula(8400, SECTION_1_39),
        },
        {
            code: 8500,
            rule: cumulativeCodeFormula(8500, SECTION_1_40),
        },
        {
            code: 8600,
            rule: cumulativeCodeFormula(8600, SECTION_1_41),
        },
        {
            code: 8700,
            rule: cumulativeCodeFormula(8700, SECTION_1_36),
        },
        {
            code: 8888,
            rule: cumulativeCodeFormula(8888, [7000, 8000, 8200, 8300, 8400, 8500, 8600, 8700]),
        },
        {
            code: 9100,
            rule: cumulativeCodeFormula(9100, SECTION_1_43),
        },
        {
            code: 9200,
            rule: cumulativeCodeFormula(9200, SECTION_1_44),
        },
        {
            code: 9400,
            rule: cumulativeCodeFormula(9400, SECTION_1_45),
        },
        {
            code: 9500,
            rule: cumulativeCodeFormula(9500, SECTION_1_46),
        },
        {
            code: 9000,
            rule: cumulativeCodeFormula(9000, [9100, 9200, 9400, 9500]),
        },
        {
            code: 9600,
            rule: cumulativeCodeFormula(9600, SECTION_1_48),
        },
        {
            code: 9700,
            rule: map => (map.get(9710)?.amount || 0) - (map.get(9720)?.amount || 0) + (map.get(9790)?.amount || 0),
        },
        {
            code: 9800,
            rule: cumulativeCodeFormula(9800, SECTION_1_50),
        },
        {
            code: 9900,
            rule: cumulativeCodeFormula(9900, SECTION_1_51),
        },
        {
            code: 9999,
            rule: cumulativeCodeFormula(9999, [9000, 9600, 9700, 9800, 9900]),
        },
    ];
    // Apply the rules to the tax adjustment codes map
    for (const { code, rule } of rules) {
        const entry = balanceSheetCodesMap.get(code);
        if (entry) {
            entry.amount = rule(balanceSheetCodesMap);
        }
    }
    const balanceSheet = Array.from(balanceSheetCodesMap.entries())
        .map(([code, { amount, label }]) => ({
        code,
        label,
        amount,
    }))
        .sort((a, b) => a.code - b.code); // Sort by code
    return balanceSheet;
}
export async function getShaam6111Data(injector, businessId, year) {
    const { ownerId } = await injector.get(AdminContextProvider).getVerifiedAdminContext();
    const financialEntityId = businessId || ownerId;
    const businessesProvider = injector.get(BusinessesProvider);
    const business = await businessesProvider.getBusinessByIdLoader.load(financialEntityId);
    if (!business) {
        throw new Error('Business not found');
    }
    if (!business?.vat_number) {
        throw new Error('Business does not have a VAT number');
    }
    if (!Number.isInteger(year) || year < 2000 || year > 2100) {
        throw new Error(`Invalid year. Must be between 2000 and 2100. Received: ${year}`);
    }
    const fromDate = new Date(1990, 0, 1, 0, 0, 0, 1); // TODO: maybe take company init date as from date
    const toDate = new Date(year + 1, 0, 0);
    const ledgerRecordsPromise = injector
        .get(LedgerProvider)
        .getLedgerRecordsByDates({ fromDate, toDate });
    const financialEntitiesPromise = injector
        .get(FinancialEntitiesProvider)
        .getAllFinancialEntities();
    const [ledgerRecords, financialEntities] = await Promise.all([
        ledgerRecordsPromise,
        financialEntitiesPromise,
    ]);
    const financialEntitiesDict = new Map();
    const financialEntitiesByIrsCodeDict = new Map();
    financialEntities.map(entity => {
        financialEntitiesDict.set(entity.id, entity);
        if (entity.irs_code) {
            const entities = financialEntitiesByIrsCodeDict.get(entity.irs_code) || [];
            entities.push(entity);
            financialEntitiesByIrsCodeDict.set(entity.irs_code, entities);
        }
    });
    const decoratedLedgerByYear = new Map();
    ledgerRecords.map(record => {
        const year = record.invoice_date.getFullYear();
        const [decoratedRecord] = decorateLedgerRecords([record], financialEntitiesDict);
        if (!decoratedLedgerByYear.has(year)) {
            decoratedLedgerByYear.set(year, []);
        }
        // Add the decorated record to the corresponding year
        decoratedLedgerByYear.get(year)?.push(decoratedRecord);
    });
    const profitAndLoss = getProfitAndLossEntries(decoratedLedgerByYear.get(year) || [], financialEntitiesByIrsCodeDict);
    const taxAdjustment = await getTaxAdjustmentEntries(injector, year, decoratedLedgerByYear);
    const ledgerSinceForever = Array.from(decoratedLedgerByYear.entries()).reduce((acc, [ledgerYear, records]) => {
        if (ledgerYear <= year) {
            return acc.concat(records);
        }
        return acc;
    }, []);
    const balanceSheet = getBalanceSheetEntries(ledgerSinceForever, financialEntitiesByIrsCodeDict);
    const header = {
        taxFileNumber: business.vat_number,
        taxYear: year.toString(),
        idNumber: business.vat_number,
        vatFileNumber: business.vat_number,
        withholdingTaxFileNumber: undefined, // TODO: fetch from admin business
        industryCode: '6201', // TODO: migrate to DB
        businessDescription: 'פיתוח פלטפורמת תוכנה', // TODO: migrate to DB
        businessType: 'MULTIPLE', // TODO: migrate to DB
        reportingMethod: 'ACCRUAL', // TODO: migrate to DB
        accountingMethod: 'DOUBLE_ENTRY', // TODO: migrate to DB
        accountingSystem: 'COMPUTERIZED',
        includesProfitLoss: !!profitAndLoss.length,
        includesTaxAdjustment: !!taxAdjustment.length,
        includesBalanceSheet: !!balanceSheet.length,
        profitLossEntryCount: profitAndLoss.length ?? undefined,
        taxAdjustmentEntryCount: taxAdjustment.length ?? undefined,
        balanceSheetEntryCount: balanceSheet.length ?? undefined,
        softwareRegistrationNumber: '99999999',
        isPartnership: false, // TODO: migrate to DB
        partnershipCount: undefined, // TODO: migrate to DB
        partnershipProfitShare: undefined, // TODO: migrate to DB
        ifrsImplementationYear: '9999', // TODO: migrate to DB
        ifrsReportingOption: 'NONE', // TODO: migrate to DB
        currencyType: 'SHEKELS', // TODO: migrate to DB
        amountsInThousands: false, // TODO: migrate to DB
        auditOpinionType: 'UNQUALIFIED', // TODO: migrate to DB
    };
    const shaam6111Data = {
        id: `shaam6111-${business.vat_number}-${year}-data`,
        header,
        profitAndLoss,
        taxAdjustment,
        balanceSheet,
        individualOrCompany: 'INDIVIDUAL', // TODO: migrate to DB
    };
    return shaam6111Data;
}
export function accountingMethodSafeParser(accountingMethod) {
    switch (accountingMethod) {
        case 'DOUBLE_ENTRY':
            return AccountingMethod.DOUBLE_ENTRY;
        case 'SINGLE_ENTRY':
            return AccountingMethod.SINGLE_ENTRY;
        default:
            throw new GraphQLError(`Unknown accounting method: ${accountingMethod}`);
    }
}
export function accountingSystemSafeParser(accountingSystem) {
    switch (accountingSystem) {
        case 'COMPUTERIZED':
            return AccountingSystem.COMPUTERIZED;
        case 'MANUAL':
            return AccountingSystem.MANUAL;
        default:
            throw new GraphQLError(`Unknown accounting system: ${accountingSystem}`);
    }
}
export function auditOpinionTypeSafeParser(auditOpinionType) {
    if (auditOpinionType == null) {
        return undefined;
    }
    switch (auditOpinionType) {
        case 'UNQUALIFIED':
            return AuditOpinionType.UNQUALIFIED;
        case 'UNQUALIFIED_WITH_GOING_CONCERN':
            return AuditOpinionType.UNQUALIFIED_WITH_GOING_CONCERN;
        case 'UNQUALIFIED_WITH_OTHER_EMPHASES':
            return AuditOpinionType.UNQUALIFIED_WITH_OTHER_EMPHASES;
        case 'QUALIFIED':
            return AuditOpinionType.QUALIFIED;
        case 'ADVERSE':
            return AuditOpinionType.ADVERSE;
        case 'DISCLAIMER':
            return AuditOpinionType.DISCLAIMER;
        case 'NONE':
            return AuditOpinionType.NONE;
        default:
            throw new GraphQLError(`Unknown audit opinion type: ${auditOpinionType}`);
    }
}
export function businessTypeSafeParser(businessType) {
    switch (businessType) {
        case 'COMMERCIAL':
            return BusinessType.COMMERCIAL;
        case 'INDUSTRIAL':
            return BusinessType.INDUSTRIAL;
        case 'SERVICE':
            return BusinessType.SERVICE;
        case 'MULTIPLE':
            return BusinessType.MULTIPLE;
        case 'COMBINATION':
            return BusinessType.COMBINATION;
        default:
            throw new GraphQLError(`Unknown business type: ${businessType}`);
    }
}
export function currencyTypeSafeParser(currencyType) {
    switch (currencyType) {
        case 'SHEKELS':
            return CurrencyType.SHEKELS;
        case 'DOLLARS':
            return CurrencyType.DOLLARS;
        default:
            throw new GraphQLError(`Unknown currency type: ${currencyType}`);
    }
}
export function ifrsReportingOptionSafeParser(ifrsReportingOption) {
    if (ifrsReportingOption == null) {
        return undefined;
    }
    switch (ifrsReportingOption) {
        case 'OPTION_1':
            return IFRSReportingOption.OPTION_1;
        case 'OPTION_2_ADJUSTMENTS':
            return IFRSReportingOption.OPTION_2_ADJUSTMENTS;
        case 'OPTION_3_ADJUSTMENTS':
            return IFRSReportingOption.OPTION_3_ADJUSTMENTS;
        case 'NONE':
            return IFRSReportingOption.NONE;
        default:
            throw new GraphQLError(`Unknown IFRS reporting option: ${ifrsReportingOption}`);
    }
}
export function reportingMethodSafeParser(reportingMethod) {
    switch (reportingMethod) {
        case 'CASH':
            return ReportingMethod.CASH;
        case 'ACCRUAL':
            return ReportingMethod.ACCRUAL;
        case 'DOLLAR_REGULATIONS':
            return ReportingMethod.DOLLAR_REGULATIONS;
        default:
            throw new GraphQLError(`Unknown reporting method: ${reportingMethod}`);
    }
}
export function yesNoSafeParser(yesNo) {
    switch (yesNo) {
        case true:
            return YesNo.YES;
        case false:
            return YesNo.NO;
        default:
            throw new GraphQLError(`Unknown Yes/No value: ${yesNo}`);
    }
}
export function yesNoOptionalSafeParser(yesNo) {
    if (yesNo == null) {
        return undefined;
    }
    return yesNoSafeParser(yesNo);
}
export function individualOrCompanySafeParser(individualOrCompany) {
    switch (individualOrCompany) {
        case 'INDIVIDUAL':
            return IndividualOrCompanyEnum.INDIVIDUAL;
        case 'COMPANY':
            return IndividualOrCompanyEnum.COMPANY;
        default:
            throw new GraphQLError(`Unknown individual or company type: ${individualOrCompany}`);
    }
}
export function yesNoToBoolean(yesNo) {
    switch (yesNo) {
        case YesNo.YES:
            return true;
        case YesNo.NO:
            return false;
        default:
            throw new GraphQLError(`Unknown Yes/No value: ${yesNo}`);
    }
}
export function yesNoToOptionalBoolean(yesNo) {
    if (yesNo == null) {
        return undefined;
    }
    return yesNoToBoolean(yesNo);
}
export function convertLocalReportDataToShaam6111ReportData(localReportData) {
    const profitAndLoss = localReportData.profitAndLoss.map(entry => ({
        code: entry.code,
        amount: entry.amount,
    }));
    const taxAdjustment = localReportData.taxAdjustment.map(entry => ({
        code: entry.code,
        amount: entry.amount,
    }));
    const balanceSheet = localReportData.balanceSheet
        ? localReportData.balanceSheet.map(entry => ({
            code: entry.code,
            amount: entry.amount,
        }))
        : [];
    const adjustedReportData = {
        profitAndLoss,
        taxAdjustment,
        balanceSheet,
        header: {
            ...localReportData.header,
            vatFileNumber: localReportData.header.vatFileNumber || undefined,
            withholdingTaxFileNumber: localReportData.header.withholdingTaxFileNumber || undefined,
            businessDescription: localReportData.header.businessDescription || undefined,
            businessType: businessTypeSafeParser(localReportData.header.businessType),
            reportingMethod: reportingMethodSafeParser(localReportData.header.reportingMethod),
            accountingMethod: accountingMethodSafeParser(localReportData.header.accountingMethod),
            accountingSystem: accountingSystemSafeParser(localReportData.header.accountingSystem),
            isPartnership: yesNoOptionalSafeParser(localReportData.header.isPartnership),
            includesProfitLoss: yesNoSafeParser(localReportData.header.includesProfitLoss),
            includesTaxAdjustment: yesNoSafeParser(localReportData.header.includesTaxAdjustment),
            includesBalanceSheet: yesNoSafeParser(localReportData.header.includesBalanceSheet),
            profitLossEntryCount: localReportData.profitAndLoss.length,
            taxAdjustmentEntryCount: localReportData.taxAdjustment.length,
            balanceSheetEntryCount: localReportData.balanceSheet?.length,
            ifrsImplementationYear: localReportData.header.ifrsImplementationYear || undefined,
            ifrsReportingOption: localReportData.header.ifrsReportingOption
                ? ifrsReportingOptionSafeParser(localReportData.header.ifrsReportingOption)
                : undefined,
            softwareRegistrationNumber: localReportData.header.softwareRegistrationNumber || undefined,
            partnershipCount: localReportData.header.partnershipCount || undefined,
            partnershipProfitShare: localReportData.header.partnershipProfitShare || undefined,
            currencyType: currencyTypeSafeParser(localReportData.header.currencyType),
            auditOpinionType: auditOpinionTypeSafeParser(localReportData.header.auditOpinionType),
            amountsInThousands: yesNoSafeParser(localReportData.header.amountsInThousands),
        },
        individualOrCompany: individualOrCompanySafeParser(localReportData.individualOrCompany ?? 'COMPANY'),
    };
    return adjustedReportData;
}
//# sourceMappingURL=shaam6111.helper.js.map