use ratatui::layout::Rect;
use ratatui::text::{Line, Span};
use ratatui::widgets::Paragraph;
use ratatui::Frame;

use crate::tui::app::{AppState, Panel};
use crate::tui::theme;

pub fn render(f: &mut Frame, area: Rect, state: &AppState) {
    let active = state.active_panel == Panel::Orders;
    let count = state.open_orders.len();
    let base_title = if active && state.authenticated && count > 0 {
        "Open Orders  d cancel"
    } else {
        "Open Orders"
    };
    let info = if count > 0 {
        let scroll = state.scroll_offset(Panel::Orders);
        if scroll > 0 {
            format!("({}/{count})", scroll + 1)
        } else {
            format!("({count})")
        }
    } else {
        String::new()
    };
    let block = theme::panel_block_with_info(base_title, &info, active);

    let inner = block.inner(area);
    f.render_widget(block, area);

    let mut lines = Vec::new();

    if !state.authenticated {
        lines.push(Line::from(Span::styled(
            "  Not authenticated \u{2014} run `bpx setup`",
            theme::dim(),
        )));
        let paragraph = Paragraph::new(lines);
        f.render_widget(paragraph, inner);
        return;
    }

    if state.open_orders.is_empty() {
        lines.push(Line::from(Span::styled(
            "  No open orders \u{2014} press o to place",
            theme::dim(),
        )));
        let paragraph = Paragraph::new(lines);
        f.render_widget(paragraph, inner);
        return;
    }

    // Get current price for distance calculation
    let current_price: f64 = state
        .ticker
        .as_ref()
        .and_then(|t| t.get("lastPrice").or_else(|| t.get("c")))
        .and_then(|v| v.as_str())
        .and_then(|s| s.parse().ok())
        .unwrap_or(0.0);

    // Header
    lines.push(Line::from(vec![
        Span::styled("  ", theme::header()),
        Span::styled(format!("{:>4}", "SIDE"), theme::header()),
        Span::styled(" ", theme::normal()),
        Span::styled(format!("{:<10}", "SYMBOL"), theme::header()),
        Span::styled(" ", theme::normal()),
        Span::styled(format!("{:>10}", "PRICE"), theme::header()),
        Span::styled(" ", theme::normal()),
        Span::styled(format!("{:>6}", "DIST"), theme::header()),
        Span::styled(" ", theme::normal()),
        Span::styled(format!("{:>8}", "QTY"), theme::header()),
        Span::styled(" ", theme::normal()),
        Span::styled(format!("{:>6}", "FILLED"), theme::header()),
    ]));

    let max_rows = (inner.height as usize).saturating_sub(1);
    let scroll = state.scroll_offset(Panel::Orders);

    for (i, order) in state
        .open_orders
        .iter()
        .skip(scroll)
        .take(max_rows)
        .enumerate()
    {
        let side = order
            .get("side")
            .or_else(|| order.get("S"))
            .and_then(|v| v.as_str())
            .unwrap_or("-");
        let symbol = order
            .get("symbol")
            .or_else(|| order.get("s"))
            .and_then(|v| v.as_str())
            .unwrap_or("-");
        let display_sym = symbol.replace("_USDC_PERP", "_PP").replace("_USDC", "");
        let price = order
            .get("price")
            .or_else(|| order.get("p"))
            .and_then(|v| v.as_str())
            .unwrap_or("-");
        let qty = order
            .get("quantity")
            .or_else(|| order.get("q"))
            .and_then(|v| v.as_str())
            .unwrap_or("-");
        let filled = order
            .get("executedQuantity")
            .or_else(|| order.get("z"))
            .and_then(|v| v.as_str())
            .unwrap_or("0");

        let is_buy = side == "Bid" || side == "BUY" || side == "Buy";
        let side_style = if is_buy { theme::bid() } else { theme::ask() };
        let side_label = if is_buy { "BUY" } else { "SELL" };

        // Distance from current price
        let order_price: f64 = price.parse().unwrap_or(0.0);
        let dist_str = if current_price > 0.0 && order_price > 0.0 {
            let dist_pct = ((order_price - current_price) / current_price) * 100.0;
            format!("{:+.1}%", dist_pct)
        } else {
            "-".to_string()
        };
        let dist_style = if order_price > current_price {
            theme::bid()
        } else {
            theme::ask()
        };

        // Row indicator — show > on the selected (first visible) row when panel is active
        let indicator = if active && i == 0 { ">" } else { " " };

        // Alternating row background
        let bg = if i % 2 == 0 {
            theme::BG
        } else {
            theme::SURFACE_ALT
        };
        let row_style = ratatui::style::Style::default().bg(bg);

        lines.push(
            Line::from(vec![
                Span::styled(format!("{indicator} "), theme::highlight().bg(bg)),
                Span::styled(format!("{side_label:>4}"), side_style.bg(bg)),
                Span::styled(" ", row_style),
                Span::styled(format!("{display_sym:<10}"), theme::normal().bg(bg)),
                Span::styled(" ", row_style),
                Span::styled(format!("{price:>10}"), theme::normal().bg(bg)),
                Span::styled(" ", row_style),
                Span::styled(format!("{:>6}", dist_str), dist_style.bg(bg)),
                Span::styled(" ", row_style),
                Span::styled(format!("{qty:>8}"), theme::normal().bg(bg)),
                Span::styled(" ", row_style),
                Span::styled(format!("{filled:>6}"), theme::secondary().bg(bg)),
            ])
            .style(row_style),
        );
    }

    let paragraph = Paragraph::new(lines);
    f.render_widget(paragraph, inner);
}
