import { __decorate, __metadata } from "tslib";
import DataLoader from 'dataloader';
import { GraphQLError } from 'graphql';
import { Injectable, Scope } from 'graphql-modules';
import { sql } from '@pgtyped/runtime';
import { reassureOwnerIdExists } from '../../../shared/helpers/index.js';
import { AdminContextProvider } from '../../admin-context/providers/admin-context.provider.js';
import { TenantAwareDBClient } from '../../app-providers/tenant-db-client.js';
const getTemplate = sql `
SELECT *
FROM accounter_schema.dynamic_report_templates
WHERE name = $name AND owner_id = $ownerId;`;
const getTemplatesByOwnerIds = sql `
SELECT *
FROM accounter_schema.dynamic_report_templates
WHERE owner_id IN $$ownerIds;`;
const updateTemplate = sql `
  UPDATE accounter_schema.dynamic_report_templates
  SET template = $template
  WHERE name = $name AND owner_id = $ownerId
  RETURNING *;`;
const updateTemplateName = sql `
  UPDATE accounter_schema.dynamic_report_templates
  SET name = $newName
  WHERE name = $prevName AND owner_id = $ownerId
  RETURNING *;`;
const insertTemplate = sql `
  INSERT INTO accounter_schema.dynamic_report_templates (name, owner_id, template)
  VALUES ($name, $ownerId, $template)
  RETURNING *;`;
const deleteTemplate = sql `
  DELETE FROM accounter_schema.dynamic_report_templates
  WHERE name = $name AND owner_id = $ownerId
  RETURNING name;`;
const lockTemplate = sql `
  UPDATE accounter_schema.dynamic_report_templates
  SET is_locked = TRUE
  WHERE name = $name AND owner_id = $ownerId
  RETURNING *;`;
const unlockTemplate = sql `
  UPDATE accounter_schema.dynamic_report_templates
  SET is_locked = FALSE
  WHERE name = $name AND owner_id = $ownerId
  RETURNING *;`;
let DynamicReportProvider = class DynamicReportProvider {
    db;
    adminContextProvider;
    constructor(db, adminContextProvider) {
        this.db = db;
        this.adminContextProvider = adminContextProvider;
    }
    async getTemplate(params) {
        return getTemplate.run(params, this.db).then(res => {
            const [template] = res;
            return template;
        });
    }
    async batchTemplatesByOwnerIdLoader(ownerIds) {
        const templates = await getTemplatesByOwnerIds.run({ ownerIds }, this.db);
        return ownerIds.map(id => templates.filter(template => template.owner_id === id));
    }
    getTemplatesByOwnerIdLoader = new DataLoader((ownerIds) => this.batchTemplatesByOwnerIdLoader(ownerIds));
    async updateTemplate(params) {
        if (params.name && params.ownerId) {
            await this.assertNotLocked(params.name, params.ownerId);
            this.invalidateByOwnerId(params.ownerId);
        }
        return updateTemplate.run(params, this.db);
    }
    async updateTemplateName(params) {
        if (params.prevName && params.ownerId) {
            await this.assertNotLocked(params.prevName, params.ownerId);
            this.invalidateByOwnerId(params.ownerId);
        }
        return updateTemplateName.run(params, this.db);
    }
    async insertTemplate(params) {
        if (params.ownerId) {
            this.invalidateByOwnerId(params.ownerId);
        }
        const { ownerId } = await this.adminContextProvider.getVerifiedAdminContext();
        return insertTemplate.run(reassureOwnerIdExists(params, ownerId), this.db);
    }
    async deleteTemplate(params) {
        if (params.name && params.ownerId) {
            await this.assertNotLocked(params.name, params.ownerId);
            this.invalidateByOwnerId(params.ownerId);
        }
        return deleteTemplate.run(params, this.db);
    }
    async lockTemplate(params) {
        if (params.ownerId) {
            this.invalidateByOwnerId(params.ownerId);
        }
        const results = await lockTemplate.run(params, this.db);
        if (results.length === 0) {
            throw new GraphQLError(`Report template "${params.name}" not found`);
        }
        return results[0];
    }
    async unlockTemplate(params) {
        if (params.ownerId) {
            this.invalidateByOwnerId(params.ownerId);
        }
        const results = await unlockTemplate.run(params, this.db);
        if (results.length === 0) {
            throw new GraphQLError(`Report template "${params.name}" not found`);
        }
        return results[0];
    }
    async assertNotLocked(name, ownerId) {
        const template = await this.getTemplate({ name, ownerId });
        if (template?.is_locked) {
            throw new GraphQLError(`Template "${name}" is locked and cannot be modified. Unlock it first.`);
        }
    }
    async invalidateByOwnerId(ownerId) {
        this.getTemplatesByOwnerIdLoader.clear(ownerId);
    }
    clearCache() {
        this.getTemplatesByOwnerIdLoader.clearAll();
    }
};
DynamicReportProvider = __decorate([
    Injectable({
        scope: Scope.Operation,
        global: true,
    }),
    __metadata("design:paramtypes", [TenantAwareDBClient,
        AdminContextProvider])
], DynamicReportProvider);
export { DynamicReportProvider };
//# sourceMappingURL=dynamic-report.provider.js.map