import {
  type CommonReservedFields,
  type NoReservedFields,
  defaultGqlPermission,
  defaultPermission,
} from "@tailor-platform/erp-kit/core";
import { db, type TailorAnyDBField } from "@tailor-platform/sdk";
import { pipeline } from "./pipeline";

const builtins = () => ({
  pipelineId: db
    .uuid()
    .relation({
      type: "n-1",
      toward: { type: pipeline },
      backward: "labels",
    })
    .description("ID of the pipeline this label belongs to"),
  name: db.string().description("PipelineLabel name (e.g. 'urgent', 'frontend', 'tech-debt')"),
  color: db.string({ optional: true }).description("Color code for UI display (e.g. '#EF4444')"),
  description: db
    .string({ optional: true })
    .description("Purpose or operational notes for the label"),
});

type ReservedFields = keyof ReturnType<typeof builtins> | CommonReservedFields;

export interface CreatePipelineLabelTypeParams<F extends Record<string, TailorAnyDBField>> {
  fields?: NoReservedFields<F, ReservedFields>;
}

export function createPipelineLabelType<const F extends Record<string, TailorAnyDBField>>(
  params: CreatePipelineLabelTypeParams<F> = {},
) {
  return db
    .type("PipelineLabel", {
      ...builtins(),
      // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- mirrors erp-kit's createXxxType factories; field bag is constrained but TS can't prove F is concrete
      ...((params.fields ?? {}) as F),
      ...db.fields.timestamps(),
    })
    .description(
      "A classification label freely definable per pipeline. Any number can be attached to a PipelineItem, and they are used for filtering and reporting. " +
        "Duplicate names per pipeline are prevented by a unique index, with a friendly duplicate check in the create/update commands.",
    )
    .indexes({
      fields: ["pipelineId", "name"],
      unique: true,
      name: "label_pipeline_name_unique_idx",
    })
    .permission(defaultPermission)
    .gqlPermission(defaultGqlPermission);
}

export const pipelineLabel = createPipelineLabelType({});
