use bpx_api_types::rfq::{Quote, RequestForQuote};
use tabled::settings::Style;
use tabled::{Table, Tabled};

use crate::output::OutputFormat;

#[derive(Tabled)]
struct RfqRow {
    #[tabled(rename = "RFQ ID")]
    rfq_id: String,
    #[tabled(rename = "SYMBOL")]
    symbol: String,
    #[tabled(rename = "SIDE")]
    side: String,
    #[tabled(rename = "QTY")]
    quantity: String,
    #[tabled(rename = "STATUS")]
    status: String,
    #[tabled(rename = "PRICE")]
    price: String,
    #[tabled(rename = "MODE")]
    mode: String,
    #[tabled(rename = "EXPIRES")]
    expiry_time: String,
    #[tabled(rename = "CREATED")]
    created: String,
}

pub fn print_rfq(rfq: &RequestForQuote, format: OutputFormat) {
    match format {
        OutputFormat::Json => super::print_json(rfq),
        OutputFormat::Table => {
            let rows = vec![rfq_to_row(rfq)];
            let mut table = Table::new(rows);
            table.with(Style::blank());
            println!("{table}");
        }
    }
}

fn rfq_to_row(rfq: &RequestForQuote) -> RfqRow {
    RfqRow {
        rfq_id: rfq.rfq_id.clone(),
        symbol: rfq.symbol.clone(),
        side: super::display_side(&rfq.side).to_string(),
        quantity: rfq
            .quantity
            .map(|q| q.to_string())
            .unwrap_or_else(|| "-".to_string()),
        status: format!("{}", rfq.status),
        price: rfq
            .price
            .map(|p| p.to_string())
            .unwrap_or_else(|| "-".to_string()),
        mode: format!("{}", rfq.execution_mode),
        expiry_time: super::format_ts_ms(rfq.expiry_time),
        created: super::format_ts_ms(rfq.created_at),
    }
}

#[derive(Tabled)]
struct QuoteRow {
    #[tabled(rename = "QUOTE ID")]
    quote_id: String,
    #[tabled(rename = "RFQ ID")]
    rfq_id: String,
    #[tabled(rename = "BID")]
    bid_price: String,
    #[tabled(rename = "ASK")]
    ask_price: String,
    #[tabled(rename = "STATUS")]
    status: String,
    #[tabled(rename = "CREATED")]
    created: String,
}

pub fn print_quote(quote: &Quote, format: OutputFormat) {
    match format {
        OutputFormat::Json => super::print_json(quote),
        OutputFormat::Table => {
            let rows = vec![QuoteRow {
                quote_id: quote.quote_id.clone(),
                rfq_id: quote.rfq_id.clone(),
                bid_price: quote.bid_price.to_string(),
                ask_price: quote.ask_price.to_string(),
                status: format!("{}", quote.status),
                created: super::format_ts_ms(quote.created_at),
            }];
            let mut table = Table::new(rows);
            table.with(Style::blank());
            println!("{table}");
        }
    }
}
