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 { Arg, Ctx, Field, InputType, Mutation, ObjectType, registerEnumType, Resolver, PubSub, PubSubEngine } from 'type-graphql';
import { LogError, RunView, CompositeKey, LogStatus } from '@memberjunction/core';
import { RequireSystemUser } from '../directives/RequireSystemUser.js';
import { MJQueryResolver } from '../generated/generated.js';
import { GetReadWriteProvider } from '../util.js';
import { DeleteOptionsInput } from '../generic/DeleteOptionsInput.js';
export var QueryStatus;
(function (QueryStatus) {
    QueryStatus["Pending"] = "Pending";
    QueryStatus["Approved"] = "Approved";
    QueryStatus["Rejected"] = "Rejected";
    QueryStatus["Expired"] = "Expired";
})(QueryStatus || (QueryStatus = {}));
registerEnumType(QueryStatus, {
    name: "QueryStatus",
    description: "Status of a query: Pending, Approved, Rejected, or Expired"
});
let QueryPermissionInputType = class QueryPermissionInputType {
    RoleID;
};
__decorate([
    Field(() => String),
    __metadata("design:type", String)
], QueryPermissionInputType.prototype, "RoleID", void 0);
QueryPermissionInputType = __decorate([
    InputType()
], QueryPermissionInputType);
export { QueryPermissionInputType };
let CreateQuerySystemUserInput = class CreateQuerySystemUserInput {
    Name;
    CategoryID;
    CategoryPath;
    UserQuestion;
    Description;
    SQL;
    TechnicalDescription;
    OriginalSQL;
    Feedback;
    Status;
    QualityRank;
    ExecutionCostRank;
    UsesTemplate;
    AuditQueryRuns;
    CacheEnabled;
    CacheTTLMinutes;
    CacheMaxSize;
    Permissions;
};
__decorate([
    Field(() => String),
    __metadata("design:type", String)
], CreateQuerySystemUserInput.prototype, "Name", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], CreateQuerySystemUserInput.prototype, "CategoryID", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], CreateQuerySystemUserInput.prototype, "CategoryPath", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], CreateQuerySystemUserInput.prototype, "UserQuestion", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], CreateQuerySystemUserInput.prototype, "Description", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], CreateQuerySystemUserInput.prototype, "SQL", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], CreateQuerySystemUserInput.prototype, "TechnicalDescription", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], CreateQuerySystemUserInput.prototype, "OriginalSQL", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], CreateQuerySystemUserInput.prototype, "Feedback", void 0);
__decorate([
    Field(() => QueryStatus, { nullable: true, defaultValue: QueryStatus.Pending }),
    __metadata("design:type", String)
], CreateQuerySystemUserInput.prototype, "Status", void 0);
__decorate([
    Field(() => Number, { nullable: true }),
    __metadata("design:type", Number)
], CreateQuerySystemUserInput.prototype, "QualityRank", void 0);
__decorate([
    Field(() => Number, { nullable: true }),
    __metadata("design:type", Number)
], CreateQuerySystemUserInput.prototype, "ExecutionCostRank", void 0);
__decorate([
    Field(() => Boolean, { nullable: true }),
    __metadata("design:type", Boolean)
], CreateQuerySystemUserInput.prototype, "UsesTemplate", void 0);
__decorate([
    Field(() => Boolean, { nullable: true }),
    __metadata("design:type", Boolean)
], CreateQuerySystemUserInput.prototype, "AuditQueryRuns", void 0);
__decorate([
    Field(() => Boolean, { nullable: true }),
    __metadata("design:type", Boolean)
], CreateQuerySystemUserInput.prototype, "CacheEnabled", void 0);
__decorate([
    Field(() => Number, { nullable: true }),
    __metadata("design:type", Number)
], CreateQuerySystemUserInput.prototype, "CacheTTLMinutes", void 0);
__decorate([
    Field(() => Number, { nullable: true }),
    __metadata("design:type", Number)
], CreateQuerySystemUserInput.prototype, "CacheMaxSize", void 0);
__decorate([
    Field(() => [QueryPermissionInputType], { nullable: true }),
    __metadata("design:type", Array)
], CreateQuerySystemUserInput.prototype, "Permissions", void 0);
CreateQuerySystemUserInput = __decorate([
    InputType()
], CreateQuerySystemUserInput);
export { CreateQuerySystemUserInput };
let UpdateQuerySystemUserInput = class UpdateQuerySystemUserInput {
    ID;
    Name;
    CategoryID;
    CategoryPath;
    UserQuestion;
    Description;
    SQL;
    TechnicalDescription;
    OriginalSQL;
    Feedback;
    Status;
    QualityRank;
    ExecutionCostRank;
    UsesTemplate;
    AuditQueryRuns;
    CacheEnabled;
    CacheTTLMinutes;
    CacheMaxSize;
    Permissions;
};
__decorate([
    Field(() => String),
    __metadata("design:type", String)
], UpdateQuerySystemUserInput.prototype, "ID", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], UpdateQuerySystemUserInput.prototype, "Name", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], UpdateQuerySystemUserInput.prototype, "CategoryID", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], UpdateQuerySystemUserInput.prototype, "CategoryPath", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], UpdateQuerySystemUserInput.prototype, "UserQuestion", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], UpdateQuerySystemUserInput.prototype, "Description", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], UpdateQuerySystemUserInput.prototype, "SQL", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], UpdateQuerySystemUserInput.prototype, "TechnicalDescription", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], UpdateQuerySystemUserInput.prototype, "OriginalSQL", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], UpdateQuerySystemUserInput.prototype, "Feedback", void 0);
__decorate([
    Field(() => QueryStatus, { nullable: true }),
    __metadata("design:type", String)
], UpdateQuerySystemUserInput.prototype, "Status", void 0);
__decorate([
    Field(() => Number, { nullable: true }),
    __metadata("design:type", Number)
], UpdateQuerySystemUserInput.prototype, "QualityRank", void 0);
__decorate([
    Field(() => Number, { nullable: true }),
    __metadata("design:type", Number)
], UpdateQuerySystemUserInput.prototype, "ExecutionCostRank", void 0);
__decorate([
    Field(() => Boolean, { nullable: true }),
    __metadata("design:type", Boolean)
], UpdateQuerySystemUserInput.prototype, "UsesTemplate", void 0);
__decorate([
    Field(() => Boolean, { nullable: true }),
    __metadata("design:type", Boolean)
], UpdateQuerySystemUserInput.prototype, "AuditQueryRuns", void 0);
__decorate([
    Field(() => Boolean, { nullable: true }),
    __metadata("design:type", Boolean)
], UpdateQuerySystemUserInput.prototype, "CacheEnabled", void 0);
__decorate([
    Field(() => Number, { nullable: true }),
    __metadata("design:type", Number)
], UpdateQuerySystemUserInput.prototype, "CacheTTLMinutes", void 0);
__decorate([
    Field(() => Number, { nullable: true }),
    __metadata("design:type", Number)
], UpdateQuerySystemUserInput.prototype, "CacheMaxSize", void 0);
__decorate([
    Field(() => [QueryPermissionInputType], { nullable: true }),
    __metadata("design:type", Array)
], UpdateQuerySystemUserInput.prototype, "Permissions", void 0);
UpdateQuerySystemUserInput = __decorate([
    InputType()
], UpdateQuerySystemUserInput);
export { UpdateQuerySystemUserInput };
let QueryFieldType = class QueryFieldType {
    ID;
    QueryID;
    Name;
    Description;
    Sequence;
    SQLBaseType;
    SQLFullType;
    SourceEntityID;
    SourceEntity;
    SourceFieldName;
    IsComputed;
    ComputationDescription;
    IsSummary;
    SummaryDescription;
};
__decorate([
    Field(() => String),
    __metadata("design:type", String)
], QueryFieldType.prototype, "ID", void 0);
__decorate([
    Field(() => String),
    __metadata("design:type", String)
], QueryFieldType.prototype, "QueryID", void 0);
__decorate([
    Field(() => String),
    __metadata("design:type", String)
], QueryFieldType.prototype, "Name", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], QueryFieldType.prototype, "Description", void 0);
__decorate([
    Field(() => Number),
    __metadata("design:type", Number)
], QueryFieldType.prototype, "Sequence", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], QueryFieldType.prototype, "SQLBaseType", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], QueryFieldType.prototype, "SQLFullType", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], QueryFieldType.prototype, "SourceEntityID", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], QueryFieldType.prototype, "SourceEntity", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], QueryFieldType.prototype, "SourceFieldName", void 0);
__decorate([
    Field(() => Boolean),
    __metadata("design:type", Boolean)
], QueryFieldType.prototype, "IsComputed", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], QueryFieldType.prototype, "ComputationDescription", void 0);
__decorate([
    Field(() => Boolean, { nullable: true }),
    __metadata("design:type", Boolean)
], QueryFieldType.prototype, "IsSummary", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], QueryFieldType.prototype, "SummaryDescription", void 0);
QueryFieldType = __decorate([
    ObjectType()
], QueryFieldType);
export { QueryFieldType };
let QueryParameterType = class QueryParameterType {
    ID;
    QueryID;
    Name;
    Description;
    Type;
    IsRequired;
    DefaultValue;
    SampleValue;
    ValidationFilters;
};
__decorate([
    Field(() => String),
    __metadata("design:type", String)
], QueryParameterType.prototype, "ID", void 0);
__decorate([
    Field(() => String),
    __metadata("design:type", String)
], QueryParameterType.prototype, "QueryID", void 0);
__decorate([
    Field(() => String),
    __metadata("design:type", String)
], QueryParameterType.prototype, "Name", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], QueryParameterType.prototype, "Description", void 0);
__decorate([
    Field(() => String),
    __metadata("design:type", String)
], QueryParameterType.prototype, "Type", void 0);
__decorate([
    Field(() => Boolean),
    __metadata("design:type", Boolean)
], QueryParameterType.prototype, "IsRequired", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], QueryParameterType.prototype, "DefaultValue", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], QueryParameterType.prototype, "SampleValue", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], QueryParameterType.prototype, "ValidationFilters", void 0);
QueryParameterType = __decorate([
    ObjectType()
], QueryParameterType);
export { QueryParameterType };
let QueryEntityType = class QueryEntityType {
    ID;
    QueryID;
    EntityID;
    Entity;
};
__decorate([
    Field(() => String),
    __metadata("design:type", String)
], QueryEntityType.prototype, "ID", void 0);
__decorate([
    Field(() => String),
    __metadata("design:type", String)
], QueryEntityType.prototype, "QueryID", void 0);
__decorate([
    Field(() => String),
    __metadata("design:type", String)
], QueryEntityType.prototype, "EntityID", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], QueryEntityType.prototype, "Entity", void 0);
QueryEntityType = __decorate([
    ObjectType()
], QueryEntityType);
export { QueryEntityType };
let QueryPermissionType = class QueryPermissionType {
    ID;
    QueryID;
    RoleID;
    Role;
};
__decorate([
    Field(() => String),
    __metadata("design:type", String)
], QueryPermissionType.prototype, "ID", void 0);
__decorate([
    Field(() => String),
    __metadata("design:type", String)
], QueryPermissionType.prototype, "QueryID", void 0);
__decorate([
    Field(() => String),
    __metadata("design:type", String)
], QueryPermissionType.prototype, "RoleID", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], QueryPermissionType.prototype, "Role", void 0);
QueryPermissionType = __decorate([
    ObjectType()
], QueryPermissionType);
export { QueryPermissionType };
let CreateQueryResultType = class CreateQueryResultType {
    Success;
    ErrorMessage;
    ID;
    Name;
    Description;
    CategoryID;
    Category;
    SQL;
    Status;
    QualityRank;
    EmbeddingVector;
    EmbeddingModelID;
    EmbeddingModelName;
    Fields;
    Parameters;
    Entities;
    Permissions;
};
__decorate([
    Field(() => Boolean),
    __metadata("design:type", Boolean)
], CreateQueryResultType.prototype, "Success", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], CreateQueryResultType.prototype, "ErrorMessage", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], CreateQueryResultType.prototype, "ID", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], CreateQueryResultType.prototype, "Name", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], CreateQueryResultType.prototype, "Description", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], CreateQueryResultType.prototype, "CategoryID", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], CreateQueryResultType.prototype, "Category", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], CreateQueryResultType.prototype, "SQL", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], CreateQueryResultType.prototype, "Status", void 0);
__decorate([
    Field(() => Number, { nullable: true }),
    __metadata("design:type", Number)
], CreateQueryResultType.prototype, "QualityRank", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], CreateQueryResultType.prototype, "EmbeddingVector", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], CreateQueryResultType.prototype, "EmbeddingModelID", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], CreateQueryResultType.prototype, "EmbeddingModelName", void 0);
__decorate([
    Field(() => [QueryFieldType], { nullable: true }),
    __metadata("design:type", Array)
], CreateQueryResultType.prototype, "Fields", void 0);
__decorate([
    Field(() => [QueryParameterType], { nullable: true }),
    __metadata("design:type", Array)
], CreateQueryResultType.prototype, "Parameters", void 0);
__decorate([
    Field(() => [QueryEntityType], { nullable: true }),
    __metadata("design:type", Array)
], CreateQueryResultType.prototype, "Entities", void 0);
__decorate([
    Field(() => [QueryPermissionType], { nullable: true }),
    __metadata("design:type", Array)
], CreateQueryResultType.prototype, "Permissions", void 0);
CreateQueryResultType = __decorate([
    ObjectType()
], CreateQueryResultType);
export { CreateQueryResultType };
let UpdateQueryResultType = class UpdateQueryResultType {
    Success;
    ErrorMessage;
    ID;
    Name;
    Description;
    CategoryID;
    Category;
    SQL;
    Status;
    QualityRank;
    EmbeddingVector;
    EmbeddingModelID;
    EmbeddingModelName;
    Fields;
    Parameters;
    Entities;
    Permissions;
};
__decorate([
    Field(() => Boolean),
    __metadata("design:type", Boolean)
], UpdateQueryResultType.prototype, "Success", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], UpdateQueryResultType.prototype, "ErrorMessage", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], UpdateQueryResultType.prototype, "ID", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], UpdateQueryResultType.prototype, "Name", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], UpdateQueryResultType.prototype, "Description", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], UpdateQueryResultType.prototype, "CategoryID", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], UpdateQueryResultType.prototype, "Category", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], UpdateQueryResultType.prototype, "SQL", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], UpdateQueryResultType.prototype, "Status", void 0);
__decorate([
    Field(() => Number, { nullable: true }),
    __metadata("design:type", Number)
], UpdateQueryResultType.prototype, "QualityRank", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], UpdateQueryResultType.prototype, "EmbeddingVector", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], UpdateQueryResultType.prototype, "EmbeddingModelID", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], UpdateQueryResultType.prototype, "EmbeddingModelName", void 0);
__decorate([
    Field(() => [QueryFieldType], { nullable: true }),
    __metadata("design:type", Array)
], UpdateQueryResultType.prototype, "Fields", void 0);
__decorate([
    Field(() => [QueryParameterType], { nullable: true }),
    __metadata("design:type", Array)
], UpdateQueryResultType.prototype, "Parameters", void 0);
__decorate([
    Field(() => [QueryEntityType], { nullable: true }),
    __metadata("design:type", Array)
], UpdateQueryResultType.prototype, "Entities", void 0);
__decorate([
    Field(() => [QueryPermissionType], { nullable: true }),
    __metadata("design:type", Array)
], UpdateQueryResultType.prototype, "Permissions", void 0);
UpdateQueryResultType = __decorate([
    ObjectType()
], UpdateQueryResultType);
export { UpdateQueryResultType };
let DeleteQueryResultType = class DeleteQueryResultType {
    Success;
    ErrorMessage;
    ID;
    Name;
    Description;
    CategoryID;
    SQL;
    Status;
};
__decorate([
    Field(() => Boolean),
    __metadata("design:type", Boolean)
], DeleteQueryResultType.prototype, "Success", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], DeleteQueryResultType.prototype, "ErrorMessage", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], DeleteQueryResultType.prototype, "ID", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], DeleteQueryResultType.prototype, "Name", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], DeleteQueryResultType.prototype, "Description", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], DeleteQueryResultType.prototype, "CategoryID", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], DeleteQueryResultType.prototype, "SQL", void 0);
__decorate([
    Field(() => String, { nullable: true }),
    __metadata("design:type", String)
], DeleteQueryResultType.prototype, "Status", void 0);
DeleteQueryResultType = __decorate([
    ObjectType()
], DeleteQueryResultType);
export { DeleteQueryResultType };
let MJQueryResolverExtended = class MJQueryResolverExtended extends MJQueryResolver {
    async CreateQuerySystemUser(input, context, pubSub) {
        try {
            let finalCategoryID = input.CategoryID;
            const provider = GetReadWriteProvider(context.providers);
            if (input.CategoryPath) {
                finalCategoryID = await this.findOrCreateCategoryPath(input.CategoryPath, provider, context.userPayload.userRecord);
            }
            const existingQuery = await this.findExistingQuery(provider, input.Name, finalCategoryID, context.userPayload.userRecord);
            if (existingQuery) {
                const categoryInfo = input.CategoryPath ? `category path '${input.CategoryPath}'` : `category ID '${finalCategoryID}'`;
                return {
                    Success: false,
                    ErrorMessage: `Query with name '${input.Name}' already exists in ${categoryInfo}`
                };
            }
            const record = await provider.GetEntityObject("Queries", context.userPayload.userRecord);
            const fieldsToSet = {
                ...input,
                CategoryID: finalCategoryID || input.CategoryID,
                Status: input.Status || 'Approved',
                QualityRank: input.QualityRank || 0,
                UsesTemplate: input.UsesTemplate || false,
                AuditQueryRuns: input.AuditQueryRuns || false,
                CacheEnabled: input.CacheEnabled || false,
                CacheTTLMinutes: input.CacheTTLMinutes || null,
                CacheMaxSize: input.CacheMaxSize || null
            };
            delete fieldsToSet.Permissions;
            delete fieldsToSet.CategoryPath;
            record.SetMany(fieldsToSet, true);
            this.ListenForEntityMessages(record, pubSub, context.userPayload.userRecord);
            const saveResult = await record.Save();
            if (saveResult) {
                await this.AfterCreate(provider, input);
                const queryID = record.ID;
                if (input.Permissions && input.Permissions.length > 0) {
                    await this.createPermissions(provider, input.Permissions, queryID, context.userPayload.userRecord);
                    await record.RefreshRelatedMetadata(true);
                }
                await provider.Refresh();
                return {
                    Success: true,
                    ID: record.ID,
                    Name: record.Name,
                    Description: record.Description,
                    CategoryID: record.CategoryID,
                    Category: record.Category,
                    SQL: record.SQL,
                    Status: record.Status,
                    QualityRank: record.QualityRank,
                    EmbeddingVector: record.EmbeddingVector,
                    EmbeddingModelID: record.EmbeddingModelID,
                    EmbeddingModelName: record.EmbeddingModel,
                    Fields: record.QueryFields.map(f => ({
                        ID: f.ID,
                        QueryID: f.QueryID,
                        Name: f.Name,
                        Description: f.Description,
                        Sequence: f.Sequence,
                        SQLBaseType: f.SQLBaseType,
                        SQLFullType: f.SQLFullType,
                        SourceEntityID: f.SourceEntityID,
                        SourceEntity: f.SourceEntity,
                        SourceFieldName: f.SourceFieldName,
                        IsComputed: f.IsComputed,
                        ComputationDescription: f.ComputationDescription,
                        IsSummary: f.IsSummary,
                        SummaryDescription: f.SummaryDescription
                    })),
                    Parameters: record.QueryParameters.map(p => ({
                        ID: p.ID,
                        QueryID: p.QueryID,
                        Name: p.Name,
                        Description: p.Description,
                        Type: p.Type,
                        IsRequired: p.IsRequired,
                        DefaultValue: p.DefaultValue,
                        SampleValue: p.SampleValue,
                        ValidationFilters: p.ValidationFilters
                    })),
                    Entities: record.QueryEntities.map(e => ({
                        ID: e.ID,
                        QueryID: e.QueryID,
                        EntityID: e.EntityID,
                        Entity: e.Entity
                    })),
                    Permissions: record.QueryPermissions.map(p => ({
                        ID: p.ID,
                        QueryID: p.QueryID,
                        RoleID: p.RoleID,
                        Role: p.Role
                    }))
                };
            }
            else {
                const existingQuery = await this.findExistingQuery(provider, input.Name, finalCategoryID, context.userPayload.userRecord);
                if (existingQuery) {
                    LogStatus(`[CreateQuery] Unique constraint detected for query '${input.Name}'. Using existing query (ID: ${existingQuery.ID}) created by concurrent request.`);
                    return {
                        Success: true,
                        ID: existingQuery.ID,
                        Name: existingQuery.Name,
                        Description: existingQuery.Description,
                        CategoryID: existingQuery.CategoryID,
                        Category: existingQuery.Category,
                        SQL: existingQuery.SQL,
                        Status: existingQuery.Status,
                        QualityRank: existingQuery.QualityRank,
                        EmbeddingVector: existingQuery.EmbeddingVector,
                        EmbeddingModelID: existingQuery.EmbeddingModelID,
                        EmbeddingModelName: existingQuery.EmbeddingModel,
                        Fields: existingQuery.Fields?.map((f) => ({
                            ID: f.ID,
                            QueryID: f.QueryID,
                            Name: f.Name,
                            Description: f.Description,
                            Sequence: f.Sequence,
                            SQLBaseType: f.SQLBaseType,
                            SQLFullType: f.SQLFullType,
                            SourceEntityID: f.SourceEntityID,
                            SourceEntity: f.SourceEntity,
                            SourceFieldName: f.SourceFieldName,
                            IsComputed: f.IsComputed,
                            ComputationDescription: f.ComputationDescription,
                            IsSummary: f.IsSummary,
                            SummaryDescription: f.SummaryDescription
                        })) || [],
                        Parameters: existingQuery.Parameters?.map((p) => ({
                            ID: p.ID,
                            QueryID: p.QueryID,
                            Name: p.Name,
                            Description: p.Description,
                            Type: p.Type,
                            IsRequired: p.IsRequired,
                            DefaultValue: p.DefaultValue,
                            SampleValue: p.SampleValue,
                            ValidationFilters: p.ValidationFilters
                        })) || [],
                        Entities: existingQuery.Entities?.map((e) => ({
                            ID: e.ID,
                            QueryID: e.QueryID,
                            EntityID: e.EntityID,
                            Entity: e.Entity
                        })) || [],
                        Permissions: existingQuery.Permissions?.map((p) => ({
                            ID: p.ID,
                            QueryID: p.QueryID,
                            RoleID: p.RoleID,
                            Role: p.Role
                        })) || []
                    };
                }
                const errorMessage = record.LatestResult?.Message || '';
                return {
                    Success: false,
                    ErrorMessage: `Failed to create query: ${errorMessage || 'Unknown error'}`
                };
            }
        }
        catch (err) {
            LogError(err);
            return {
                Success: false,
                ErrorMessage: `MJQueryResolverExtended::CreateQuerySystemUser --- Error creating query: ${err instanceof Error ? err.message : String(err)}`
            };
        }
    }
    async createPermissions(p, permissions, queryID, contextUser) {
        const createdPermissions = [];
        if (permissions && permissions.length > 0) {
            for (const perm of permissions) {
                const permissionEntity = await p.GetEntityObject('Query Permissions', contextUser);
                if (permissionEntity) {
                    permissionEntity.QueryID = queryID;
                    permissionEntity.RoleID = perm.RoleID;
                    const saveResult = await permissionEntity.Save();
                    if (saveResult) {
                        createdPermissions.push({
                            ID: permissionEntity.ID,
                            QueryID: permissionEntity.QueryID,
                            RoleID: permissionEntity.RoleID,
                            Role: permissionEntity.Role
                        });
                    }
                }
            }
        }
        return createdPermissions;
    }
    async UpdateQuerySystemUser(input, context, pubSub) {
        try {
            const provider = GetReadWriteProvider(context.providers);
            const queryEntity = await provider.GetEntityObject('Queries', context.userPayload.userRecord);
            if (!queryEntity || !await queryEntity.Load(input.ID)) {
                return {
                    Success: false,
                    ErrorMessage: `Query with ID ${input.ID} not found`
                };
            }
            let finalCategoryID = input.CategoryID;
            if (input.CategoryPath) {
                finalCategoryID = await this.findOrCreateCategoryPath(input.CategoryPath, provider, context.userPayload.userRecord);
            }
            const existingQueryResult = await provider.RunView({
                EntityName: 'Queries',
                ExtraFilter: `Name='${input.Name}' AND CategoryID='${finalCategoryID}'`
            }, context.userPayload.userRecord);
            if (existingQueryResult.Success && existingQueryResult.Results?.length > 0) {
                return {
                    Success: false,
                    ErrorMessage: `Query with name '${input.Name}' already exists in the specified ${input.CategoryID ? 'category' : 'categoryPath'}`
                };
            }
            const updateFields = {};
            if (input.Name !== undefined)
                updateFields.Name = input.Name;
            if (finalCategoryID !== undefined)
                updateFields.CategoryID = finalCategoryID;
            if (input.UserQuestion !== undefined)
                updateFields.UserQuestion = input.UserQuestion;
            if (input.Description !== undefined)
                updateFields.Description = input.Description;
            if (input.SQL !== undefined)
                updateFields.SQL = input.SQL;
            if (input.TechnicalDescription !== undefined)
                updateFields.TechnicalDescription = input.TechnicalDescription;
            if (input.OriginalSQL !== undefined)
                updateFields.OriginalSQL = input.OriginalSQL;
            if (input.Feedback !== undefined)
                updateFields.Feedback = input.Feedback;
            if (input.Status !== undefined)
                updateFields.Status = input.Status;
            if (input.QualityRank !== undefined)
                updateFields.QualityRank = input.QualityRank;
            if (input.ExecutionCostRank !== undefined)
                updateFields.ExecutionCostRank = input.ExecutionCostRank;
            if (input.UsesTemplate !== undefined)
                updateFields.UsesTemplate = input.UsesTemplate;
            if (input.AuditQueryRuns !== undefined)
                updateFields.AuditQueryRuns = input.AuditQueryRuns;
            if (input.CacheEnabled !== undefined)
                updateFields.CacheEnabled = input.CacheEnabled;
            if (input.CacheTTLMinutes !== undefined)
                updateFields.CacheTTLMinutes = input.CacheTTLMinutes;
            if (input.CacheMaxSize !== undefined)
                updateFields.CacheMaxSize = input.CacheMaxSize;
            queryEntity.SetMany(updateFields);
            const saveResult = await queryEntity.Save();
            if (!saveResult) {
                return {
                    Success: false,
                    ErrorMessage: `Failed to update query: ${queryEntity.LatestResult?.Message || 'Unknown error'}`
                };
            }
            const queryID = queryEntity.ID;
            if (input.Permissions !== undefined) {
                const rv = new RunView();
                const existingPermissions = await rv.RunView({
                    EntityName: 'Query Permissions',
                    ExtraFilter: `QueryID='${queryID}'`,
                    ResultType: 'entity_object'
                }, context.userPayload.userRecord);
                if (existingPermissions.Success && existingPermissions.Results) {
                    for (const perm of existingPermissions.Results) {
                        await perm.Delete();
                    }
                }
                await this.createPermissions(provider, input.Permissions, queryID, context.userPayload.userRecord);
                await queryEntity.RefreshRelatedMetadata(true);
            }
            return {
                Success: true,
                ID: queryEntity.ID,
                Name: queryEntity.Name,
                Description: queryEntity.Description,
                CategoryID: queryEntity.CategoryID,
                Category: queryEntity.Category,
                SQL: queryEntity.SQL,
                Status: queryEntity.Status,
                QualityRank: queryEntity.QualityRank,
                EmbeddingVector: queryEntity.EmbeddingVector,
                EmbeddingModelID: queryEntity.EmbeddingModelID,
                EmbeddingModelName: queryEntity.EmbeddingModel,
                Fields: queryEntity.QueryFields.map(f => ({
                    ID: f.ID,
                    QueryID: f.QueryID,
                    Name: f.Name,
                    Description: f.Description,
                    Sequence: f.Sequence,
                    SQLBaseType: f.SQLBaseType,
                    SQLFullType: f.SQLFullType,
                    SourceEntityID: f.SourceEntityID,
                    SourceEntity: f.SourceEntity,
                    SourceFieldName: f.SourceFieldName,
                    IsComputed: f.IsComputed,
                    ComputationDescription: f.ComputationDescription,
                    IsSummary: f.IsSummary,
                    SummaryDescription: f.SummaryDescription
                })),
                Parameters: queryEntity.QueryParameters.map(p => ({
                    ID: p.ID,
                    QueryID: p.QueryID,
                    Name: p.Name,
                    Description: p.Description,
                    Type: p.Type,
                    IsRequired: p.IsRequired,
                    DefaultValue: p.DefaultValue,
                    SampleValue: p.SampleValue,
                    ValidationFilters: p.ValidationFilters
                })),
                Entities: queryEntity.QueryEntities.map(e => ({
                    ID: e.ID,
                    QueryID: e.QueryID,
                    EntityID: e.EntityID,
                    Entity: e.Entity
                })),
                Permissions: queryEntity.QueryPermissions.map(p => ({
                    ID: p.ID,
                    QueryID: p.QueryID,
                    RoleID: p.RoleID,
                    Role: p.Role
                }))
            };
        }
        catch (err) {
            LogError(err);
            return {
                Success: false,
                ErrorMessage: `MJQueryResolverExtended::UpdateQuerySystemUser --- Error updating query: ${err instanceof Error ? err.message : String(err)}`
            };
        }
    }
    async DeleteQuerySystemResolver(ID, options, context, pubSub) {
        try {
            if (!ID || ID.trim() === '') {
                return {
                    Success: false,
                    ErrorMessage: 'MJQueryResolverExtended::DeleteQuerySystemResolver --- Invalid query ID: ID cannot be null or empty'
                };
            }
            const provider = GetReadWriteProvider(context.providers);
            const key = new CompositeKey([{ FieldName: 'ID', Value: ID }]);
            const deleteOptions = options || {
                SkipEntityAIActions: false,
                SkipEntityActions: false
            };
            const deletedQuery = await this.DeleteRecord('Queries', key, deleteOptions, provider, context.userPayload, pubSub);
            if (deletedQuery) {
                return {
                    Success: true,
                    ID: deletedQuery.ID,
                    Name: deletedQuery.Name,
                    Description: deletedQuery.Description,
                    CategoryID: deletedQuery.CategoryID,
                    SQL: deletedQuery.SQL,
                    Status: deletedQuery.Status
                };
            }
            else {
                return {
                    Success: false,
                    ErrorMessage: 'Failed to delete query using DeleteRecord method'
                };
            }
        }
        catch (err) {
            LogError(err);
            return {
                Success: false,
                ErrorMessage: `MJQueryResolverExtended::DeleteQuerySystemResolver --- Error deleting query: ${err instanceof Error ? err.message : String(err)}`
            };
        }
    }
    async findOrCreateCategoryPath(categoryPath, p, contextUser) {
        if (!categoryPath || categoryPath.trim() === '') {
            throw new Error('CategoryPath cannot be empty');
        }
        const pathParts = categoryPath.split('/').map(part => part.trim()).filter(part => part.length > 0);
        if (pathParts.length === 0) {
            throw new Error('CategoryPath must contain at least one valid category name');
        }
        let currentParentID = null;
        let currentCategoryID = null;
        for (let i = 0; i < pathParts.length; i++) {
            const categoryName = pathParts[i];
            const existingCategory = await this.findCategoryByNameAndParent(p, categoryName, currentParentID, contextUser);
            if (existingCategory) {
                currentCategoryID = existingCategory.ID;
                currentParentID = existingCategory.ID;
            }
            else {
                try {
                    const newCategory = await p.GetEntityObject("Query Categories", contextUser);
                    if (!newCategory) {
                        throw new Error(`Failed to create entity object for Query Categories`);
                    }
                    newCategory.Name = categoryName;
                    newCategory.ParentID = currentParentID;
                    newCategory.UserID = contextUser.ID;
                    newCategory.Description = `Auto-created category from path: ${categoryPath}`;
                    const saveResult = await newCategory.Save();
                    if (!saveResult) {
                        const recheckExisting = await this.findCategoryByNameAndParent(p, categoryName, currentParentID, contextUser);
                        if (recheckExisting) {
                            LogStatus(`[CreateQuery] Unique constraint detected for category '${categoryName}'. Using existing category (ID: ${recheckExisting.ID}) created by concurrent request.`);
                            currentCategoryID = recheckExisting.ID;
                            currentParentID = recheckExisting.ID;
                        }
                        else {
                            const errorMessage = newCategory.LatestResult?.Message || '';
                            throw new Error(`Failed to create category '${categoryName}': ${errorMessage || 'Unknown error'}`);
                        }
                    }
                    else {
                        currentCategoryID = newCategory.ID;
                        currentParentID = newCategory.ID;
                    }
                }
                catch (error) {
                    const recheckExisting = await this.findCategoryByNameAndParent(p, categoryName, currentParentID, contextUser);
                    if (recheckExisting) {
                        LogStatus(`[CreateQuery] Exception during category creation for '${categoryName}'. Using existing category (ID: ${recheckExisting.ID}) created by concurrent request.`);
                        currentCategoryID = recheckExisting.ID;
                        currentParentID = recheckExisting.ID;
                    }
                    else {
                        throw new Error(`Failed to create category '${categoryName}': ${error instanceof Error ? error.message : String(error)}`);
                    }
                }
            }
        }
        if (!currentCategoryID) {
            throw new Error('Failed to determine final category ID');
        }
        return currentCategoryID;
    }
    async findExistingQuery(provider, queryName, categoryID, contextUser) {
        try {
            const categoryFilter = categoryID ? `CategoryID='${categoryID}'` : 'CategoryID IS NULL';
            const nameFilter = `LOWER(Name) = LOWER('${queryName.replace(/'/g, "''")}')`;
            const result = await provider.RunView({
                EntityName: 'Queries',
                ExtraFilter: `${nameFilter} AND ${categoryFilter}`
            }, contextUser);
            if (result.Success && result.Results && result.Results.length > 0) {
                return result.Results[0];
            }
            return null;
        }
        catch (error) {
            return null;
        }
    }
    async findCategoryByNameAndParent(provider, categoryName, parentID, contextUser) {
        try {
            const parentFilter = parentID ? `ParentID='${parentID}'` : 'ParentID IS NULL';
            const nameFilter = `LOWER(Name) = LOWER('${categoryName.replace(/'/g, "''")}')`;
            const result = await provider.RunView({
                EntityName: 'Query Categories',
                ExtraFilter: `${nameFilter} AND ${parentFilter}`,
                ResultType: 'entity_object'
            }, contextUser);
            if (result.Success && result.Results && result.Results.length > 0) {
                return result.Results[0];
            }
            return null;
        }
        catch (error) {
            return null;
        }
    }
};
__decorate([
    RequireSystemUser(),
    Mutation(() => CreateQueryResultType),
    __param(0, Arg('input', () => CreateQuerySystemUserInput)),
    __param(1, Ctx()),
    __param(2, PubSub()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [CreateQuerySystemUserInput, Object, PubSubEngine]),
    __metadata("design:returntype", Promise)
], MJQueryResolverExtended.prototype, "CreateQuerySystemUser", null);
__decorate([
    RequireSystemUser(),
    Mutation(() => UpdateQueryResultType),
    __param(0, Arg('input', () => UpdateQuerySystemUserInput)),
    __param(1, Ctx()),
    __param(2, PubSub()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [UpdateQuerySystemUserInput, Object, PubSubEngine]),
    __metadata("design:returntype", Promise)
], MJQueryResolverExtended.prototype, "UpdateQuerySystemUser", null);
__decorate([
    RequireSystemUser(),
    Mutation(() => DeleteQueryResultType),
    __param(0, Arg('ID', () => String)),
    __param(1, Arg('options', () => DeleteOptionsInput, { nullable: true })),
    __param(2, Ctx()),
    __param(3, PubSub()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [String, DeleteOptionsInput, Object, PubSubEngine]),
    __metadata("design:returntype", Promise)
], MJQueryResolverExtended.prototype, "DeleteQuerySystemResolver", null);
MJQueryResolverExtended = __decorate([
    Resolver()
], MJQueryResolverExtended);
export { MJQueryResolverExtended };
//# sourceMappingURL=CreateQueryResolver.js.map