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);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
import { Metadata } from '@memberjunction/core';
import { Arg, Ctx, Field, ObjectType, Query, Resolver } from 'type-graphql';
import { GetReadOnlyProvider } from '../util.js';
/**
 * Result type for the IS-A child entity discovery query.
 * Returns the name of the child entity type that has a record matching
 * the given parent entity's primary key, or null if no child exists.
 */
let ISAChildEntityResult = class ISAChildEntityResult {
};
__decorate([
    Field(() => Boolean),
    __metadata("design:type", Boolean)
], ISAChildEntityResult.prototype, "Success", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], ISAChildEntityResult.prototype, "ChildEntityName", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], ISAChildEntityResult.prototype, "ErrorMessage", void 0);
ISAChildEntityResult = __decorate([
    ObjectType()
], ISAChildEntityResult);
export { ISAChildEntityResult };
/**
 * Result type for the IS-A child entities discovery query (plural).
 * Returns all child entity type names that have records matching the given
 * parent entity's primary key. Used for overlapping subtype parents.
 */
let ISAChildEntitiesResult = class ISAChildEntitiesResult {
};
__decorate([
    Field(() => Boolean),
    __metadata("design:type", Boolean)
], ISAChildEntitiesResult.prototype, "Success", void 0);
__decorate([
    Field(() => [String], { nullable: true }),
    __metadata("design:type", Array)
], ISAChildEntitiesResult.prototype, "ChildEntityNames", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], ISAChildEntitiesResult.prototype, "ErrorMessage", void 0);
ISAChildEntitiesResult = __decorate([
    ObjectType()
], ISAChildEntitiesResult);
export { ISAChildEntitiesResult };
/**
 * Resolver for IS-A entity hierarchy discovery.
 *
 * Provides GraphQL endpoints for client-side code to discover child entity
 * records in an IS-A hierarchy. This enables bidirectional chain construction
 * where a loaded entity discovers its more-derived child type.
 */
let ISAEntityResolver = class ISAEntityResolver {
    /**
     * Discovers which IS-A child entity, if any, has a record with the given
     * primary key value. The server executes a single UNION ALL query across
     * all child entity tables for maximum efficiency.
     *
     * @param EntityName The parent entity name to check children for
     * @param RecordID The primary key value to search for in child tables
     * @returns The child entity name if found, or null with Success=true if no child exists
     */
    async FindISAChildEntity(EntityName, RecordID, { providers, userPayload }) {
        try {
            const provider = GetReadOnlyProvider(providers, { allowFallbackToReadWrite: true });
            const md = new Metadata();
            const entityInfo = md.Entities.find(e => e.Name === EntityName);
            if (!entityInfo) {
                return {
                    Success: false,
                    ErrorMessage: `Entity '${EntityName}' not found`
                };
            }
            if (!entityInfo.IsParentType) {
                return { Success: true };
            }
            // Cast to IEntityDataProvider to access the optional FindISAChildEntity method
            const entityProvider = provider;
            if (!entityProvider.FindISAChildEntity) {
                return {
                    Success: false,
                    ErrorMessage: 'Provider does not support FindISAChildEntity'
                };
            }
            const result = await entityProvider.FindISAChildEntity(entityInfo, RecordID, userPayload?.userRecord);
            if (result) {
                return {
                    Success: true,
                    ChildEntityName: result.ChildEntityName
                };
            }
            return { Success: true };
        }
        catch (e) {
            return {
                Success: false,
                ErrorMessage: e instanceof Error ? e.message : String(e)
            };
        }
    }
    /**
     * Discovers ALL IS-A child entities that have records with the given primary
     * key value. Used for overlapping subtype parents (AllowMultipleSubtypes = true)
     * where multiple children can coexist. The server executes a single UNION ALL
     * query across all child entity tables for maximum efficiency.
     *
     * @param EntityName The parent entity name to check children for
     * @param RecordID The primary key value to search for in child tables
     * @returns Array of child entity names found (empty if none)
     */
    async FindISAChildEntities(EntityName, RecordID, { providers, userPayload }) {
        try {
            const provider = GetReadOnlyProvider(providers, { allowFallbackToReadWrite: true });
            const md = new Metadata();
            const entityInfo = md.Entities.find(e => e.Name === EntityName);
            if (!entityInfo) {
                return {
                    Success: false,
                    ErrorMessage: `Entity '${EntityName}' not found`
                };
            }
            if (!entityInfo.IsParentType) {
                return { Success: true, ChildEntityNames: [] };
            }
            const entityProvider = provider;
            if (!entityProvider.FindISAChildEntities) {
                return {
                    Success: false,
                    ErrorMessage: 'Provider does not support FindISAChildEntities'
                };
            }
            const results = await entityProvider.FindISAChildEntities(entityInfo, RecordID, userPayload?.userRecord);
            return {
                Success: true,
                ChildEntityNames: results.map(r => r.ChildEntityName)
            };
        }
        catch (e) {
            return {
                Success: false,
                ErrorMessage: e instanceof Error ? e.message : String(e)
            };
        }
    }
};
__decorate([
    Query(() => ISAChildEntityResult),
    __param(0, Arg('EntityName', () => String)),
    __param(1, Arg('RecordID', () => String)),
    __param(2, Ctx()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String, Object]),
    __metadata("design:returntype", Promise)
], ISAEntityResolver.prototype, "FindISAChildEntity", null);
__decorate([
    Query(() => ISAChildEntitiesResult),
    __param(0, Arg('EntityName', () => String)),
    __param(1, Arg('RecordID', () => String)),
    __param(2, Ctx()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, String, Object]),
    __metadata("design:returntype", Promise)
], ISAEntityResolver.prototype, "FindISAChildEntities", null);
ISAEntityResolver = __decorate([
    Resolver(ISAChildEntityResult)
], ISAEntityResolver);
export { ISAEntityResolver };
export default ISAEntityResolver;
//# sourceMappingURL=ISAEntityResolver.js.map