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, Int, Mutation, ObjectType, registerEnumType } from 'type-graphql';
import { CompositeKey, KeyValuePair, LogError, Metadata, TransactionVariable } from '@memberjunction/core';
import { SafeJSONParse } from '@memberjunction/global';
export var TransactionVariableType;
(function (TransactionVariableType) {
    TransactionVariableType["Define"] = "Define";
    TransactionVariableType["Use"] = "Use";
})(TransactionVariableType || (TransactionVariableType = {}));
registerEnumType(TransactionVariableType, {
    name: "TransactionVariableType",
    description: "Specifies the type of variable: Define or Use",
});
export var TransactionOperationType;
(function (TransactionOperationType) {
    TransactionOperationType["Create"] = "Create";
    TransactionOperationType["Update"] = "Update";
    TransactionOperationType["Delete"] = "Delete";
})(TransactionOperationType || (TransactionOperationType = {}));
registerEnumType(TransactionOperationType, {
    name: "TransactionOperationType",
    description: "Specifies the type of operation: Create, Update, or Delete",
});
let TransactionVariableInputType = class TransactionVariableInputType {
    Name;
    ItemIndex;
    FieldName;
    Type;
};
__decorate([
    Field(() => String),
    __metadata("design:type", String)
], TransactionVariableInputType.prototype, "Name", void 0);
__decorate([
    Field(() => Int),
    __metadata("design:type", Number)
], TransactionVariableInputType.prototype, "ItemIndex", void 0);
__decorate([
    Field(() => String),
    __metadata("design:type", String)
], TransactionVariableInputType.prototype, "FieldName", void 0);
__decorate([
    Field(() => TransactionVariableType),
    __metadata("design:type", String)
], TransactionVariableInputType.prototype, "Type", void 0);
TransactionVariableInputType = __decorate([
    InputType()
], TransactionVariableInputType);
export { TransactionVariableInputType };
let TransactionItemInputType = class TransactionItemInputType {
    EntityName;
    EntityObjectJSON;
    OperationType;
};
__decorate([
    Field(() => String),
    __metadata("design:type", String)
], TransactionItemInputType.prototype, "EntityName", void 0);
__decorate([
    Field(() => String),
    __metadata("design:type", String)
], TransactionItemInputType.prototype, "EntityObjectJSON", void 0);
__decorate([
    Field(() => TransactionOperationType),
    __metadata("design:type", String)
], TransactionItemInputType.prototype, "OperationType", void 0);
TransactionItemInputType = __decorate([
    InputType()
], TransactionItemInputType);
export { TransactionItemInputType };
let TransactionInputType = class TransactionInputType {
    Items;
    Variables;
};
__decorate([
    Field(() => [TransactionItemInputType]),
    __metadata("design:type", Array)
], TransactionInputType.prototype, "Items", void 0);
__decorate([
    Field(() => [TransactionVariableInputType], { nullable: true }),
    __metadata("design:type", Array)
], TransactionInputType.prototype, "Variables", void 0);
TransactionInputType = __decorate([
    InputType()
], TransactionInputType);
export { TransactionInputType };
let TransactionOutputType = class TransactionOutputType {
    Success;
    ErrorMessages;
    ResultsJSON;
};
__decorate([
    Field(() => Boolean),
    __metadata("design:type", Boolean)
], TransactionOutputType.prototype, "Success", void 0);
__decorate([
    Field(() => [String]),
    __metadata("design:type", Array)
], TransactionOutputType.prototype, "ErrorMessages", void 0);
__decorate([
    Field(() => [String]),
    __metadata("design:type", Array)
], TransactionOutputType.prototype, "ResultsJSON", void 0);
TransactionOutputType = __decorate([
    ObjectType()
], TransactionOutputType);
export { TransactionOutputType };
export class TransactionResolver {
    async ExecuteTransactionGroup(group, context) {
        try {
            const md = new Metadata();
            const tg = await md.CreateTransactionGroup();
            const entityObjects = [];
            const objectValues = [];
            for (const item of group.Items) {
                const entity = await md.GetEntityObject(item.EntityName, context.userPayload.userRecord);
                entityObjects.push(entity);
                const itemValues = SafeJSONParse(item.EntityObjectJSON);
                const pkey = new CompositeKey(entity.PrimaryKeys.map(pk => {
                    const kv = new KeyValuePair();
                    kv.FieldName = pk.Name;
                    kv.Value = itemValues[pk.Name];
                    return kv;
                }));
                switch (item.OperationType) {
                    case "Update":
                    case "Create":
                        if (item.OperationType === "Update") {
                            await entity.InnerLoad(pkey);
                        }
                        objectValues.push(itemValues);
                        entity.SetMany(itemValues, true);
                        entity.TransactionGroup = tg;
                        await entity.Save();
                        break;
                    case "Delete":
                        await entity.InnerLoad(pkey);
                        objectValues.push(entity.GetDataObject());
                        entity.TransactionGroup = tg;
                        await entity.Delete();
                        break;
                }
            }
            if (group.Variables && group.Variables.length > 0) {
                for (const networkVar of group.Variables) {
                    if (networkVar.ItemIndex >= 0 && networkVar.ItemIndex < entityObjects.length) {
                        const entityObject = entityObjects[networkVar.ItemIndex];
                        const newVar = new TransactionVariable(networkVar.Name, entityObject, networkVar.FieldName, networkVar.Type);
                        tg.AddVariable(newVar);
                    }
                    else {
                        throw new Error(`TransactionResolver::ExecuteTransactionGroup --- Error\n\n' + 'Invalid ItemIndex ${networkVar.ItemIndex} in TransactionVariable "${JSON.stringify(networkVar)}"`);
                    }
                }
            }
            if (await tg.Submit()) {
                return await this.PrepareReturnValue(true, entityObjects, objectValues, group);
            }
            else {
                return await this.PrepareReturnValue(false, entityObjects, objectValues, group);
            }
        }
        catch (err) {
            LogError(err);
            throw new Error('TransactionResolver::ExecuteTransactionGroup --- Error\n\n' + err);
        }
    }
    async PrepareReturnValue(success, entityObjects, objectValues, group) {
        const jsonResults = [];
        for (let i = 0; i < group.Items.length; i++) {
            const item = group.Items[i];
            if (item.OperationType === 'Delete') {
                jsonResults.push(JSON.stringify(objectValues[i]));
            }
            else {
                jsonResults.push(await entityObjects[i].GetDataObjectJSON());
            }
        }
        return {
            Success: success,
            ErrorMessages: entityObjects.map(e => JSON.stringify(e.LatestResult)),
            ResultsJSON: jsonResults
        };
    }
}
__decorate([
    Mutation(() => TransactionOutputType),
    __param(0, Arg('group', () => TransactionInputType)),
    __param(1, Ctx()),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [TransactionInputType, Object]),
    __metadata("design:returntype", Promise)
], TransactionResolver.prototype, "ExecuteTransactionGroup", null);
//# sourceMappingURL=TransactionGroupResolver.js.map