import { AccountingEventType, type PostingContext, type PurchasePostedPayload } from '@/lib/accounting/core';
import type { PurchaseJournalPostingInput } from '../application/purchase-accounting.port';

function round2(value: number): number {
  return Math.round((Number(value || 0) + Number.EPSILON) * 100) / 100;
}

function resolvePaymentMethod(input: PurchaseJournalPostingInput): PurchasePostedPayload['paymentMethod'] {
  const methods = input.opts?.paymentMethods || [];
  const firstMethod = methods[0]?.method;

  if (firstMethod === 'bank_transfer') return 'bank_transfer';
  if (firstMethod === 'check' && methods[0]?.checkSource === 'incoming') return 'incoming_check';
  if (Number(input.amountPaidBase || 0) > 0) return 'cash';
  return 'none';
}

export function mapPurchaseInputToPostedEvent(
  input: PurchaseJournalPostingInput,
  overrides: {
    supplierAccountCode?: string;
    timestamp?: string;
  } = {},
): { payload: PurchasePostedPayload; context: PostingContext } {
  const tax = round2(input.taxAmountBase);
  const net = round2(input.totalAmountBase);

  const payload: PurchasePostedPayload = {
    netAmountBase: net,
    taxAmountBase: tax,
    amountPaidBase: round2(input.amountPaidBase),
    supplierAccountCode: overrides.supplierAccountCode || '2111-001',
    purchasesAccountCode: '5110',
    inputTaxAccountCode: '1160',
    cashAccountCode: '1110',
    bankAccountCode: '1120',
    notesReceivableAccountCode: '1140',
    transactionCurrency: input.currencyCode || 'USD',
    exchangeRateSnapshot: input.opts?.fxRate || 1,
    currencyPrecision: 2,
    paymentMethod: resolvePaymentMethod(input),
    branchId: 'main',
  };

  const context: PostingContext = {
    event: AccountingEventType.PURCHASE_POSTED,
    documentId: input.opts?.invoiceId || input.orderNumber,
    postingType: 'purchase',
    postingSequence: 1,
    postingRuleVersion: 'v1',
    actorId: input.createdBy,
    timestamp: overrides.timestamp || new Date().toISOString(),
    status: 'approved',
  };

  return { payload, context };
}
