import { ok, type ReadonlyDB } from "@tailor-platform/erp-kit/core";
import type { DB } from "../generated/kysely-tailordb";

export interface ListPurchaseReceiptEvidenceForMatchingInput {
  purchaseOrderId: string;
  purchaseOrderLineIds: string[];
  statuses?: ("DRAFT" | "POSTED")[];
}

export interface PurchaseReceiptEvidenceForMatching {
  purchaseOrderLineId: string;
  inventoryExecutionLineId: string;
  inventoryExecutionId: string;
  quantity: string;
  createdAt: Date;
}

export async function run(db: ReadonlyDB<DB>, input: ListPurchaseReceiptEvidenceForMatchingInput) {
  if (input.purchaseOrderLineIds.length === 0) {
    return ok({ receiptEvidence: [] as PurchaseReceiptEvidenceForMatching[] });
  }

  const receiptEvidence = await db
    .selectFrom("InventoryExecutionLine")
    .innerJoin(
      "InventoryExecution",
      "InventoryExecution.id",
      "InventoryExecutionLine.inventoryExecutionId",
    )
    .select([
      "InventoryExecutionLine.sourceLineId as purchaseOrderLineId",
      "InventoryExecutionLine.id as inventoryExecutionLineId",
      "InventoryExecutionLine.inventoryExecutionId",
      "InventoryExecutionLine.quantity",
      "InventoryExecutionLine.createdAt",
    ])
    .where("InventoryExecutionLine.sourceLineId", "in", input.purchaseOrderLineIds)
    .where("InventoryExecutionLine.direction", "=", "IN")
    .where("InventoryExecution.executionType", "=", "GOODS_RECEIPT")
    .where("InventoryExecution.status", "in", input.statuses ?? ["POSTED"])
    .where("InventoryExecution.sourceDocumentType", "=", "PURCHASE_ORDER")
    .where("InventoryExecution.sourceDocumentId", "=", input.purchaseOrderId)
    .orderBy("InventoryExecutionLine.createdAt", "asc")
    .execute();

  return ok({
    receiptEvidence: receiptEvidence.filter(
      (row): row is PurchaseReceiptEvidenceForMatching => row.purchaseOrderLineId !== null,
    ),
  });
}
