import type { Prisma } from "@prisma/client";
import { prisma } from "./prisma";

/** What moved the goods. Positive types add stock, negative ones remove it; ADJUSTMENT / INVENTORY can go either way. */
export const STOCK_MOVE_TYPES = [
  "OPENING",
  "PURCHASE",
  "PURCHASE_CANCEL",
  "SALE",
  "SALE_CANCEL",
  "TRUCK_LOAD",
  "TRUCK_RETURN",
  "STORE_TRANSFER",
  "STORE_RETURN",
  "CUSTOMER_RETURN",
  "LOSS",
  "INVENTORY",
  "ADJUSTMENT",
] as const;
export type StockMoveType = (typeof STOCK_MOVE_TYPES)[number];

/** Types a person can record by hand from the stock pages (the others come from documents). */
export const MANUAL_MOVE_TYPES = ["ADJUSTMENT", "INVENTORY", "LOSS", "CUSTOMER_RETURN"] as const;

type Tx = Prisma.TransactionClient;

export type StockMoveInput = {
  productId: string;
  delta: number;
  type: StockMoveType;
  reason?: string;
  reference?: string | null;
  sourceId?: string | null;
  unitCost?: number | null;
  userId?: string | null;
};

/**
 * Change a product's warehouse quantity and write the ledger line with the balance after it.
 * Pass `tx` to run inside a caller's transaction.
 */
export async function moveStock(input: StockMoveInput, tx?: Tx) {
  const run = async (db: Tx) => {
    const product = await db.product.update({
      where: { id: input.productId },
      data: { quantity: { increment: input.delta } },
    });
    return db.stockMove.create({
      data: {
        productId: input.productId,
        delta: input.delta,
        type: input.type,
        reason: input.reason ?? "",
        reference: input.reference ?? null,
        sourceId: input.sourceId ?? null,
        unitCost: input.unitCost ?? null,
        userId: input.userId ?? null,
        balanceAfter: product.quantity,
      },
    });
  };
  return tx ? run(tx) : prisma.$transaction(run);
}

/** Link from a ledger line to the document that caused it. */
export function sourceHref(move: { type: string; sourceId: string | null }) {
  if (!move.sourceId) return null;
  if (move.type === "PURCHASE" || move.type === "PURCHASE_CANCEL") return `/purchases/${move.sourceId}`;
  if (move.type === "SALE" || move.type === "SALE_CANCEL" || move.type === "CUSTOMER_RETURN") return `/delivery-notes/${move.sourceId}`;
  if (move.type === "TRUCK_LOAD" || move.type === "TRUCK_RETURN") return `/rounds/${move.sourceId}`;
  return null;
}
