import { z } from "zod";
import { loadAuditLogDisplayMaps } from "@open-mercato/core/modules/audit_logs/api/audit-logs/display";
import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
import { resolveOrganizationScopeForRequest } from "@open-mercato/core/modules/directory/utils/organizationScope";
import { resolveTranslations } from "@open-mercato/shared/lib/i18n/server";
import { CrudHttpError, isCrudHttpError } from "@open-mercato/shared/lib/crud/errors";
import { NextResponse } from "next/server";
import { buildHistoryEntries } from "../../lib/historyHelpers.js";
import { SalesNote } from "../../data/entities.js";
import { findWithDecryption } from "@open-mercato/shared/lib/encryption/find";
import { createLogger } from "@open-mercato/shared/lib/logger";
const logger = createLogger("sales");
const metadata = {
  GET: { requireAuth: true }
};
const querySchema = z.object({
  kind: z.enum(["order", "quote"]),
  id: z.string().uuid(),
  limit: z.coerce.number().min(1).max(100).default(50),
  before: z.string().optional(),
  after: z.string().optional(),
  types: z.string().optional()
  // comma-separated: status,action,comment
});
const HISTORY_TYPES = /* @__PURE__ */ new Set(["status", "action", "comment"]);
function parseDocumentHistoryTypes(input) {
  const raw = typeof input === "string" ? input.trim() : "";
  if (!raw) return /* @__PURE__ */ new Set();
  const values = raw.split(",").map((part) => part.trim().toLowerCase()).filter((value) => value.length > 0);
  const result = /* @__PURE__ */ new Set();
  values.forEach((value) => {
    if (HISTORY_TYPES.has(value)) {
      result.add(value);
    }
  });
  return result;
}
async function GET(req) {
  try {
    const url = new URL(req.url);
    const query = querySchema.parse(Object.fromEntries(url.searchParams));
    const container = await createRequestContainer();
    const auth = await getAuthFromRequest(req);
    const { translate } = await resolveTranslations();
    if (!auth || !auth.tenantId) {
      throw new CrudHttpError(401, { error: translate("sales.documents.errors.unauthorized", "Unauthorized") });
    }
    const scope = await resolveOrganizationScopeForRequest({ container, auth, request: req });
    const organizationId = scope?.selectedId ?? auth.orgId ?? null;
    if (!organizationId) {
      throw new CrudHttpError(400, {
        error: translate("sales.documents.errors.organization_required", "Organization context is required")
      });
    }
    const requiredFeature = query.kind === "order" ? "sales.orders.view" : "sales.quotes.view";
    const rbac = container.resolve("rbacService");
    const hasAccess = await rbac.userHasAllFeatures(auth.sub, [requiredFeature], {
      tenantId: auth.tenantId,
      organizationId
    });
    if (!hasAccess) {
      throw new CrudHttpError(403, { error: translate("api.errors.forbidden", "Forbidden") });
    }
    const resourceKind = query.kind === "order" ? "sales.order" : "sales.quote";
    const actionLogService = container.resolve("actionLogService");
    const em = container.resolve("em").fork();
    const [actionLogList, notes] = await Promise.all([
      actionLogService.list({
        tenantId: auth.tenantId,
        organizationId,
        resourceKind,
        resourceId: query.id,
        includeRelated: true,
        limit: query.limit,
        before: query.before ? new Date(query.before) : void 0,
        after: query.after ? new Date(query.after) : void 0
      }),
      findWithDecryption(
        em,
        SalesNote,
        {
          contextType: query.kind,
          contextId: query.id,
          tenantId: auth.tenantId,
          organizationId,
          deletedAt: null
        },
        { orderBy: { createdAt: "DESC" } },
        { tenantId: auth.tenantId, organizationId }
      )
    ]);
    const logs = actionLogList.items;
    const allUserIds = [
      ...logs.map((l) => l.actorUserId).filter((v) => !!v),
      ...notes.map((n) => n.authorUserId).filter((v) => !!v)
    ];
    const displayMaps = await loadAuditLogDisplayMaps(em, {
      userIds: allUserIds,
      tenantIds: [],
      organizationIds: []
    });
    let items = buildHistoryEntries({ actionLogs: logs, notes, kind: query.kind, displayUsers: displayMaps.users });
    const typesFilter = parseDocumentHistoryTypes(query.types);
    if (typesFilter.size > 0) {
      items = items.filter((entry) => typesFilter.has(entry.kind));
    }
    let nextCursor = void 0;
    if (logs.length === query.limit && items.length > 0) {
      const last = items[items.length - 1];
      nextCursor = Buffer.from(`${last.occurredAt}|${last.id}`).toString("base64");
    }
    return NextResponse.json({ items, nextCursor });
  } catch (err) {
    if (isCrudHttpError(err)) {
      return NextResponse.json(err.body, { status: err.status });
    }
    logger.error("sales.document-history.get failed", { err });
    const { translate } = await resolveTranslations();
    return NextResponse.json(
      { error: translate("sales.documents.history.error", "Failed to load history.") },
      { status: 400 }
    );
  }
}
const historyActorSchema = z.object({
  id: z.string().uuid().nullable(),
  label: z.string()
});
const historyEntrySchema = z.object({
  id: z.string(),
  occurredAt: z.string().datetime(),
  kind: z.enum(["status", "action", "comment"]),
  action: z.string(),
  actor: historyActorSchema,
  source: z.enum(["action_log", "note"]),
  metadata: z.object({
    statusFrom: z.string().nullable().optional(),
    statusTo: z.string().nullable().optional(),
    documentKind: z.enum(["order", "quote"]).optional(),
    commandId: z.string().optional()
  }).optional()
});
const documentHistoryResponseSchema = z.object({
  items: z.array(historyEntrySchema),
  nextCursor: z.string().optional()
});
const openApi = {
  tag: "Sales",
  summary: "Get document change history",
  methods: {
    GET: {
      summary: "List history entries for an order or quote",
      query: querySchema,
      responses: [
        { status: 200, description: "History entries", schema: documentHistoryResponseSchema },
        { status: 400, description: "Invalid query", schema: z.object({ error: z.string() }) },
        { status: 401, description: "Unauthorized", schema: z.object({ error: z.string() }) },
        { status: 403, description: "Forbidden", schema: z.object({ error: z.string() }) },
        { status: 404, description: "Document not found", schema: z.object({ error: z.string() }) }
      ]
    }
  }
};
export {
  GET,
  metadata,
  openApi,
  parseDocumentHistoryTypes
};
//# sourceMappingURL=route.js.map
