import { GraphQLError } from 'graphql';
import { dateToTimelessDateString, formatFinancialAmount } from '../../../shared/helpers/index.js';
import { normalizeDocumentType } from '../../documents/resolvers/common.js';
import { ClientsProvider } from '../../financial-entities/providers/clients.provider.js';
import { normalizeBillingCycle, normalizeProduct, normalizeSubscriptionPlan, } from '../helpers/contracts.helper.js';
import { ContractsProvider } from '../providers/contracts.provider.js';
export const contractsResolvers = {
    Query: {
        allOpenContracts: async (_, __, { injector }) => {
            try {
                return injector.get(ContractsProvider).getAllOpenContracts();
            }
            catch (e) {
                console.error('Error fetching countries', e);
                throw new GraphQLError('Error fetching countries');
            }
        },
        contractsByClient: async (_, { clientId }, { injector }) => {
            try {
                return injector.get(ContractsProvider).getContractsByClientIdLoader.load(clientId);
            }
            catch (e) {
                const message = 'Error fetching contracts by client';
                console.error(message, e);
                throw new GraphQLError(message);
            }
        },
        contractsByAdmin: async (_, { adminId }, { injector }) => {
            try {
                return injector.get(ContractsProvider).getContractsByAdminBusinessIdLoader.load(adminId);
            }
            catch (e) {
                const message = 'Error fetching contracts by admin';
                console.error(message, e);
                throw new GraphQLError(message);
            }
        },
        contractsById: async (_, { id }, { injector }) => {
            try {
                return injector
                    .get(ContractsProvider)
                    .getContractsByIdLoader.load(id)
                    .then(res => {
                    if (!res)
                        throw new GraphQLError('Contract not found');
                    return res;
                });
            }
            catch (e) {
                const message = 'Error fetching contracts by id';
                console.error(message, e);
                throw new GraphQLError(message);
            }
        },
    },
    Mutation: {
        createContract: async (_, { input }, { injector }) => {
            try {
                const params = {
                    amount: input.amount.raw,
                    billingCycle: input.billingCycle,
                    clientId: input.clientId,
                    currency: input.amount.currency,
                    documentType: input.documentType,
                    endDate: input.endDate,
                    isActive: input.isActive,
                    msCloud: input.msCloud?.toString(),
                    plan: input.plan,
                    product: input.product,
                    purchaseOrders: [...input.purchaseOrders],
                    remarks: input.remarks,
                    startDate: input.startDate,
                    operationsLimit: input.operationsLimit?.toString(),
                };
                if (input.deactivateContracts && input.deactivateContracts.length > 0) {
                    await Promise.all(input.deactivateContracts.map(contractId => injector.get(ContractsProvider).updateContract({ contractId, isActive: false })));
                }
                return injector.get(ContractsProvider).createContract(params);
            }
            catch (e) {
                console.error('Error creating contract', e);
                throw new GraphQLError('Error creating contract');
            }
        },
        updateContract: async (_, { contractId, input }, { injector }) => {
            try {
                const params = {
                    contractId,
                    amount: input.amount?.raw,
                    billingCycle: input.billingCycle,
                    clientId: input.clientId,
                    currency: input.amount?.currency,
                    documentType: input.documentType,
                    endDate: input.endDate,
                    isActive: input.isActive,
                    msCloud: input.msCloud?.toString(),
                    plan: input.plan,
                    product: input.product,
                    purchaseOrders: input.purchaseOrders ? [...input.purchaseOrders] : undefined,
                    remarks: input.remarks,
                    startDate: input.startDate,
                    operationsLimit: input.operationsLimit?.toString(),
                };
                return injector.get(ContractsProvider).updateContract(params);
            }
            catch (e) {
                console.error('Error updating contract', e);
                throw new GraphQLError('Error updating contract');
            }
        },
        deleteContract: async (_, { id }, { injector }) => {
            try {
                return injector.get(ContractsProvider).deleteContract(id);
            }
            catch (e) {
                console.error('Error deleting contract', e);
                throw new GraphQLError('Error deleting contract');
            }
        },
    },
    Contract: {
        id: dbContract => dbContract.id,
        client: async (dbContract, _, { injector }) => {
            return injector
                .get(ClientsProvider)
                .getClientByIdLoader.load(dbContract.client_id)
                .then(res => {
                if (!res)
                    throw new GraphQLError('Client not found');
                return res;
            })
                .catch(err => {
                console.error('Error fetching client', err);
                throw new GraphQLError('Error fetching client');
            });
        },
        purchaseOrders: dbContract => dbContract.purchase_orders, //String[]
        startDate: dbContract => dateToTimelessDateString(dbContract.start_date), //TimelessDate!
        endDate: dbContract => dateToTimelessDateString(dbContract.end_date), //TimelessDate!
        remarks: dbContract => dbContract.remarks, //String
        amount: dbContract => formatFinancialAmount(dbContract.amount, dbContract.currency), //FinancialAmount!
        documentType: dbContract => normalizeDocumentType(dbContract.document_type), //DocumentType!
        billingCycle: dbContract => normalizeBillingCycle(dbContract.billing_cycle), //BillingCycle!
        isActive: dbContract => dbContract.is_active ?? false, //Boolean!
        product: dbContract => normalizeProduct(dbContract.product), //Product!
        plan: dbContract => normalizeSubscriptionPlan(dbContract.plan), //SubscriptionPlan!
        msCloud: dbContract => dbContract.ms_cloud, //URL
        operationsLimit: dbContract => BigInt(dbContract.operations_count), //Int
    },
};
//# sourceMappingURL=contracts.resolver.js.map