import {
  db,
  type TailorAnyDBField,
  unsafeAllowAllGqlPermission,
  unsafeAllowAllTypePermission,
} from "@tailor-platform/sdk";
import { item as itemStub } from "../lib/_db_deps";
import { storageLocation } from "./storageLocation";
import { inventoryCount } from "./inventoryCount";
import { lot } from "./lot";
import { serialNumber } from "./serialNumber";

export const ADJUSTMENT_TYPES = ["CORRECTION", "SCRAP"] as const;
export const BASE_ADJUSTMENT_STATUSES = [
  "DRAFT",
  "PENDING_APPROVAL",
  "APPROVED",
  "REJECTED",
  "CONFIRMED",
] as const;

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

export function createInventoryAdjustmentType<const F extends Record<string, TailorAnyDBField>>(
  params: CreateInventoryAdjustmentTypeParams<F>,
) {
  return db
    .type("InventoryAdjustment", {
      adjustmentType: db
        .enum([...ADJUSTMENT_TYPES] as [string, ...string[]])
        .description("Adjustment type: CORRECTION or SCRAP"),
      itemId: db
        .uuid()
        .relation({
          type: "n-1",
          toward: { type: itemStub },
          backward: "inventoryAdjustments",
        })
        .description("Foreign key to Item"),
      storageLocationId: db
        .uuid()
        .relation({
          type: "n-1",
          toward: { type: storageLocation },
          backward: "inventoryAdjustments",
        })
        .description("Foreign key to StorageLocation"),
      quantityDelta: db
        .float()
        .description("Quantity change (positive for increase, negative for decrease)"),
      reasonCode: db.string().description("Reason code for the adjustment"),
      status: db
        .enum([...BASE_ADJUSTMENT_STATUSES] as [string, ...string[]])
        .description("Lifecycle status: DRAFT, PENDING_APPROVAL, APPROVED, REJECTED, CONFIRMED"),
      inventoryCountId: db
        .uuid({ optional: true })
        .relation({
          type: "n-1",
          toward: { type: inventoryCount },
          backward: "inventoryAdjustments",
        })
        .description("Optional link to originating inventory count"),
      lotId: db
        .uuid({ optional: true })
        .relation({
          type: "n-1",
          toward: { type: lot },
          backward: "inventoryAdjustments",
        })
        .description("Optional foreign key to Lot for lot-tracked items"),
      serialNumberId: db
        .uuid({ optional: true })
        .relation({
          type: "n-1",
          toward: { type: serialNumber },
          backward: "inventoryAdjustments",
        })
        .description("Optional foreign key to SerialNumber for serial-tracked items"),
      ...((params.fields ?? {}) as F),
      ...db.fields.timestamps(),
    })
    .permission(unsafeAllowAllTypePermission)
    .gqlPermission(unsafeAllowAllGqlPermission);
}

export const inventoryAdjustment = createInventoryAdjustmentType({});
