/* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unused-vars */
import type { Transaction } from "../generated/kysely-tailordb";
import {
  CompanyScopeMismatchError,
  PartnerNotSupplierError,
  PaymentTermInactiveError,
  PaymentTermNotFoundError,
  SupplierNotFoundError,
} from "../lib/errors.generated";
import {
  getSupplierProfileByCompanyAndSupplier,
  getSupplierRole,
  isActiveStatus,
  selectOne,
} from "../lib/domain";
import { err, ok, type CommandContext } from "@tailor-platform/erp-kit/module";

export interface SetSupplierDefaultPurchasePaymentTermInput {
  companyId: string;
  supplierId: string;
  defaultPurchasePaymentTermId?: string | null;
}

export async function run(
  db: Transaction,
  input: SetSupplierDefaultPurchasePaymentTermInput,
  ctx: CommandContext,
) {
  const supplier = await selectOne(db, "BusinessPartner", "id", input.supplierId);
  if (!supplier) {
    return err(new SupplierNotFoundError(input.supplierId));
  }

  const supplierRole = await getSupplierRole(db, input.supplierId);
  if (!supplierRole) {
    return err(new PartnerNotSupplierError(input.supplierId));
  }

  const paymentTermId = input.defaultPurchasePaymentTermId ?? null;
  if (paymentTermId) {
    const paymentTerm = await selectOne(db, "PurchasePaymentTerm", "id", paymentTermId);
    if (!paymentTerm) {
      return err(new PaymentTermNotFoundError(paymentTermId));
    }
    if (paymentTerm.companyId !== input.companyId) {
      return err(new CompanyScopeMismatchError(paymentTermId));
    }
    if (!isActiveStatus(paymentTerm.status as string | null)) {
      return err(new PaymentTermInactiveError(paymentTermId));
    }
  }

  const existing = await getSupplierProfileByCompanyAndSupplier(
    db,
    input.companyId,
    input.supplierId,
    true,
  );
  if (existing) {
    if (existing.defaultPurchasePaymentTermId === paymentTermId) {
      return ok({ supplierProfile: existing });
    }

    const supplierProfile = await db
      .updateTable("SupplierProfile")
      .set({
        defaultPurchasePaymentTermId: paymentTermId,
        updatedAt: new Date(),
      })
      .where("id", "=", existing.id as string)
      .returningAll()
      .executeTakeFirstOrThrow();

    return ok({ supplierProfile });
  }

  const supplierProfile = await db
    .insertInto("SupplierProfile")
    .values({
      companyId: input.companyId,
      supplierId: input.supplierId,
      defaultPurchasePaymentTermId: paymentTermId,
      createdAt: new Date(),
      updatedAt: null,
    })
    .returningAll()
    .executeTakeFirst();

  return ok({ supplierProfile: supplierProfile! });
}
