import { GraphQLError } from 'graphql';
import { AdminContextProvider } from '../../admin-context/providers/admin-context.provider.js';
import { SortCodesProvider } from '../../sort-codes/providers/sort-codes.provider.js';
import { hasFinancialEntitiesCoreProperties } from '../helpers/financial-entities.helper.js';
import { FinancialEntitiesProvider } from '../providers/financial-entities.provider.js';
import { TaxCategoriesProvider } from '../providers/tax-categories.provider.js';
import { commonTaxChargeFields } from './common.js';
export const taxCategoriesResolvers = {
    Query: {
        taxCategories: async (_parent, _args, { injector }) => {
            return injector
                .get(TaxCategoriesProvider)
                .getAllTaxCategories()
                .then(res => res.filter(c => !!c.name));
        },
        taxCategory: async (_, { id }, { injector }) => {
            try {
                const res = await injector.get(TaxCategoriesProvider).taxCategoryByIdLoader.load(id);
                if (!res) {
                    throw new Error('Nothing received from DB');
                }
                return res;
            }
            catch (error) {
                const message = `Tax category with ID="${id}" not found`;
                console.error(`${message}: ${error}`);
                throw new GraphQLError(message);
            }
        },
        taxCategoryByBusinessId: async (_, args, { injector }) => {
            const { businessId } = args;
            return injector
                .get(TaxCategoriesProvider)
                .taxCategoryByBusinessIDsLoader.load(businessId)
                .then(res => res ?? null);
        },
    },
    Mutation: {
        updateTaxCategory: async (_, { taxCategoryId, fields }, { injector }) => {
            if (hasFinancialEntitiesCoreProperties(fields)) {
                await injector.get(FinancialEntitiesProvider).updateFinancialEntity({
                    ...fields,
                    financialEntityId: taxCategoryId,
                    irsCode: fields.irsCode ?? null,
                    isActive: fields.isActive ?? true,
                });
            }
            const adjustedFields = {
                hashavshevetName: fields.hashavshevetName,
                taxExcluded: fields.taxExcluded,
                taxCategoryId,
            };
            try {
                if (fields.hashavshevetName || fields.taxExcluded != null) {
                    await injector
                        .get(TaxCategoriesProvider)
                        .updateTaxCategory(adjustedFields)
                        .catch((e) => {
                        const message = `Error updating tax category for business ID="${taxCategoryId}"`;
                        console.error(`${message}: ${e}`);
                        throw new Error(message);
                    });
                }
                const updatedTaxCategory = await injector
                    .get(TaxCategoriesProvider)
                    .taxCategoryByIdLoader.load(taxCategoryId);
                if (!updatedTaxCategory) {
                    throw new Error(`Updated tax category not found`);
                }
                return updatedTaxCategory;
            }
            catch (e) {
                return {
                    __typename: 'CommonError',
                    message: `Failed to update tax category ID="${taxCategoryId}": ${e.message}`,
                };
            }
        },
        insertTaxCategory: async (_, { fields }, { injector }) => {
            try {
                const { ownerId } = await injector.get(AdminContextProvider).getVerifiedAdminContext();
                let irsCode = fields.irsCode ?? null;
                if (!irsCode && fields.sortCode) {
                    const sortCode = await injector
                        .get(SortCodesProvider)
                        .getSortCodesByIdLoader.load({ key: fields.sortCode, ownerId });
                    if (sortCode?.default_irs_code) {
                        irsCode = sortCode.default_irs_code;
                    }
                }
                const [financialEntity] = await injector
                    .get(FinancialEntitiesProvider)
                    .insertFinancialEntity({
                    ownerId,
                    name: fields.name,
                    sortCode: fields.sortCode,
                    type: 'tax_category',
                    irsCode,
                    isActive: fields.isActive ?? true,
                })
                    .catch((e) => {
                    const message = `Failed to create financial entity: ${e.message}`;
                    console.error(`${message}: ${e}`);
                    throw new Error(message);
                });
                if (!financialEntity) {
                    throw new Error('Failed to create core financial entity');
                }
                const [taxCategory] = await injector.get(TaxCategoriesProvider).insertTaxCategory({
                    id: financialEntity.id,
                    hashavshevetName: fields.hashavshevetName,
                    taxExcluded: fields.taxExcluded ?? false,
                });
                return { ...financialEntity, ...taxCategory };
            }
            catch (e) {
                const message = 'Failed to create tax category';
                console.error(`${message}: ${e}`);
                throw new GraphQLError(message);
            }
        },
    },
    TaxCategory: {
        __isTypeOf: parent => 'hashavshevet_name' in parent,
        id: parent => parent.id,
        name: parent => parent.name,
    },
    CommonCharge: commonTaxChargeFields,
    FinancialCharge: commonTaxChargeFields,
    ConversionCharge: commonTaxChargeFields,
    SalaryCharge: commonTaxChargeFields,
    InternalTransferCharge: commonTaxChargeFields,
    DividendCharge: commonTaxChargeFields,
    BusinessTripCharge: commonTaxChargeFields,
    MonthlyVatCharge: commonTaxChargeFields,
    BankDepositCharge: commonTaxChargeFields,
    ForeignSecuritiesCharge: commonTaxChargeFields,
    CreditcardBankCharge: commonTaxChargeFields,
    LtdFinancialEntity: {
        taxCategory: async (parent, _, { injector }) => {
            const taxCategory = await injector
                .get(TaxCategoriesProvider)
                .taxCategoryByBusinessIDsLoader.load(parent.id);
            if (!taxCategory) {
                throw new GraphQLError(`Tax category for business ID="${parent.id}" not found`);
            }
            return taxCategory;
        },
    },
};
//# sourceMappingURL=tax-categories.resolver.js.map