use serde::{Deserialize, Serialize};

use crate::orchestrator::FeeConfig;

/// Whether a fill is classified as maker or taker for fee calculation.
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub enum FillType {
    Maker,
    #[default]
    Taker,
}

pub fn compute_fees(quantity: f64, price: f64, config: &FeeConfig, fill_type: FillType) -> f64 {
    let notional = quantity.abs() * price;
    let fee_rate = match fill_type {
        FillType::Maker => config.maker_fee_bps / 10_000.0,
        FillType::Taker => config.taker_fee_bps / 10_000.0,
    };
    (notional * fee_rate).max(config.min_fee)
}

pub fn funding_pnl(position: f64, close_price: f64, funding_rate: f64) -> f64 {
    -position * close_price * funding_rate
}

pub fn borrow_cost(
    position: f64,
    close_price: f64,
    borrow_rate_annual_bps: f64,
    bar_seconds: f64,
) -> f64 {
    if position >= 0.0 {
        return 0.0;
    }

    let borrow_rate = borrow_rate_annual_bps / 10_000.0;
    position.abs() * close_price * borrow_rate * (bar_seconds / (365.25 * 86_400.0))
}
