/* eslint-disable @typescript-eslint/no-unused-vars */
import type { Selectable, Transaction } from "../generated/kysely-tailordb";
import {
  CompanyNotFoundError,
  EmptyScheduleError,
  InvalidInstallmentTotalError,
  InvalidScheduleLineError,
} from "../lib/errors.generated";
import { validateScheduleLines } from "../lib/domain";
import { err, ok, type CommandContext } from "@tailor-platform/erp-kit/core";

export interface CreatePurchasePaymentTermInput {
  companyId: string;
  name: string;
  code?: string;
  scheduleLines: Pick<
    Selectable<"PurchasePaymentTermLine">,
    "kind" | "days" | "fixedDayOfMonth" | "percentage" | "fixedAmount" | "note"
  >[];
  notes?: string;
}

export async function run<CF extends Record<string, unknown>>(
  db: Transaction,
  input: CreatePurchasePaymentTermInput & CF,
  ctx: CommandContext,
) {
  const { companyId, name, code, scheduleLines, notes, ...customFields } = input;
  const company = await db
    .selectFrom("Company")
    .selectAll()
    .where("id", "=", companyId)
    .executeTakeFirst();
  if (!company) {
    return err(new CompanyNotFoundError(companyId));
  }

  const validation = validateScheduleLines(scheduleLines);
  if (validation === "EMPTY_SCHEDULE") {
    return err(new EmptyScheduleError(companyId));
  }
  if (validation === "INVALID_INSTALLMENT_TOTAL") {
    return err(new InvalidInstallmentTotalError(companyId));
  }
  if (validation === "INVALID_SCHEDULE_LINE") {
    return err(new InvalidScheduleLineError(companyId));
  }

  const paymentTerm = await db
    .insertInto("PurchasePaymentTerm")
    .values({
      ...(customFields as Record<string, unknown>),
      companyId,
      name,
      code: code ?? null,
      status: "ACTIVE",
      notes: notes ?? null,
      createdAt: new Date(),
      updatedAt: null,
    })
    .returningAll()
    .executeTakeFirstOrThrow();

  const now = new Date();
  await db
    .insertInto("PurchasePaymentTermLine")
    .values(
      scheduleLines.map((line) => ({
        purchasePaymentTermId: paymentTerm.id,
        kind: line.kind ?? "NET_DAYS",
        days: line.days ?? null,
        fixedDayOfMonth: line.fixedDayOfMonth ?? null,
        percentage: line.percentage ?? null,
        fixedAmount: line.fixedAmount ?? null,
        note: line.note ?? null,
        createdAt: now,
        updatedAt: null,
      })),
    )
    .execute();

  return ok({ paymentTerm });
}
