import { z } from "zod";
import { makeCrudRoute } from "@open-mercato/shared/lib/crud/factory";
import { resolveTranslations } from "@open-mercato/shared/lib/i18n/server";
import { CrudHttpError } from "@open-mercato/shared/lib/crud/errors";
import { SalesQuoteAdjustment } from "../../data/entities.js";
import {
  enforceAdjustmentSign,
  quoteAdjustmentCreateSchema
} from "../../data/validators.js";
import { createPagedListResponseSchema, createSalesCrudOpenApi, defaultOkResponseSchema } from "../openapi.js";
import { withScopedPayload } from "../utils.js";
import { E } from "../../../../generated/entities.ids.generated.js";
import * as F from "../../../../generated/entities/sales_quote_adjustment/index.js";
import { buildCustomFieldFiltersFromQuery, extractAllCustomFieldEntries } from "@open-mercato/shared/lib/crud/custom-fields";
const rawBodySchema = z.object({}).passthrough();
const listSchema = z.object({
  page: z.coerce.number().min(1).default(1),
  pageSize: z.coerce.number().min(1).max(100).default(50),
  quoteId: z.string().uuid().optional(),
  sortField: z.string().optional(),
  sortDir: z.enum(["asc", "desc"]).optional()
}).passthrough();
const routeMetadata = {
  GET: { requireAuth: true, requireFeatures: ["sales.quotes.view"] },
  POST: { requireAuth: true, requireFeatures: ["sales.quotes.manage"] },
  PUT: { requireAuth: true, requireFeatures: ["sales.quotes.manage"] },
  DELETE: { requireAuth: true, requireFeatures: ["sales.quotes.manage"] }
};
const upsertSchema = quoteAdjustmentCreateSchema.extend({ id: z.string().uuid().optional() }).superRefine(enforceAdjustmentSign);
const deleteSchema = z.object({
  id: z.string().uuid(),
  quoteId: z.string().uuid()
});
const crud = makeCrudRoute({
  metadata: routeMetadata,
  orm: {
    entity: SalesQuoteAdjustment,
    idField: "id",
    orgField: "organizationId",
    tenantField: "tenantId",
    softDeleteField: "deletedAt"
  },
  indexer: { entityType: E.sales.sales_quote_adjustment },
  list: {
    schema: listSchema,
    entityId: E.sales.sales_quote_adjustment,
    decorateCustomFields: { entityIds: [E.sales.sales_quote_adjustment] },
    fields: [
      F.id,
      "quote_id",
      "quote_line_id",
      F.scope,
      F.kind,
      F.code,
      F.label,
      F.calculator_key,
      F.promotion_id,
      F.rate,
      F.amount_net,
      F.amount_gross,
      F.currency_code,
      F.metadata,
      F.position,
      F.created_at,
      F.updated_at
    ],
    sortFieldMap: {
      createdAt: F.created_at,
      updatedAt: F.updated_at,
      position: F.position
    },
    buildFilters: async (query, ctx) => {
      const filters = {};
      if (query.quoteId) filters.quote_id = { $eq: query.quoteId };
      try {
        const em = ctx.container.resolve("em");
        const cfFilters = await buildCustomFieldFiltersFromQuery({
          entityId: E.sales.sales_quote_adjustment,
          query,
          em,
          tenantId: ctx.auth?.tenantId ?? null
        });
        Object.assign(filters, cfFilters);
      } catch {
      }
      return filters;
    },
    transformItem: (item) => {
      if (!item) return item;
      const normalized = { ...item };
      const cfEntries = extractAllCustomFieldEntries(item);
      for (const key of Object.keys(normalized)) {
        if (key.startsWith("cf:")) delete normalized[key];
      }
      return { ...normalized, ...cfEntries };
    }
  },
  actions: {
    create: {
      commandId: "sales.quotes.adjustments.upsert",
      schema: rawBodySchema,
      mapInput: async ({ raw, ctx }) => {
        const { translate } = await resolveTranslations();
        const payload = upsertSchema.parse(withScopedPayload(raw ?? {}, ctx, translate));
        return { body: payload };
      },
      response: ({ result }) => ({ id: result?.adjustmentId ?? null, quoteId: result?.quoteId ?? null }),
      status: 201
    },
    update: {
      commandId: "sales.quotes.adjustments.upsert",
      schema: rawBodySchema,
      mapInput: async ({ raw, ctx }) => {
        const { translate } = await resolveTranslations();
        const payload = upsertSchema.parse(withScopedPayload(raw ?? {}, ctx, translate));
        return { body: payload };
      },
      response: ({ result }) => ({ id: result?.adjustmentId ?? null, quoteId: result?.quoteId ?? null })
    },
    delete: {
      commandId: "sales.quotes.adjustments.delete",
      schema: rawBodySchema,
      mapInput: async ({ raw, ctx }) => {
        const { translate } = await resolveTranslations();
        const payload = deleteSchema.parse(
          withScopedPayload(
            {
              ...raw?.body ?? {},
              ...raw?.query ?? {}
            },
            ctx,
            translate
          )
        );
        if (!payload.id || !payload.quoteId) {
          throw new CrudHttpError(400, { error: translate("sales.documents.detail.error", "Document not found or inaccessible.") });
        }
        return { body: payload };
      },
      response: () => ({ ok: true })
    }
  }
});
const { GET, POST, PUT, DELETE } = crud;
const metadata = routeMetadata;
const adjustmentSchema = z.object({
  id: z.string().uuid(),
  quote_id: z.string().uuid(),
  quote_line_id: z.string().uuid().nullable().optional(),
  scope: z.string(),
  kind: z.string(),
  code: z.string().nullable().optional(),
  label: z.string().nullable().optional(),
  calculator_key: z.string().nullable().optional(),
  promotion_id: z.string().uuid().nullable().optional(),
  rate: z.number(),
  amount_net: z.number(),
  amount_gross: z.number(),
  currency_code: z.string().nullable().optional(),
  metadata: z.record(z.string(), z.unknown()).nullable().optional(),
  position: z.number(),
  created_at: z.string(),
  updated_at: z.string()
});
const openApi = createSalesCrudOpenApi({
  resourceName: "Quote adjustment",
  querySchema: listSchema,
  listResponseSchema: createPagedListResponseSchema(adjustmentSchema),
  create: {
    schema: upsertSchema,
    responseSchema: z.object({ id: z.string().uuid().nullable(), quoteId: z.string().uuid().nullable() }),
    description: "Creates a quote adjustment and recalculates totals."
  },
  update: {
    schema: upsertSchema,
    responseSchema: z.object({ id: z.string().uuid().nullable(), quoteId: z.string().uuid().nullable() }),
    description: "Updates a quote adjustment and recalculates totals."
  },
  del: {
    schema: deleteSchema,
    responseSchema: defaultOkResponseSchema,
    description: "Deletes a quote adjustment and recalculates totals."
  }
});
export {
  DELETE,
  GET,
  POST,
  PUT,
  metadata,
  openApi
};
//# sourceMappingURL=route.js.map
