import type {
  PurchaseBill,
  PurchaseOrder,
  PurchasePaymentTerm,
  PurchasePriceList,
  PurchasePriceRule,
  Schema,
  SupplierProfile,
  GoodsReceipt,
} from "../lib/types";
import {
  encodeJson,
  type GoodsReceiptLineInput,
  type PaymentTermScheduleLineInput,
  type PurchaseBillLineInput,
  type PurchaseOrderLineInput,
} from "../lib/domain";

const createdAt = new Date("2024-01-01T00:00:00.000Z");

export const baseCompany = {
  id: "company-1",
  status: "ACTIVE",
};

export const baseSupplier = {
  id: "supplier-1",
  companyId: baseCompany.id,
  name: "Supplier One",
  status: "ACTIVE",
};

export const inactiveSupplier = {
  ...baseSupplier,
  id: "supplier-2",
  status: "INACTIVE",
};

export const baseSupplierRole = {
  id: "partner-role-1",
  partnerId: baseSupplier.id,
  role: "SUPPLIER",
};

export const baseReceivingSite = {
  id: "site-1",
  companyId: baseCompany.id,
  status: "ACTIVE",
};

export const baseCurrency = {
  id: "currency-1",
  code: "USD",
  isActive: true,
};

export const baseUnit = {
  id: "unit-1",
  categoryId: "uom-category-1",
  symbol: "EA",
  isActive: true,
};

export const compatibleUnit = {
  id: "unit-2",
  categoryId: "uom-category-1",
  symbol: "BOX",
  isActive: true,
};

export const incompatibleUnit = {
  id: "unit-3",
  categoryId: "uom-category-2",
  symbol: "KG",
  isActive: true,
};

export const baseItem = {
  id: "item-1",
  unitId: baseUnit.id,
  status: "ACTIVE",
  name: "Base Item",
  sku: "ITEM-001",
};

export const inactiveItem = {
  ...baseItem,
  id: "item-2",
  status: "INACTIVE",
};

export const baseScheduleLines: PaymentTermScheduleLineInput[] = [{ kind: "NET_DAYS", days: 30 }];

export const installmentScheduleLines: PaymentTermScheduleLineInput[] = [
  { kind: "INSTALLMENT", days: 15, percentage: 50 },
  { kind: "INSTALLMENT", days: 30, percentage: 50 },
];

export const discountScheduleLines: PaymentTermScheduleLineInput[] = [
  {
    kind: "NET_DAYS",
    days: 30,
    discountDays: 10,
    discountPercentage: 2,
    discountBasis: "GROSS_AMOUNT",
  },
];

export const basePaymentTerm = {
  id: "payment-term-1",
  companyId: baseCompany.id,
  name: "Net 30",
  code: "NET30",
  status: "ACTIVE",
  scheduleLines: encodeJson(baseScheduleLines),
  notes: null,
  createdAt,
  updatedAt: null,
} as const satisfies PurchasePaymentTerm<Schema>;

export const inactivePaymentTerm = {
  ...basePaymentTerm,
  id: "payment-term-2",
  status: "INACTIVE",
} as const satisfies PurchasePaymentTerm<Schema>;

export const baseSupplierProfile = {
  id: "supplier-profile-1",
  companyId: baseCompany.id,
  supplierId: baseSupplier.id,
  defaultPurchasePaymentTermId: basePaymentTerm.id,
  createdAt,
  updatedAt: null,
} as const satisfies SupplierProfile<Schema>;

export const basePriceList = {
  id: "price-list-1",
  companyId: baseCompany.id,
  supplierId: baseSupplier.id,
  name: "Default Supplier Contract",
  code: "PL-001",
  priority: 10,
  status: "ACTIVE",
  notes: null,
  createdAt,
  updatedAt: null,
} as const satisfies PurchasePriceList<Schema>;

export const inactivePriceList = {
  ...basePriceList,
  id: "price-list-2",
  status: "INACTIVE",
} as const satisfies PurchasePriceList<Schema>;

export const basePriceRule = {
  id: "price-rule-1",
  priceListId: basePriceList.id,
  itemId: baseItem.id,
  currencyId: baseCurrency.id,
  unitId: baseUnit.id,
  minimumQuantity: 0,
  unitPrice: 100,
  effectiveFrom: createdAt,
  effectiveTo: null,
  priority: 10,
  status: "ACTIVE",
  notes: null,
  createdAt,
  updatedAt: null,
} as const satisfies PurchasePriceRule<Schema>;

export const higherBreakPriceRule = {
  ...basePriceRule,
  id: "price-rule-2",
  minimumQuantity: 10,
  unitPrice: 90,
  priority: 20,
} as const satisfies PurchasePriceRule<Schema>;

