use bpx_api_types::order::{Side, TimeInForce};
use ratatui::layout::{Constraint, Direction, Layout, Rect};
use ratatui::text::{Line, Span};
use ratatui::widgets::{Block, Borders, Clear, Paragraph};
use ratatui::Frame;

use crate::tui::app::{AppState, OrderFormField, OrderFormState};
use crate::tui::theme;

pub fn render(f: &mut Frame, area: Rect, form: &OrderFormState, state: &AppState) {
    let popup = centered_rect(40, 55, area);
    f.render_widget(Clear, popup);

    let is_buy = form.side == Side::Bid;
    let side_label = if is_buy { "BUY" } else { "SELL" };
    let order_type = if form.price_input.is_empty() {
        "Market"
    } else {
        "Limit"
    };
    let title = format!(" {side_label} {} [{order_type}] ", form.symbol);
    let title_style = if is_buy { theme::bid() } else { theme::ask() };

    let block = Block::default()
        .title(title)
        .title_style(title_style)
        .borders(Borders::ALL)
        .border_style(ratatui::style::Style::default().fg(theme::BORDER_FOCUS))
        .style(ratatui::style::Style::default().bg(theme::SURFACE));

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

    let active = form.active_field;
    let indicator = |field: OrderFormField| -> &str {
        if active == field {
            ">"
        } else {
            " "
        }
    };

    let side_display = if is_buy { "BUY" } else { "SELL" };
    let side_style = if is_buy { theme::bid() } else { theme::ask() };

    let tif_display = match form.time_in_force {
        TimeInForce::GTC => "GTC",
        TimeInForce::IOC => "IOC",
        TimeInForce::FOK => "FOK",
    };

    let checkbox = |checked: bool| -> &str {
        if checked {
            "[x]"
        } else {
            "[ ]"
        }
    };

    let price_display = if form.price_input.is_empty() {
        "(market)"
    } else {
        &form.price_input
    };

    let cursor = |field: OrderFormField| -> &str {
        if active == field {
            "\u{2588}"
        } else {
            ""
        }
    };

    let field_style = |field: OrderFormField| -> ratatui::style::Style {
        if active == field {
            theme::highlight()
        } else {
            theme::normal()
        }
    };

    // Calculate available balance for size presets
    let available_usdc: f64 = state
        .balances
        .get("USDC")
        .and_then(|v| {
            v.get("available")
                .and_then(|x| x.as_str())
                .and_then(|s| s.parse().ok())
        })
        .unwrap_or(0.0);

    // Get current price for notional calculation
    let ref_price: f64 = if !form.price_input.is_empty() {
        form.price_input.parse().unwrap_or(0.0)
    } else {
        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)
    };

    let mut lines = vec![
        Line::from(""),
        // Side
        Line::from(vec![
            Span::styled(
                format!(" {} Side:    ", indicator(OrderFormField::Side)),
                field_style(OrderFormField::Side),
            ),
            Span::styled(side_display, side_style),
        ]),
        // Price
        Line::from(vec![
            Span::styled(
                format!(" {} Price:   ", indicator(OrderFormField::Price)),
                field_style(OrderFormField::Price),
            ),
            Span::styled(price_display, theme::normal()),
            Span::styled(cursor(OrderFormField::Price), theme::highlight()),
        ]),
        // Quantity
        Line::from(vec![
            Span::styled(
                format!(" {} Qty:     ", indicator(OrderFormField::Quantity)),
                field_style(OrderFormField::Quantity),
            ),
            Span::styled(&form.quantity_input, theme::normal()),
            Span::styled(cursor(OrderFormField::Quantity), theme::highlight()),
        ]),
    ];

    // Quick size presets — show when Qty field is active and we have price+balance
    if active == OrderFormField::Quantity && ref_price > 0.0 && available_usdc > 0.0 {
        let mut preset_spans = vec![Span::styled("   Size: ", theme::dim())];
        for (key, pct) in [("1", 0.25), ("2", 0.50), ("3", 0.75), ("4", 1.00)] {
            let notional = available_usdc * pct;
            let qty = notional / ref_price;
            preset_spans.push(Span::styled(key, theme::highlight()));
            preset_spans.push(Span::styled(format!("={:.0}% ", pct * 100.0), theme::dim()));
            let _ = qty; // displayed via the key hint
        }
        lines.push(Line::from(preset_spans));
    } else {
        lines.push(Line::from(""));
    }

    // Post-only
    lines.push(Line::from(vec![Span::styled(
        format!(
            " {} {} Post-only",
            indicator(OrderFormField::PostOnly),
            checkbox(form.post_only)
        ),
        field_style(OrderFormField::PostOnly),
    )]));
    // TIF
    lines.push(Line::from(vec![
        Span::styled(
            format!(" {} TIF:     ", indicator(OrderFormField::TimeInForce)),
            field_style(OrderFormField::TimeInForce),
        ),
        Span::styled(tif_display, theme::normal()),
    ]));
    // Reduce-only
    lines.push(Line::from(vec![Span::styled(
        format!(
            " {} {} Reduce-only",
            indicator(OrderFormField::ReduceOnly),
            checkbox(form.reduce_only)
        ),
        field_style(OrderFormField::ReduceOnly),
    )]));

    // Error message
    if let Some(ref err) = form.error_message {
        lines.push(Line::from(""));
        lines.push(Line::from(Span::styled(
            format!("  \u{2717} {err}"),
            theme::status_err(),
        )));
    }

    // Notional value hint
    if !form.quantity_input.is_empty() && ref_price > 0.0 {
        if let Ok(qty) = form.quantity_input.parse::<f64>() {
            let notional = qty * ref_price;
            lines.push(Line::from(Span::styled(
                format!("  \u{2248} ${notional:.2} notional"),
                theme::dim(),
            )));
        }
    }

    lines.push(Line::from(""));
    lines.push(Line::from(vec![
        Span::styled("  Tab", theme::highlight()),
        Span::styled(" fields  ", theme::dim()),
        Span::styled("Enter", theme::highlight()),
        Span::styled(" submit  ", theme::dim()),
        Span::styled("1-4", theme::highlight()),
        Span::styled(" 25-100%", theme::dim()),
    ]));
    lines.push(Line::from(vec![
        Span::styled("  Esc", theme::highlight()),
        Span::styled(" cancel  ", theme::dim()),
        Span::styled("Space", theme::highlight()),
        Span::styled(" toggle", theme::dim()),
    ]));

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

fn centered_rect(percent_x: u16, percent_y: u16, r: Rect) -> Rect {
    let popup_layout = Layout::default()
        .direction(Direction::Vertical)
        .constraints([
            Constraint::Percentage((100 - percent_y) / 2),
            Constraint::Percentage(percent_y),
            Constraint::Percentage((100 - percent_y) / 2),
        ])
        .split(r);

    Layout::default()
        .direction(Direction::Horizontal)
        .constraints([
            Constraint::Percentage((100 - percent_x) / 2),
            Constraint::Percentage(percent_x),
            Constraint::Percentage((100 - percent_x) / 2),
        ])
        .split(popup_layout[1])[1]
}
