/**
 * Core sales calculation library by Softseti
 * @module softseti-sale-calculator-library
 */

import { PaymentCalculation, RefundCalculation, RefundOptions, Sale, SaleItem, SaleTotals, WholesaleLevel } from "./interfaces";

declare module 'softseti-sale-calculator-library' {
  /**
   * Initializes the calculator with global parameters
   * @param {object} params - Configuration parameters
   */
  export function init(params: any): void;

  /**
   * Preprocesses sale data for calculations
   * @param {Sale} sale - Sale object to preprocess
   * @returns {Sale} Preprocessed sale object
   */
  export function preprocessSale(sale: any): any;

  /**
   * Calculates subtotal for a sale
   * @param {Sale} sale - Sale object
   * @returns {number} Subtotal amount
   */
  export function calcSubtotal(sale: any): number;

  /**
   * Calculates total amount for a sale
   * @param {Sale} sale - Sale object
   * @returns {number} Total amount
   */
  export function calcTotal(sale: any): number;

  /**
   * Calculates remaining debt for a sale
   * @param {Sale} sale - Sale object
   * @returns {number} Debt amount
   */
  export function calcDebt(sale: any): number;

  /**
   * Calculates change amount for a sale
   * @param {Sale} sale - Sale object
   * @returns {number} Change amount
   */
  export function calcChange(sale: any): number;

  /**
   * Calculates taxes by tax abbreviation
   * @param {Sale} sale - Sale object
   * @param {string} abbreviation - Tax abbreviation (e.g., 'VAT')
   * @returns {number} Tax amount
   */
  export function calcTaxesByAbbreviation(sale: Sale, abbreviation: string): number;

  /**
   * Calculates original payment amount
   * @param {object} payment - Payment object
   * @param {Sale} sale - Sale object
   * @returns {number} Original payment amount
   */
  export function calcOriginalPaymentAmount(payment: any, sale: Sale): number;

  /**
   * Calculates given payment amount
   * @param {object} payment - Payment object
   * @param {Sale} sale - Sale object
   * @returns {number} Given payment amount
   */
  export function calcGivedPaymentAmount(payment: any, sale: Sale): number;

  /**
   * Calculates detailed payment information
   * @param {object} payment - Payment object
   * @param {Sale} sale - Sale object
   * @returns {PaymentCalculation} Payment details
   */
  export function calculatePaymentDetails(payment: any, sale: Sale): PaymentCalculation;

  /**
   * Gets applied wholesale levels
   * @param {Sale} sale - Sale object
   * @returns {WholesaleLevel[]} Applied wholesale levels
   */
  export function appliedWholesaleLevels(sale: any): WholesaleLevel[];

  /**
   * Calculates comprehensive sale totals
   * @param {Sale} sale - Sale object
   * @returns {SaleTotals} Sale totals
   */
  export function calculateSaleTotals(sale: any): SaleTotals;

  /**
   * Internal calculation methods (advanced use only)
   */
  export const _internals: {
    /**
     * Calculates sale product sum
     * @internal
     */
    calcDwSaleProductSum: (saleProduct: any, sale: Sale) => number;
    
    /**
     * Calculates sale product discount
     * @internal
     */
    calcDwSaleProductDiscount: (product: any, sale: Sale) => number;
    
    /**
     * Gets applicable product taxes
     * @internal
     */
    getApplicableProductTaxes: (saleProduct: any, productSum: number, sale: Sale) => number;
    
    /**
     * Currency exchange calculation
     * @internal
     */
    exchange: (amount: number, fromCurrency: string, toCurrency: string) => number;
  };

  /**
   * Calculates refund details for a sale
   * 
   * @param {Sale} sale - Original sale object
   * @param {SaleItem[]} returnItems - Items to return with quantity or refund amount
   * @param {RefundOptions} options - Refund calculation options
   * @param {string|number} [currentMemoId] - Current credit memo ID (for partial refunds)
   * 
   * @example
   * // Full item refund
   * calculateRefund(sale, returnItems, {
   *   input_type: 'items_full_refund',
   *   decimal_precision: 2
   * });
   * 
   * @example
   * // Amount-only refund
   * calculateRefund(sale, [], {
   *   input_type: 'amount_only',
   *   requested_refund_amount: 500,
   *   decimal_precision: 2
   * });
   * 
   * @returns {RefundCalculation} Refund calculation results
   */
  export function calculateRefund(
    sale: Sale,
    returnItems: SaleItem[],
    options: RefundOptions,
    currentMemoId?: string | number
  ): RefundCalculation;
}