import { DECREASED_VAT_RATIO } from '../../../shared/constants.js';
import { DocumentType } from '../../../shared/enums.js';
import { dateToTimelessDateString, formatCurrency } from '../../../shared/helpers/index.js';
import { AdminContextProvider } from '../../admin-context/providers/admin-context.provider.js';
import { getChargeDocumentsMeta, getChargeTransactionsMeta, } from '../../charges/helpers/common.helper.js';
import { DepreciationProvider } from '../../depreciation/providers/depreciation.provider.js';
import { ExchangeProvider } from '../../exchange-rates/providers/exchange.provider.js';
import { VatProvider } from '../../vat/providers/vat.provider.js';
export async function adjustTaxRecord(rawRecord, injector) {
    const { defaultLocalCurrency, locality } = await injector
        .get(AdminContextProvider)
        .getVerifiedAdminContext();
    try {
        const { charge, doc, business } = rawRecord;
        const currency = formatCurrency(doc.currency_code);
        if (!doc.total_amount) {
            throw new Error(`Amount missing for invoice ID=${doc.id}`);
        }
        if (!doc.currency_code) {
            throw new Error(`Currency missing for invoice ID=${doc.id}`);
        }
        if (!doc.date) {
            throw new Error(`Date is missing for invoice ID=${doc.id}`);
        }
        const [isProperty, { transactionsMinEventDate }, { documentsMinDate }] = await Promise.all([
            injector
                .get(DepreciationProvider)
                .getDepreciationRecordsByChargeIdLoader.load(charge.id)
                .then(records => records.length > 0),
            getChargeTransactionsMeta(charge.id, injector),
            getChargeDocumentsMeta(charge.id, injector),
        ]);
        const isDecreasedVat = charge.is_property;
        if (isDecreasedVat && !isProperty) {
            throw new Error(`Charge ${charge.id} is marked as property, but has no depreciation records.`);
        }
        // get exchange rate
        let rate = 1;
        if (doc.exchange_rate_override) {
            rate = Number(doc.exchange_rate_override);
        }
        else {
            rate = await injector
                .get(ExchangeProvider)
                .getExchangeRates(currency, defaultLocalCurrency, doc.date);
        }
        const creditInvoiceFactor = doc.type === DocumentType.CreditInvoice ? -1 : 1;
        const vatAmount = doc.vat_amount ? doc.vat_amount * creditInvoiceFactor : 0;
        const totalAmount = doc.total_amount * creditInvoiceFactor;
        const noVatAmount = doc.no_vat_amount ? Number(doc.no_vat_amount) * creditInvoiceFactor : 0;
        const isLocal = business.country === locality;
        const partialRecord = {
            businessId: business.id,
            chargeAccountantStatus: charge.accountant_status,
            chargeDate: transactionsMinEventDate ?? documentsMinDate, // must have min_date, as will throw if local doc is missing date
            chargeId: charge.id,
            currencyCode: currency,
            documentDate: doc.date,
            documentId: doc.id,
            documentSerial: doc.serial_number,
            documentUrl: doc.image_url,
            documentAmount: String(creditInvoiceFactor * totalAmount),
            foreignVat: doc.currency_code === defaultLocalCurrency ? null : vatAmount,
            localVat: doc.currency_code === defaultLocalCurrency ? vatAmount : null,
            isProperty,
            vatNumber: isLocal ? business.vat_number : undefined,
            isExpense: doc.type === DocumentType.CreditInvoice
                ? doc.debtor_id !== doc.owner_id
                : doc.debtor_id === doc.owner_id,
            allocationNumber: doc.allocation_number,
            pcn874RecordType: business.pcn874_record_type_override ?? undefined,
        };
        // set default amountBeforeVAT
        if (!vatAmount) {
            partialRecord.localAmountBeforeVAT = (totalAmount - noVatAmount) * rate;
        }
        else if (partialRecord.businessId) {
            const vatValue = await injector
                .get(VatProvider)
                .getVatValueByDateLoader.load(dateToTimelessDateString(doc.date));
            if (!vatValue) {
                throw new Error(`VAT value is missing for invoice ID=${doc.id}`);
            }
            const convertedVat = vatValue / (1 + vatValue);
            const tiplessTotalAmount = totalAmount - noVatAmount;
            const vatDiff = Math.abs(tiplessTotalAmount * convertedVat - vatAmount);
            if (vatDiff > 0.005) {
                console.error(`Expected VAT amount is not ${vatValue * 100}%, but got ${vatAmount / (tiplessTotalAmount - vatAmount)} for invoice ID=${doc.id}`);
            }
            // decorate record with additional fields
            const vatAfterDeduction = vatAmount * (isDecreasedVat ? DECREASED_VAT_RATIO : 1);
            const amountBeforeVAT = totalAmount - vatAfterDeduction;
            partialRecord.foreignVatAfterDeduction = vatAfterDeduction;
            partialRecord.localVatAfterDeduction = vatAfterDeduction * rate;
            partialRecord.foreignAmountBeforeVAT = amountBeforeVAT;
            partialRecord.localAmountBeforeVAT = amountBeforeVAT * rate;
            partialRecord.roundedVATToAdd = Math.round(vatAfterDeduction * rate);
            partialRecord.eventLocalAmount = totalAmount * rate;
        }
        return partialRecord;
    }
    catch (e) {
        console.error(e);
        throw e;
    }
}
//# sourceMappingURL=vat-report.helper.js.map