package com.flightticket.service;

import com.flightticket.dto.modification.ModificationCost;
import com.flightticket.dto.modification.WalletImpact;
import com.flightticket.model.entity.Booking;
import com.flightticket.model.enums.ModificationType;

import java.math.BigDecimal;

/**
 * Service for calculating costs associated with booking modifications.
 * 
 * Requirements: 6.1, 6.2, 3.2
 */
public interface CostCalculationService {
    
    /**
     * Calculate the fare difference between original and new flight.
     * 
     * Formula: fareDifference = newFare - originalFare
     * - Positive value indicates fare increase
     * - Negative value indicates fare decrease
     * - Zero indicates no fare change
     * 
     * @param originalFare The original booking fare
     * @param newFare The new flight fare
     * @return The fare difference (can be positive, negative, or zero)
     * 
     * Requirements: 3.2
     * Property 11: Fare Difference Calculation
     */
    BigDecimal calculateFareDifference(BigDecimal originalFare, BigDecimal newFare);
    
    /**
     * Get the modification fee for a specific modification type.
     * This fee is typically retrieved from fare rules or airline policies.
     * 
     * @param booking The booking being modified
     * @param modificationType The type of modification
     * @return The modification fee (always non-negative)
     * 
     * Requirements: 6.1
     */
    BigDecimal getModificationFee(Booking booking, ModificationType modificationType);
    
    /**
     * Calculate the total cost of a modification.
     * 
     * Formula: totalCost = modificationFee + fareDifference
     * - Positive totalCost means wallet will be debited (customer pays)
     * - Negative totalCost means wallet will be credited (customer receives refund)
     * 
     * @param modificationFee The airline modification fee
     * @param fareDifference The fare difference (new - original)
     * @return The total modification cost
     * 
     * Requirements: 6.1
     * Property 9: Modification Cost Calculation
     */
    BigDecimal calculateTotalCost(BigDecimal modificationFee, BigDecimal fareDifference);
    
    /**
     * Calculate the complete modification cost including all details.
     * 
     * @param booking The original booking
     * @param newFare The new flight fare
     * @param modificationType The type of modification
     * @return Complete modification cost details
     * 
     * Requirements: 6.1, 6.2, 3.2
     */
    ModificationCost calculateModificationCost(
        Booking booking,
        BigDecimal newFare,
        ModificationType modificationType
    );
    
    /**
     * Calculate the wallet impact of a modification.
     * Determines whether the transaction will be a DEBIT or CREDIT,
     * and calculates the new balance.
     * 
     * For DEBIT transactions (totalCost > 0):
     * - Checks if wallet has sufficient balance
     * - Calculates shortfall if insufficient
     * 
     * For CREDIT transactions (totalCost < 0):
     * - Always sufficient (adding money to wallet)
     * 
     * @param currentBalance The current wallet balance
     * @param modificationCost The modification cost details
     * @return Wallet impact details including transaction type and new balance
     * 
     * Requirements: 6.2, 6.3, 6.4
     * Property 10: Credit Calculation for Fare Decreases
     * Property 12: Wallet Balance Validation Before Processing
     * Property 13: Insufficient Balance Handling
     */
    WalletImpact calculateWalletImpact(BigDecimal currentBalance, ModificationCost modificationCost);
}
