"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.IntegrationLinkService = void 0;
const api_prisma_1 = require("@hed-hog/api-prisma");
const common_1 = require("@nestjs/common");
const types_1 = require("../types");
let IntegrationLinkService = class IntegrationLinkService {
    constructor(prisma) {
        this.prisma = prisma;
    }
    resolvePersistence(persistenceClient) {
        var _a;
        const client = (persistenceClient !== null && persistenceClient !== void 0 ? persistenceClient : this.prisma);
        const delegate = (_a = client.integration_link) !== null && _a !== void 0 ? _a : client.integrationLink;
        const useSnakeCase = !!client.integration_link;
        if (!delegate) {
            throw new Error('Integration link delegate is not available on the Prisma client.');
        }
        return { delegate, useSnakeCase };
    }
    toDomainLink(record) {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
        return {
            id: String(record.id),
            sourceModule: (_b = (_a = record.source_module) !== null && _a !== void 0 ? _a : record.sourceModule) !== null && _b !== void 0 ? _b : '',
            sourceEntityType: (_d = (_c = record.source_entity_type) !== null && _c !== void 0 ? _c : record.sourceEntityType) !== null && _d !== void 0 ? _d : '',
            sourceEntityId: (_f = (_e = record.source_entity_id) !== null && _e !== void 0 ? _e : record.sourceEntityId) !== null && _f !== void 0 ? _f : '',
            targetModule: (_h = (_g = record.target_module) !== null && _g !== void 0 ? _g : record.targetModule) !== null && _h !== void 0 ? _h : '',
            targetEntityType: (_k = (_j = record.target_entity_type) !== null && _j !== void 0 ? _j : record.targetEntityType) !== null && _k !== void 0 ? _k : '',
            targetEntityId: (_m = (_l = record.target_entity_id) !== null && _l !== void 0 ? _l : record.targetEntityId) !== null && _m !== void 0 ? _m : '',
            linkType: ((_p = (_o = record.link_type) !== null && _o !== void 0 ? _o : record.linkType) !== null && _p !== void 0 ? _p : types_1.LinkType.REFERENCE),
            metadata: (_q = record.metadata) !== null && _q !== void 0 ? _q : null,
            createdAt: (_s = (_r = record.created_at) !== null && _r !== void 0 ? _r : record.createdAt) !== null && _s !== void 0 ? _s : new Date(),
            updatedAt: (_u = (_t = record.updated_at) !== null && _t !== void 0 ? _t : record.updatedAt) !== null && _u !== void 0 ? _u : new Date(),
        };
    }
    toDatabaseId(linkId) {
        if (typeof linkId === 'number') {
            return linkId;
        }
        const numericId = Number(linkId);
        return Number.isNaN(numericId) ? linkId : numericId;
    }
    /**
     * Create a link between entities from different modules
     */
    async createLink(dto, persistenceClient) {
        const { delegate, useSnakeCase } = this.resolvePersistence(persistenceClient);
        const record = await delegate.create({
            data: useSnakeCase
                ? {
                    source_module: dto.sourceModule,
                    source_entity_type: dto.sourceEntityType,
                    source_entity_id: dto.sourceEntityId,
                    target_module: dto.targetModule,
                    target_entity_type: dto.targetEntityType,
                    target_entity_id: dto.targetEntityId,
                    link_type: dto.linkType,
                    metadata: dto.metadata || null,
                }
                : {
                    sourceModule: dto.sourceModule,
                    sourceEntityType: dto.sourceEntityType,
                    sourceEntityId: dto.sourceEntityId,
                    targetModule: dto.targetModule,
                    targetEntityType: dto.targetEntityType,
                    targetEntityId: dto.targetEntityId,
                    linkType: dto.linkType,
                    metadata: dto.metadata || null,
                },
        });
        return this.toDomainLink(record);
    }
    /**
     * Find all links originating from a source entity
     */
    async findOutbound(sourceModule, sourceEntityType, sourceEntityId) {
        const { delegate, useSnakeCase } = this.resolvePersistence();
        const records = await delegate.findMany({
            where: useSnakeCase
                ? {
                    source_module: sourceModule,
                    source_entity_type: sourceEntityType,
                    source_entity_id: sourceEntityId,
                }
                : {
                    sourceModule,
                    sourceEntityType,
                    sourceEntityId,
                },
        });
        return records.map((record) => this.toDomainLink(record));
    }
    /**
     * Find all links terminating at a target entity
     */
    async findInbound(targetModule, targetEntityType, targetEntityId) {
        const { delegate, useSnakeCase } = this.resolvePersistence();
        const records = await delegate.findMany({
            where: useSnakeCase
                ? {
                    target_module: targetModule,
                    target_entity_type: targetEntityType,
                    target_entity_id: targetEntityId,
                }
                : {
                    targetModule,
                    targetEntityType,
                    targetEntityId,
                },
        });
        return records.map((record) => this.toDomainLink(record));
    }
    /**
     * Find links of a specific type
     */
    async findByLinkType(linkType) {
        const { delegate, useSnakeCase } = this.resolvePersistence();
        const records = await delegate.findMany({
            where: useSnakeCase ? { link_type: linkType } : { linkType },
        });
        return records.map((record) => this.toDomainLink(record));
    }
    /**
     * Delete a link
     */
    async deleteLink(linkId) {
        const { delegate } = this.resolvePersistence();
        const record = await delegate.delete({
            where: { id: this.toDatabaseId(linkId) },
        });
        return this.toDomainLink(record);
    }
    /**
     * Get link by ID
     */
    async getById(linkId) {
        const { delegate } = this.resolvePersistence();
        const record = await delegate.findUnique({
            where: { id: this.toDatabaseId(linkId) },
        });
        return record ? this.toDomainLink(record) : null;
    }
    /**
     * Find bidirectional link between two entities
     */
    async findBidirectional(module1, entity1Type, entity1Id, module2, entity2Type, entity2Id) {
        const { delegate, useSnakeCase } = this.resolvePersistence();
        const record = await delegate.findFirst({
            where: {
                OR: useSnakeCase
                    ? [
                        {
                            source_module: module1,
                            source_entity_type: entity1Type,
                            source_entity_id: entity1Id,
                            target_module: module2,
                            target_entity_type: entity2Type,
                            target_entity_id: entity2Id,
                        },
                        {
                            source_module: module2,
                            source_entity_type: entity2Type,
                            source_entity_id: entity2Id,
                            target_module: module1,
                            target_entity_type: entity1Type,
                            target_entity_id: entity1Id,
                        },
                    ]
                    : [
                        {
                            sourceModule: module1,
                            sourceEntityType: entity1Type,
                            sourceEntityId: entity1Id,
                            targetModule: module2,
                            targetEntityType: entity2Type,
                            targetEntityId: entity2Id,
                        },
                        {
                            sourceModule: module2,
                            sourceEntityType: entity2Type,
                            sourceEntityId: entity2Id,
                            targetModule: module1,
                            targetEntityType: entity1Type,
                            targetEntityId: entity1Id,
                        },
                    ],
            },
        });
        return record ? this.toDomainLink(record) : null;
    }
    /**
     * Count links from a module
     */
    async countFromModule(sourceModule) {
        const { delegate, useSnakeCase } = this.resolvePersistence();
        return delegate.count({
            where: useSnakeCase ? { source_module: sourceModule } : { sourceModule },
        });
    }
};
exports.IntegrationLinkService = IntegrationLinkService;
exports.IntegrationLinkService = IntegrationLinkService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [api_prisma_1.PrismaService])
], IntegrationLinkService);
//# sourceMappingURL=integration-link.service.js.map