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 { Dictionary, DictionaryEntry } from "@open-mercato/core/modules/dictionaries/data/entities";
import { E } from "../../../../generated/entities.ids.generated.js";
import * as F from "../../../../generated/entities/dictionary_entry/index.js";
import { statusDictionaryCreateSchema, statusDictionaryUpdateSchema } from "../../data/validators.js";
import { getSalesDictionaryDefinition, ensureSalesDictionary } from "../../lib/dictionaries.js";
import { buildAggregateSearchFilter, parseScopedCommandInput, resolveCrudRecordId } from "../utils.js";
import {
  createPagedListResponseSchema,
  createSalesCrudOpenApi,
  defaultDeleteRequestSchema
} from "../openapi.js";
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),
  search: z.string().optional(),
  sortField: z.string().optional(),
  sortDir: z.enum(["asc", "desc"]).optional()
}).passthrough();
const kind = "adjustment-kind";
const definition = getSalesDictionaryDefinition(kind);
const metadata = {
  GET: { requireAuth: true, requireFeatures: ["sales.orders.view"] },
  POST: { requireAuth: true, requireFeatures: ["sales.settings.manage"] },
  PUT: { requireAuth: true, requireFeatures: ["sales.settings.manage"] },
  DELETE: { requireAuth: true, requireFeatures: ["sales.settings.manage"] }
};
const dictionaryItemSchema = z.object({
  id: z.string().uuid(),
  value: z.string(),
  label: z.string().nullable(),
  color: z.string().nullable(),
  icon: z.string().nullable(),
  organizationId: z.string().uuid().nullable(),
  tenantId: z.string().uuid().nullable(),
  createdAt: z.string(),
  updatedAt: z.string()
});
const dictionaryListResponseSchema = createPagedListResponseSchema(dictionaryItemSchema);
const normalizeId = (value) => {
  if (typeof value !== "string") return null;
  const trimmed = value.trim();
  return trimmed.length > 0 ? trimmed : null;
};
async function resolveDictionaryContext(ctx) {
  if (!ctx.auth || !ctx.auth.tenantId) {
    throw new CrudHttpError(401, { error: "Tenant context is required." });
  }
  const em = ctx.container.resolve("em");
  const tenantId = ctx.auth.tenantId;
  const candidateOrgIds = /* @__PURE__ */ new Set();
  const pushCandidate = (value) => {
    const normalized = normalizeId(value);
    if (normalized) candidateOrgIds.add(normalized);
  };
  pushCandidate(ctx.selectedOrganizationId);
  pushCandidate(ctx.auth.orgId ?? null);
  const scope = ctx.organizationScope;
  if (scope) {
    if (Array.isArray(scope.filterIds)) {
      for (const id of scope.filterIds) pushCandidate(id);
    }
    if (Array.isArray(scope.allowedIds)) {
      for (const id of scope.allowedIds) pushCandidate(id);
    }
  }
  for (const orgId of candidateOrgIds) {
    const dictionary = await ensureSalesDictionary({
      em,
      tenantId,
      organizationId: orgId,
      kind
    });
    if (dictionary) {
      return { dictionaryId: dictionary.id, organizationId: orgId };
    }
  }
  const fallback = await em.findOne(
    Dictionary,
    {
      tenantId,
      key: definition.key,
      deletedAt: null
    },
    { orderBy: { createdAt: "asc" } }
  );
  if (fallback) {
    return { dictionaryId: fallback.id, organizationId: fallback.organizationId };
  }
  throw new CrudHttpError(400, { error: "Organization context is required." });
}
const crud = makeCrudRoute({
  metadata,
  orm: {
    entity: DictionaryEntry,
    idField: "id",
    orgField: "organizationId",
    tenantField: "tenantId",
    softDeleteField: null
  },
  indexer: { entityType: E.dictionaries.dictionary_entry },
  list: {
    schema: listSchema,
    entityId: E.dictionaries.dictionary_entry,
    fields: [
      F.id,
      F.value,
      F.label,
      F.color,
      F.icon,
      F.organization_id,
      F.tenant_id,
      F.created_at,
      F.updated_at
    ],
    sortFieldMap: {
      id: F.id,
      value: F.value,
      label: F.label,
      createdAt: F.created_at,
      updatedAt: F.updated_at
    },
    buildFilters: async (query, ctx) => {
      const { dictionaryId } = await resolveDictionaryContext(ctx);
      const filters = {
        dictionary_id: dictionaryId
      };
      const searchFilter = buildAggregateSearchFilter(query.search);
      if (searchFilter) Object.assign(filters, searchFilter);
      return filters;
    },
    transformItem: (item) => ({
      id: item.id,
      value: item.value,
      label: item.label,
      color: item.color ?? null,
      icon: item.icon ?? null,
      organizationId: item.organization_id ?? null,
      tenantId: item.tenant_id ?? null,
      createdAt: item.created_at,
      updatedAt: item.updated_at
    })
  },
  actions: {
    create: {
      commandId: `${definition.commandPrefix}.create`,
      schema: rawBodySchema,
      mapInput: async ({ raw, ctx }) => {
        const { translate } = await resolveTranslations();
        return parseScopedCommandInput(statusDictionaryCreateSchema, raw ?? {}, ctx, translate);
      },
      response: ({ result }) => ({ id: result?.entryId ?? null }),
      status: 201
    },
    update: {
      commandId: `${definition.commandPrefix}.update`,
      schema: rawBodySchema,
      mapInput: async ({ raw, ctx }) => {
        const { translate } = await resolveTranslations();
        return parseScopedCommandInput(statusDictionaryUpdateSchema, raw ?? {}, ctx, translate);
      },
      response: () => ({ ok: true })
    },
    delete: {
      commandId: `${definition.commandPrefix}.delete`,
      schema: rawBodySchema,
      mapInput: async ({ parsed, ctx }) => {
        const { translate } = await resolveTranslations();
        const id = resolveCrudRecordId(parsed, ctx, translate);
        return { id };
      },
      response: () => ({ ok: true })
    }
  }
});
const { GET, POST, PUT, DELETE } = crud;
const openApi = createSalesCrudOpenApi({
  resourceName: "Sales adjustment kind",
  querySchema: listSchema,
  listResponseSchema: dictionaryListResponseSchema,
  create: {
    schema: rawBodySchema,
    responseSchema: z.object({ id: z.string().uuid().nullable() }),
    description: "Creates an adjustment kind."
  },
  update: {
    schema: rawBodySchema,
    responseSchema: defaultDeleteRequestSchema,
    description: "Updates an adjustment kind."
  },
  del: {
    schema: rawBodySchema,
    responseSchema: defaultDeleteRequestSchema,
    description: "Deletes an adjustment kind."
  }
});
export {
  DELETE,
  GET,
  POST,
  PUT,
  metadata,
  openApi
};
//# sourceMappingURL=route.js.map