export const inactivePriceRule = {
  ...basePriceRule,
  id: "price-rule-3",
  status: "INACTIVE",
} as const satisfies PurchasePriceRule<Schema>;

export const basePurchaseOrderLines: PurchaseOrderLineInput[] = [
  {
    id: "po-line-1",
    itemId: baseItem.id,
    quantity: 10,
    unitPrice: 100,
    unitId: baseUnit.id,
    receivingSiteId: baseReceivingSite.id,
    requiresPhysicalReceipt: true,
    matchedPriceRuleId: basePriceRule.id,
    priceSnapshot: { unitPrice: 100, matchedPriceRuleId: basePriceRule.id },
    receivedQuantity: 0,
    billedQuantity: 0,
  },
];

export const basePurchaseOrder = {
  id: "purchase-order-1",
  companyId: baseCompany.id,
  supplierId: baseSupplier.id,
  documentReceivingSiteId: baseReceivingSite.id,
  paymentTermId: basePaymentTerm.id,
  status: "DRAFT",
  orderDate: createdAt,
  externalSupplierOrderReference: "PO-EXT-1",
  lines: encodeJson(basePurchaseOrderLines),
  paymentTermSnapshot: encodeJson({
    id: basePaymentTerm.id,
    name: basePaymentTerm.name,
    lines: baseScheduleLines,
  }),
  rejectionReason: null,
  closeReason: null,
  createdAt,
  updatedAt: null,
} as const satisfies PurchaseOrder<Schema>;

export const submittedPurchaseOrder = {
  ...basePurchaseOrder,
  id: "purchase-order-2",
  status: "SUBMITTED",
} as const satisfies PurchaseOrder<Schema>;

export const orderedPurchaseOrder = {
  ...basePurchaseOrder,
  id: "purchase-order-3",
  status: "ORDERED",
} as const satisfies PurchaseOrder<Schema>;

export const baseGoodsReceiptLines: GoodsReceiptLineInput[] = [
  {
    id: "gr-line-1",
    purchaseOrderLineId: "po-line-1",
    quantity: 4,
    itemId: baseItem.id,
    unitId: baseUnit.id,
    requiresInventoryHandoff: true,
    destinationSite: baseReceivingSite.id,
    destinationStorageLocation: "dock-1",
  },
];

export const baseGoodsReceipt = {
  id: "goods-receipt-1",
  companyId: baseCompany.id,
  supplierId: baseSupplier.id,
  purchaseOrderId: orderedPurchaseOrder.id,
  receiptDate: createdAt,
  status: "DRAFT",
  lines: encodeJson(baseGoodsReceiptLines),
  inventoryHandoff: null,
  createdAt,
  updatedAt: null,
} as const satisfies GoodsReceipt<Schema>;

export const postedGoodsReceipt = {
  ...baseGoodsReceipt,
  id: "goods-receipt-2",
  status: "POSTED",
} as const satisfies GoodsReceipt<Schema>;

export const basePurchaseBillLines: PurchaseBillLineInput[] = [
  {
    id: "bill-line-1",
    purchaseOrderLineId: "po-line-1",
    quantity: 4,
    billedUnitPrice: 100,
    taxCode: "VAT",
    taxableAmount: 400,
    taxAmount: 40,
  },
];

export const basePurchaseBill = {
  id: "purchase-bill-1",
  companyId: baseCompany.id,
  supplierId: baseSupplier.id,
  invoiceNumber: "INV-001",
  invoiceDate: createdAt,
  status: "DRAFT",
  lines: encodeJson(basePurchaseBillLines),
  paymentTermSnapshot: encodeJson({
    id: basePaymentTerm.id,
    name: basePaymentTerm.name,
    lines: baseScheduleLines,
  }),
  supplierTaxIdentification: "TAX-001",
  matchingMode: null,
  varianceReason: null,
  releaseReason: null,
  dueSchedule: null,
  downstreamAccepted: false,
  comparisonEvidence: null,
  billReadyHandoff: null,
  createdAt,
  updatedAt: null,
} as const satisfies PurchaseBill<Schema>;

export const blockedPurchaseBill = {
  ...basePurchaseBill,
  id: "purchase-bill-2",
  status: "BLOCKED",
  varianceReason: "Price variance",
} as const satisfies PurchaseBill<Schema>;

export const matchedPurchaseBill = {
  ...basePurchaseBill,
  id: "purchase-bill-3",
  status: "MATCHED",
  matchingMode: "TWO_WAY",
  dueSchedule: encodeJson([{ dueDate: createdAt, amount: 440 }]),
} as const satisfies PurchaseBill<Schema>;
