import {
  DispoStagedRecordType,
} from "@capakraken/db";
import { commitDispoImportBatch } from "@capakraken/application";
import { TRPCError } from "@trpc/server";
import { createAuditEntry } from "../lib/audit.js";
import {
  assertImportBatchCancelable,
  buildCancelledImportBatchUpdateData,
  buildDispoImportCommitAuditSummary,
  buildResolvedStagedRecordUpdateData,
  resolveDispoStagedRecordStoreKey,
  type DispoStagedRecordStores,
} from "./dispo-management-support.js";

type AuditDb = Parameters<typeof createAuditEntry>[0]["db"];
type CommitDb = Parameters<typeof commitDispoImportBatch>[0];

export async function cancelImportBatch(
  db: AuditDb & {
    importBatch: { findUnique: Function; update: Function };
  },
  input: { id: string; userId?: string | undefined },
) {
  const batch = await db.importBatch.findUnique({
    where: { id: input.id },
    select: { id: true, status: true },
  });

  if (!batch) {
    throw new TRPCError({ code: "NOT_FOUND", message: `Import batch "${input.id}" not found` });
  }
  assertImportBatchCancelable({ id: input.id, status: batch.status });

  const cancelled = await db.importBatch.update({
    where: { id: input.id },
    data: buildCancelledImportBatchUpdateData(),
  });

  void createAuditEntry({
    db,
    entityType: "ImportBatch",
    entityId: input.id,
    action: "UPDATE",
    summary: "Cancelled import batch",
    after: cancelled as Record<string, unknown>,
    source: "ui",
    ...(input.userId !== undefined ? { userId: input.userId } : {}),
  });

  return cancelled;
}

export async function resolveStagedRecord(
  db: DispoStagedRecordStores,
  input: { action: "APPROVE" | "REJECT" | "SKIP"; id: string; recordType: DispoStagedRecordType },
) {
  const storeKey = resolveDispoStagedRecordStoreKey(input.recordType);
  return db[storeKey].update({
    where: { id: input.id },
    data: buildResolvedStagedRecordUpdateData(input.action),
  });
}

export async function commitImportBatch(
  db: CommitDb,
  input: {
    importBatchId: string;
    allowTbdUnresolved?: boolean | undefined;
    importTbdProjects?: boolean | undefined;
    userId?: string | undefined;
  },
) {
  const result = await commitDispoImportBatch(db, {
    importBatchId: input.importBatchId,
    ...(input.allowTbdUnresolved !== undefined ? { allowTbdUnresolved: input.allowTbdUnresolved } : {}),
    ...(input.importTbdProjects !== undefined ? { importTbdProjects: input.importTbdProjects } : {}),
  });

  const counts = result as unknown as Record<string, unknown>;
  void createAuditEntry({
    db: db as AuditDb,
    entityType: "ImportBatch",
    entityId: input.importBatchId,
    entityName: input.importBatchId,
    action: "IMPORT",
    summary: buildDispoImportCommitAuditSummary(counts),
    after: counts,
    source: "ui",
    ...(input.userId !== undefined ? { userId: input.userId } : {}),
  });

  return result;
}
