import { GraphQLError } from 'graphql';
import { addGreenInvoiceClient, updateGreenInvoiceClient, } from '../../green-invoice/helpers/green-invoice-clients.helper.js';
import { validateClientIntegrations } from '../helpers/clients.helper.js';
import { BusinessesProvider } from '../providers/businesses.provider.js';
import { ClientsProvider } from '../providers/clients.provider.js';
export const clientsResolvers = {
    Query: {
        client: async (_, { businessId }, { injector }) => {
            try {
                const client = await injector.get(ClientsProvider).getClientByIdLoader.load(businessId);
                if (!client) {
                    throw new GraphQLError(`Client with ID "${businessId}" not found`);
                }
                return client;
            }
            catch (error) {
                const message = 'Failed to fetch client';
                console.error(message, error);
                throw new GraphQLError(message);
            }
        },
        allClients: async (_, __, { injector }) => {
            try {
                const matches = await injector.get(ClientsProvider).getAllClients();
                return matches;
            }
            catch (error) {
                const message = 'Failed to fetch clients';
                console.error(message, error);
                throw new GraphQLError(message);
            }
        },
    },
    Mutation: {
        updateClient: async (_, { businessId, fields }, { injector }) => {
            let updatedIntegrations = fields.integrations ?? undefined;
            if (updatedIntegrations) {
                const currentClient = await injector
                    .get(ClientsProvider)
                    .getClientByIdLoader.load(businessId);
                if (!currentClient) {
                    throw new GraphQLError(`Client with ID="${businessId}" not found`);
                }
                const currentIntegrations = validateClientIntegrations(currentClient.integrations);
                updatedIntegrations = {
                    ...currentIntegrations,
                    ...updatedIntegrations,
                };
            }
            const adjustedFields = {
                businessId,
                emails: fields.emails ? [...fields.emails] : undefined,
                newBusinessId: fields.newBusinessId,
                integrations: updatedIntegrations,
            };
            try {
                const [updatedClient] = await injector
                    .get(ClientsProvider)
                    .updateClient({ ...adjustedFields, businessId })
                    .catch((e) => {
                    const message = `Error updating client ID="${businessId}"`;
                    console.error(`${message}: ${e}`);
                    if (e instanceof GraphQLError) {
                        throw e;
                    }
                    throw new Error(message);
                });
                // update green invoice client if needed
                await updateGreenInvoiceClient(businessId, injector, undefined, fields);
                return updatedClient;
            }
            catch (e) {
                return {
                    __typename: 'CommonError',
                    message: `Failed to update client ID="${businessId}": ${e.message}`,
                };
            }
        },
        insertClient: async (_, { fields }, { injector }) => {
            try {
                const newClient = {
                    businessId: fields.businessId,
                    emails: fields.emails ? [...fields.emails] : [],
                    integrations: fields.integrations ?? {},
                };
                const [insertClient] = await injector.get(ClientsProvider).insertClient(newClient);
                if (!insertClient) {
                    throw new Error(`No client returned after insertion`);
                }
                // create green invoice client record
                await addGreenInvoiceClient(insertClient.business_id, injector);
                return insertClient;
            }
            catch (e) {
                console.error(e);
                return {
                    __typename: 'CommonError',
                    message: `Failed to create Client`,
                };
            }
        },
    },
    Client: {
        id: business => business.business_id,
        originalBusiness: async (business, _, { injector }) => {
            const businessMatch = await injector
                .get(BusinessesProvider)
                .getBusinessByIdLoader.load(business.business_id);
            if (!businessMatch) {
                throw new GraphQLError('Business not found');
            }
            return businessMatch;
        },
        emails: business => business.emails ?? [],
        integrations: business => business,
    },
    ClientIntegrations: {
        id: business => `${business.business_id}-integrations`,
        hiveId: business => validateClientIntegrations(business.integrations).hiveId ?? null,
        linearId: business => validateClientIntegrations(business.integrations).linearId ?? null,
        slackChannelKey: business => validateClientIntegrations(business.integrations).slackChannelKey ?? null,
        notionId: business => validateClientIntegrations(business.integrations).notionId ?? null,
        workflowyUrl: business => validateClientIntegrations(business.integrations).workflowyUrl ?? null,
    },
    LtdFinancialEntity: {
        clientInfo: async (business, _, { injector }) => {
            const client = await injector.get(ClientsProvider).getClientByIdLoader.load(business.id);
            return client || null;
        },
    },
    UpdateClientResponse: {
        __resolveType: (obj, _context, _info) => {
            if ('__typename' in obj && obj.__typename === 'CommonError')
                return 'CommonError';
            return 'Client';
        },
    },
};
//# sourceMappingURL=clients.resolvers.js.map