import { registerCommand } from "@open-mercato/shared/lib/commands";
import { UniqueConstraintViolationException } from "@mikro-orm/core";
import { CrudHttpError } from "@open-mercato/shared/lib/crud/errors";
import { resolveTranslations } from "@open-mercato/shared/lib/i18n/server";
import { findOneWithDecryption } from "@open-mercato/shared/lib/encryption/find";
import { buildChanges, emitCrudSideEffects, emitCrudUndoSideEffects } from "@open-mercato/shared/lib/commands/helpers";
import { makeCreateRedo } from "@open-mercato/shared/lib/commands/redo";
import { StaffTeamMember, StaffTimeProject, StaffTimeProjectMember } from "../data/entities.js";
const timeProjectCrudIndexer = {
  entityType: "staff:staff_time_project"
};
const timeProjectMemberCrudIndexer = {
  entityType: "staff:staff_time_project_member"
};
import {
  staffTimeProjectCreateSchema,
  staffTimeProjectUpdateSchema,
  staffTimeProjectMemberAssignSchema
} from "../data/validators.js";
import { staffTimeProjectCrudEvents, staffTimeProjectMemberCrudEvents } from "../lib/crud.js";
import {
  applyScopeToWhere,
  commandActorScope,
  commandInputScope,
  ensureOrganizationScope,
  ensureTenantScope,
  extractUndoPayload,
  scopeForDecryption,
  scopedStaffSnapshotWhere,
  staffSnapshotDecryptionScope,
  staffSnapshotScopeFromContext,
  staffSnapshotScopeFromSnapshot
} from "./shared.js";
function isUniqueViolation(error) {
  if (error instanceof UniqueConstraintViolationException) return true;
  if (!error || typeof error !== "object") return false;
  const code = error.code;
  if (code === "23505") return true;
  const message = error.message;
  return typeof message === "string" && message.toLowerCase().includes("duplicate key");
}
async function loadTimeProjectSnapshot(em, id, scope) {
  const project = await findOneWithDecryption(
    em,
    StaffTimeProject,
    scopedStaffSnapshotWhere(id, scope),
    void 0,
    staffSnapshotDecryptionScope(scope)
  );
  if (!project) return null;
  return {
    id: project.id,
    tenantId: project.tenantId,
    organizationId: project.organizationId,
    name: project.name,
    customerId: project.customerId ?? null,
    code: project.code,
    description: project.description ?? null,
    projectType: project.projectType ?? null,
    color: project.color ?? null,
    status: project.status,
    ownerUserId: project.ownerUserId ?? null,
    costCenter: project.costCenter ?? null,
    startDate: project.startDate instanceof Date ? project.startDate.toISOString().split("T")[0] : project.startDate ?? null,
    deletedAt: project.deletedAt ? project.deletedAt.toISOString() : null
  };
}
async function loadTimeProjectMemberSnapshot(em, id, scope) {
  const member = await findOneWithDecryption(
    em,
    StaffTimeProjectMember,
    scopedStaffSnapshotWhere(id, scope),
    void 0,
    staffSnapshotDecryptionScope(scope)
  );
  if (!member) return null;
  return {
    id: member.id,
    tenantId: member.tenantId,
    organizationId: member.organizationId,
    timeProjectId: member.timeProjectId,
    staffMemberId: member.staffMemberId,
    role: member.role ?? null,
    status: member.status,
    showInGrid: member.showInGrid ?? false,
    assignedStartDate: member.assignedStartDate instanceof Date ? member.assignedStartDate.toISOString().split("T")[0] : String(member.assignedStartDate),
    assignedEndDate: member.assignedEndDate instanceof Date ? member.assignedEndDate.toISOString().split("T")[0] : member.assignedEndDate ?? null,
    deletedAt: member.deletedAt ? member.deletedAt.toISOString() : null
  };
}
function timeProjectSeedFromSnapshot(snapshot) {
  return {
    id: snapshot.id,
    tenantId: snapshot.tenantId,
    organizationId: snapshot.organizationId,
    name: snapshot.name,
    customerId: snapshot.customerId ?? null,
    code: snapshot.code,
    description: snapshot.description ?? null,
    projectType: snapshot.projectType ?? null,
    color: snapshot.color ?? null,
    status: snapshot.status ?? "active",
    ownerUserId: snapshot.ownerUserId ?? null,
    costCenter: snapshot.costCenter ?? null,
    startDate: snapshot.startDate ? new Date(snapshot.startDate) : null,
    createdAt: /* @__PURE__ */ new Date(),
    updatedAt: /* @__PURE__ */ new Date(),
    deletedAt: null
  };
}
function timeProjectMemberSeedFromSnapshot(snapshot) {
  return {
    id: snapshot.id,
    tenantId: snapshot.tenantId,
    organizationId: snapshot.organizationId,
    timeProjectId: snapshot.timeProjectId,
    staffMemberId: snapshot.staffMemberId,
    role: snapshot.role ?? null,
    status: snapshot.status ?? "active",
    showInGrid: snapshot.showInGrid ?? false,
    assignedStartDate: new Date(snapshot.assignedStartDate),
    assignedEndDate: snapshot.assignedEndDate ? new Date(snapshot.assignedEndDate) : null,
    createdAt: /* @__PURE__ */ new Date(),
    updatedAt: /* @__PURE__ */ new Date(),
    deletedAt: null
  };
}
const createTimeProjectCommand = {
  id: "staff.timesheets.time_projects.create",
  async execute(rawInput, ctx) {
    const parsed = staffTimeProjectCreateSchema.parse(rawInput);
    ensureTenantScope(ctx, parsed.tenantId);
    ensureOrganizationScope(ctx, parsed.organizationId);
    commandInputScope(ctx, parsed.tenantId, parsed.organizationId);
    const em = ctx.container.resolve("em").fork();
    const now = /* @__PURE__ */ new Date();
    const project = em.create(StaffTimeProject, {
      tenantId: parsed.tenantId,
      organizationId: parsed.organizationId,
      name: parsed.name,
      customerId: parsed.customerId ?? null,
      code: parsed.code,
      description: parsed.description ?? null,
      projectType: parsed.projectType ?? null,
      color: parsed.color ?? null,
      status: parsed.status ?? "active",
      ownerUserId: parsed.ownerUserId ?? null,
      costCenter: parsed.costCenter ?? null,
      startDate: parsed.startDate ?? null,
      createdAt: now,
      updatedAt: now,
      deletedAt: null
    });
    em.persist(project);
    try {
      await em.flush();
    } catch (err) {
      if (isUniqueViolation(err)) {
        const { translate } = await resolveTranslations();
        throw new CrudHttpError(409, {
          error: translate("staff.timesheets.errors.projectCodeDuplicate", "A project with this code already exists."),
          fieldErrors: { code: translate("staff.timesheets.errors.projectCodeDuplicate", "A project with this code already exists.") }
        });
      }
      throw err;
    }
    await emitCrudSideEffects({
      dataEngine: ctx.container.resolve("dataEngine"),
      action: "created",
      entity: project,
      identifiers: {
        id: project.id,
        organizationId: project.organizationId,
        tenantId: project.tenantId
      },
      events: staffTimeProjectCrudEvents,
      indexer: timeProjectCrudIndexer
    });
    return { timeProjectId: project.id };
  },
  captureAfter: async (_input, result, ctx) => {
    const em = ctx.container.resolve("em").fork();
    const snapshot = await loadTimeProjectSnapshot(em, result.timeProjectId, staffSnapshotScopeFromContext(ctx));
    if (!snapshot) return null;
    return { snapshot };
  },
  buildLog: async ({ result, ctx }) => {
    const em = ctx.container.resolve("em").fork();
    const snapshot = await loadTimeProjectSnapshot(em, result.timeProjectId, staffSnapshotScopeFromContext(ctx));
    if (!snapshot) return null;
    const { translate } = await resolveTranslations();
    return {
      actionLabel: translate("staff.audit.timesheets.time_projects.create", "Create time project"),
      resourceKind: "staff.timesheets.time_project",
      resourceId: snapshot.id,
      tenantId: snapshot.tenantId,
      organizationId: snapshot.organizationId,
      snapshotAfter: snapshot,
      payload: {
        undo: {
          after: snapshot
        }
      }
    };
  },
  undo: async ({ logEntry, ctx }) => {
    const payload = extractUndoPayload(logEntry);
    const after = payload?.after;
    if (!after) return;
    const em = ctx.container.resolve("em").fork();
    const project = await em.findOne(StaffTimeProject, scopedStaffSnapshotWhere(after.id, staffSnapshotScopeFromSnapshot(after)));
    if (project) {
      project.deletedAt = /* @__PURE__ */ new Date();
      await em.flush();
      await emitCrudUndoSideEffects({
        dataEngine: ctx.container.resolve("dataEngine"),
        action: "deleted",
        entity: project,
        identifiers: {
          id: project.id,
          organizationId: project.organizationId,
          tenantId: project.tenantId
        },
        events: staffTimeProjectCrudEvents
      });
    }
  },
  redo: makeCreateRedo({
    entityClass: StaffTimeProject,
    getSnapshotId: (snapshot) => snapshot.id,
    seedFromSnapshot: timeProjectSeedFromSnapshot,
    buildResult: (entity) => ({ timeProjectId: entity.id }),
    events: staffTimeProjectCrudEvents,
    indexer: timeProjectCrudIndexer
  })
};
const updateTimeProjectCommand = {
  id: "staff.timesheets.time_projects.update",
  async prepare(rawInput, ctx) {
    const parsed = staffTimeProjectUpdateSchema.parse(rawInput);
    const em = ctx.container.resolve("em");
    const snapshot = await loadTimeProjectSnapshot(em, parsed.id, staffSnapshotScopeFromContext(ctx));
    if (!snapshot) return {};
    return { before: snapshot };
  },
  async execute(rawInput, ctx) {
    const parsed = staffTimeProjectUpdateSchema.parse(rawInput);
    const em = ctx.container.resolve("em").fork();
    const scope = commandActorScope(ctx);
    const project = await findOneWithDecryption(
      em,
      StaffTimeProject,
      applyScopeToWhere({ id: parsed.id, deletedAt: null }, scope),
      void 0,
      scopeForDecryption(scope)
    );
    if (!project) throw new CrudHttpError(404, { error: "Time project not found." });
    ensureTenantScope(ctx, project.tenantId);
    ensureOrganizationScope(ctx, project.organizationId);
    if (parsed.name !== void 0) project.name = parsed.name;
    if (parsed.customerId !== void 0) project.customerId = parsed.customerId ?? null;
    if (parsed.code !== void 0) project.code = parsed.code;
    if (parsed.description !== void 0) project.description = parsed.description ?? null;
    if (parsed.projectType !== void 0) project.projectType = parsed.projectType ?? null;
    if (parsed.color !== void 0) project.color = parsed.color ?? null;
    if (parsed.status !== void 0) project.status = parsed.status;
    if (parsed.ownerUserId !== void 0) project.ownerUserId = parsed.ownerUserId ?? null;
    if (parsed.costCenter !== void 0) project.costCenter = parsed.costCenter ?? null;
    if (parsed.startDate !== void 0) project.startDate = parsed.startDate ?? null;
    project.updatedAt = /* @__PURE__ */ new Date();
    try {
      await em.flush();
    } catch (err) {
      if (isUniqueViolation(err)) {
        const { translate } = await resolveTranslations();
        throw new CrudHttpError(409, {
          error: translate("staff.timesheets.errors.projectCodeDuplicate", "A project with this code already exists."),
          fieldErrors: { code: translate("staff.timesheets.errors.projectCodeDuplicate", "A project with this code already exists.") }
        });
      }
      throw err;
    }
    await emitCrudSideEffects({
      dataEngine: ctx.container.resolve("dataEngine"),
      action: "updated",
      entity: project,
      identifiers: {
        id: project.id,
        organizationId: project.organizationId,
        tenantId: project.tenantId
      },
      events: staffTimeProjectCrudEvents,
      indexer: timeProjectCrudIndexer
    });
    return { timeProjectId: project.id };
  },
  buildLog: async ({ snapshots, ctx }) => {
    const before = snapshots.before;
    if (!before) return null;
    const em = ctx.container.resolve("em").fork();
    const after = await loadTimeProjectSnapshot(em, before.id, staffSnapshotScopeFromSnapshot(before));
    if (!after) return null;
    const changes = buildChanges(before, after, [
      "name",
      "customerId",
      "code",
      "description",
      "projectType",
      "color",
      "status",
      "ownerUserId",
      "costCenter",
      "startDate",
      "deletedAt"
    ]);
    const { translate } = await resolveTranslations();
    return {
      actionLabel: translate("staff.audit.timesheets.time_projects.update", "Update time project"),
      resourceKind: "staff.timesheets.time_project",
      resourceId: before.id,
      tenantId: before.tenantId,
      organizationId: before.organizationId,
      snapshotBefore: before,
      snapshotAfter: after,
      changes,
      payload: {
        undo: {
          before,
          after
        }
      }
    };
  },
  undo: async ({ logEntry, ctx }) => {
    const payload = extractUndoPayload(logEntry);
    const before = payload?.before;
    if (!before) return;
    const em = ctx.container.resolve("em").fork();
    const project = await em.findOne(StaffTimeProject, scopedStaffSnapshotWhere(before.id, staffSnapshotScopeFromSnapshot(before)));
    if (!project) return;
    project.name = before.name;
    project.customerId = before.customerId ?? null;
    project.code = before.code;
    project.description = before.description ?? null;
    project.projectType = before.projectType ?? null;
    project.color = before.color ?? null;
    project.status = before.status ?? "active";
    project.ownerUserId = before.ownerUserId ?? null;
    project.costCenter = before.costCenter ?? null;
    project.startDate = before.startDate ? new Date(before.startDate) : null;
    project.deletedAt = before.deletedAt ? new Date(before.deletedAt) : null;
    project.updatedAt = /* @__PURE__ */ new Date();
    await em.flush();
    await emitCrudUndoSideEffects({
      dataEngine: ctx.container.resolve("dataEngine"),
      action: "updated",
      entity: project,
      identifiers: {
        id: project.id,
        organizationId: project.organizationId,
        tenantId: project.tenantId
      },
      events: staffTimeProjectCrudEvents,
      indexer: timeProjectCrudIndexer
    });
  }
};
const deleteTimeProjectCommand = {
  id: "staff.timesheets.time_projects.delete",
  async prepare(input, ctx) {
    const id = input?.id;
    if (!id) throw new CrudHttpError(400, { error: "Time project id is required." });
    const em = ctx.container.resolve("em");
    const snapshot = await loadTimeProjectSnapshot(em, id, staffSnapshotScopeFromContext(ctx));
    if (!snapshot) return {};
    return { before: snapshot };
  },
  async execute(input, ctx) {
    const id = input?.id;
    if (!id) throw new CrudHttpError(400, { error: "Time project id is required." });
    const em = ctx.container.resolve("em").fork();
    const scope = commandActorScope(ctx);
    const project = await findOneWithDecryption(
      em,
      StaffTimeProject,
      applyScopeToWhere({ id, deletedAt: null }, scope),
      void 0,
      scopeForDecryption(scope)
    );
    if (!project) throw new CrudHttpError(404, { error: "Time project not found." });
    ensureTenantScope(ctx, project.tenantId);
    ensureOrganizationScope(ctx, project.organizationId);
    project.deletedAt = /* @__PURE__ */ new Date();
    project.updatedAt = /* @__PURE__ */ new Date();
    await em.flush();
    await emitCrudSideEffects({
      dataEngine: ctx.container.resolve("dataEngine"),
      action: "deleted",
      entity: project,
      identifiers: {
        id: project.id,
        organizationId: project.organizationId,
        tenantId: project.tenantId
      },
      events: staffTimeProjectCrudEvents,
      indexer: timeProjectCrudIndexer
    });
    return { timeProjectId: project.id };
  },
  buildLog: async ({ snapshots }) => {
    const before = snapshots.before;
    if (!before) return null;
    const { translate } = await resolveTranslations();
    return {
      actionLabel: translate("staff.audit.timesheets.time_projects.delete", "Delete time project"),
      resourceKind: "staff.timesheets.time_project",
      resourceId: before.id,
      tenantId: before.tenantId,
      organizationId: before.organizationId,
      snapshotBefore: before,
      payload: {
        undo: {
          before
        }
      }
    };
  },
  undo: async ({ logEntry, ctx }) => {
    const payload = extractUndoPayload(logEntry);
    const before = payload?.before;
    if (!before) return;
    const em = ctx.container.resolve("em").fork();
    let project = await em.findOne(StaffTimeProject, scopedStaffSnapshotWhere(before.id, staffSnapshotScopeFromSnapshot(before)));
    if (!project) {
      project = em.create(StaffTimeProject, {
        id: before.id,
        tenantId: before.tenantId,
        organizationId: before.organizationId,
        name: before.name,
        customerId: before.customerId ?? null,
        code: before.code,
        description: before.description ?? null,
        projectType: before.projectType ?? null,
        status: before.status ?? "active",
        ownerUserId: before.ownerUserId ?? null,
        costCenter: before.costCenter ?? null,
        startDate: before.startDate ? new Date(before.startDate) : null,
        deletedAt: null,
        createdAt: /* @__PURE__ */ new Date(),
        updatedAt: /* @__PURE__ */ new Date()
      });
      em.persist(project);
    } else {
      project.name = before.name;
      project.customerId = before.customerId ?? null;
      project.code = before.code;
      project.description = before.description ?? null;
      project.projectType = before.projectType ?? null;
      project.status = before.status ?? "active";
      project.ownerUserId = before.ownerUserId ?? null;
      project.costCenter = before.costCenter ?? null;
      project.startDate = before.startDate ? new Date(before.startDate) : null;
      project.deletedAt = null;
      project.updatedAt = /* @__PURE__ */ new Date();
    }
    await em.flush();
    await emitCrudUndoSideEffects({
      dataEngine: ctx.container.resolve("dataEngine"),
      action: "created",
      entity: project,
      identifiers: {
        id: project.id,
        organizationId: project.organizationId,
        tenantId: project.tenantId
      },
      events: staffTimeProjectCrudEvents,
      indexer: timeProjectCrudIndexer
    });
  }
};
const assignTimeProjectMemberCommand = {
  id: "staff.timesheets.time_project_members.assign",
  async execute(rawInput, ctx) {
    const parsed = staffTimeProjectMemberAssignSchema.parse(rawInput);
    ensureTenantScope(ctx, parsed.tenantId);
    ensureOrganizationScope(ctx, parsed.organizationId);
    const scope = commandInputScope(ctx, parsed.tenantId, parsed.organizationId);
    const em = ctx.container.resolve("em").fork();
    const projectExists = await em.findOne(
      StaffTimeProject,
      applyScopeToWhere({ id: parsed.timeProjectId, deletedAt: null }, scope),
      { fields: ["id"] }
    );
    if (!projectExists) {
      const { translate } = await resolveTranslations();
      throw new CrudHttpError(422, {
        error: translate("staff.timesheets.errors.projectNotFound", "Time project not found or not accessible."),
        fieldErrors: {
          timeProjectId: translate("staff.timesheets.errors.projectNotFound", "Time project not found or not accessible.")
        }
      });
    }
    const memberExists = await em.findOne(
      StaffTeamMember,
      applyScopeToWhere({ id: parsed.staffMemberId, deletedAt: null }, scope),
      { fields: ["id"] }
    );
    if (!memberExists) {
      const { translate } = await resolveTranslations();
      throw new CrudHttpError(422, {
        error: translate("staff.timesheets.errors.staffMemberNotFound", "Staff member not found or not accessible."),
        fieldErrors: {
          staffMemberId: translate("staff.timesheets.errors.staffMemberNotFound", "Staff member not found or not accessible.")
        }
      });
    }
    const now = /* @__PURE__ */ new Date();
    const member = em.create(StaffTimeProjectMember, {
      tenantId: parsed.tenantId,
      organizationId: parsed.organizationId,
      timeProjectId: parsed.timeProjectId,
      staffMemberId: parsed.staffMemberId,
      role: parsed.role ?? null,
      status: parsed.status ?? "active",
      showInGrid: false,
      assignedStartDate: parsed.assignedStartDate,
      assignedEndDate: parsed.assignedEndDate ?? null,
      createdAt: now,
      updatedAt: now,
      deletedAt: null
    });
    em.persist(member);
    await em.flush();
    await emitCrudSideEffects({
      dataEngine: ctx.container.resolve("dataEngine"),
      action: "created",
      entity: member,
      identifiers: { id: member.id, organizationId: member.organizationId, tenantId: member.tenantId },
      events: staffTimeProjectMemberCrudEvents,
      indexer: timeProjectMemberCrudIndexer
    });
    return { timeProjectMemberId: member.id };
  },
  captureAfter: async (_input, result, ctx) => {
    const em = ctx.container.resolve("em").fork();
    const snapshot = await loadTimeProjectMemberSnapshot(em, result.timeProjectMemberId, staffSnapshotScopeFromContext(ctx));
    if (!snapshot) return null;
    return { snapshot };
  },
  buildLog: async ({ result, ctx }) => {
    const em = ctx.container.resolve("em").fork();
    const snapshot = await loadTimeProjectMemberSnapshot(em, result.timeProjectMemberId, staffSnapshotScopeFromContext(ctx));
    if (!snapshot) return null;
    const { translate } = await resolveTranslations();
    return {
      actionLabel: translate("staff.audit.timesheets.time_project_members.assign", "Assign time project member"),
      resourceKind: "staff.timesheets.time_project_member",
      resourceId: snapshot.id,
      tenantId: snapshot.tenantId,
      organizationId: snapshot.organizationId,
      snapshotAfter: snapshot,
      payload: {
        undo: {
          after: snapshot
        }
      }
    };
  },
  undo: async ({ logEntry, ctx }) => {
    const payload = extractUndoPayload(logEntry);
    const after = payload?.after;
    if (!after) return;
    const em = ctx.container.resolve("em").fork();
    const member = await em.findOne(StaffTimeProjectMember, scopedStaffSnapshotWhere(after.id, staffSnapshotScopeFromSnapshot(after)));
    if (member) {
      member.deletedAt = /* @__PURE__ */ new Date();
      await em.flush();
      await emitCrudUndoSideEffects({
        dataEngine: ctx.container.resolve("dataEngine"),
        action: "deleted",
        entity: member,
        identifiers: { id: member.id, organizationId: member.organizationId, tenantId: member.tenantId },
        events: staffTimeProjectMemberCrudEvents
      });
    }
  },
  redo: makeCreateRedo({
    entityClass: StaffTimeProjectMember,
    getSnapshotId: (snapshot) => snapshot.id,
    seedFromSnapshot: timeProjectMemberSeedFromSnapshot,
    buildResult: (entity) => ({ timeProjectMemberId: entity.id }),
    events: staffTimeProjectMemberCrudEvents,
    indexer: timeProjectMemberCrudIndexer
  })
};
const unassignTimeProjectMemberCommand = {
  id: "staff.timesheets.time_project_members.unassign",
  async prepare(input, ctx) {
    const id = input?.id;
    if (!id) throw new CrudHttpError(400, { error: "Time project member id is required." });
    const em = ctx.container.resolve("em");
    const snapshot = await loadTimeProjectMemberSnapshot(em, id, staffSnapshotScopeFromContext(ctx));
    if (!snapshot) return {};
    return { before: snapshot };
  },
  async execute(input, ctx) {
    const id = input?.id;
    if (!id) throw new CrudHttpError(400, { error: "Time project member id is required." });
    const em = ctx.container.resolve("em").fork();
    const scope = commandActorScope(ctx);
    const member = await findOneWithDecryption(
      em,
      StaffTimeProjectMember,
      applyScopeToWhere({ id, deletedAt: null }, scope),
      void 0,
      scopeForDecryption(scope)
    );
    if (!member) throw new CrudHttpError(404, { error: "Time project member not found." });
    ensureTenantScope(ctx, member.tenantId);
    ensureOrganizationScope(ctx, member.organizationId);
    member.deletedAt = /* @__PURE__ */ new Date();
    member.updatedAt = /* @__PURE__ */ new Date();
    await em.flush();
    await emitCrudSideEffects({
      dataEngine: ctx.container.resolve("dataEngine"),
      action: "deleted",
      entity: member,
      identifiers: { id: member.id, organizationId: member.organizationId, tenantId: member.tenantId },
      events: staffTimeProjectMemberCrudEvents,
      indexer: timeProjectMemberCrudIndexer
    });
    return { timeProjectMemberId: member.id };
  },
  buildLog: async ({ snapshots }) => {
    const before = snapshots.before;
    if (!before) return null;
    const { translate } = await resolveTranslations();
    return {
      actionLabel: translate("staff.audit.timesheets.time_project_members.unassign", "Unassign time project member"),
      resourceKind: "staff.timesheets.time_project_member",
      resourceId: before.id,
      tenantId: before.tenantId,
      organizationId: before.organizationId,
      snapshotBefore: before,
      payload: {
        undo: {
          before
        }
      }
    };
  },
  undo: async ({ logEntry, ctx }) => {
    const payload = extractUndoPayload(logEntry);
    const before = payload?.before;
    if (!before) return;
    const em = ctx.container.resolve("em").fork();
    let member = await em.findOne(StaffTimeProjectMember, scopedStaffSnapshotWhere(before.id, staffSnapshotScopeFromSnapshot(before)));
    if (!member) {
      member = em.create(StaffTimeProjectMember, {
        id: before.id,
        tenantId: before.tenantId,
        organizationId: before.organizationId,
        timeProjectId: before.timeProjectId,
        staffMemberId: before.staffMemberId,
        role: before.role ?? null,
        status: before.status ?? "active",
        showInGrid: before.showInGrid ?? false,
        assignedStartDate: new Date(before.assignedStartDate),
        assignedEndDate: before.assignedEndDate ? new Date(before.assignedEndDate) : null,
        deletedAt: null,
        createdAt: /* @__PURE__ */ new Date(),
        updatedAt: /* @__PURE__ */ new Date()
      });
      em.persist(member);
    } else {
      member.timeProjectId = before.timeProjectId;
      member.staffMemberId = before.staffMemberId;
      member.role = before.role ?? null;
      member.status = before.status ?? "active";
      member.assignedStartDate = new Date(before.assignedStartDate);
      member.assignedEndDate = before.assignedEndDate ? new Date(before.assignedEndDate) : null;
      member.deletedAt = null;
      member.updatedAt = /* @__PURE__ */ new Date();
    }
    await em.flush();
    await emitCrudUndoSideEffects({
      dataEngine: ctx.container.resolve("dataEngine"),
      action: "created",
      entity: member,
      identifiers: { id: member.id, organizationId: member.organizationId, tenantId: member.tenantId },
      events: staffTimeProjectMemberCrudEvents,
      indexer: timeProjectMemberCrudIndexer
    });
  }
};
registerCommand(createTimeProjectCommand);
registerCommand(updateTimeProjectCommand);
registerCommand(deleteTimeProjectCommand);
registerCommand(assignTimeProjectMemberCommand);
registerCommand(unassignTimeProjectMemberCommand);
//# sourceMappingURL=timesheets-projects.js.map
