use crate::app::{AppState, GatewayOption, OperationMode};
/// Setup Portal Screen - Clean Architecture
/// Gateway connection setup wizard with three options:
/// - Local Bundle (localhost:3001)
/// - 4Runr Server (cloud, coming soon)
/// - Custom URL (user's own gateway)
use ratatui::prelude::*;
use ratatui::widgets::{Block, Borders, Clear, List, ListItem, Paragraph, Wrap};

// === BRAND COLORS ===
const BRAND_PURPLE: Color = Color::Rgb(138, 43, 226);
const CYBER_CYAN: Color = Color::Rgb(0, 255, 255);
const NEON_GREEN: Color = Color::Rgb(57, 255, 20);
const AMBER_WARN: Color = Color::Rgb(255, 191, 0);
const TEXT_PRIMARY: Color = Color::Rgb(230, 230, 240);
const TEXT_DIM: Color = Color::Rgb(100, 100, 120);
const TEXT_MUTED: Color = Color::Rgb(60, 60, 80);
const BG_PANEL: Color = Color::Rgb(18, 18, 25);
const ERROR_RED: Color = Color::Rgb(255, 69, 69);

/// Main render entry point
/// This is called from main.rs after terminal.clear() and autoresize()
pub fn render(f: &mut Frame, state: &mut AppState) {
    let area = f.size();

    // Validate terminal size
    if area.width == 0 || area.height == 0 {
        return; // Invalid terminal state, skip frame
    }

    if area.width < 85 || area.height < 25 {
        render_too_small(f, area);
        return;
    }

    // Full-screen clear (already done in main.rs, but ensure it's clean)
    f.render_widget(Clear, area);

    // Background
    let bg = Block::default().style(Style::default().bg(BG_PANEL));
    f.render_widget(bg, area);

    // Center portal dialog
    let portal_width = area.width.min(110).max(85);
    let portal_height = area.height.min(38).max(25);
    let portal_x = area.width.saturating_sub(portal_width) / 2;
    let portal_y = area.height.saturating_sub(portal_height) / 2;

    let portal_rect = Rect {
        x: portal_x,
        y: portal_y,
        width: portal_width,
        height: portal_height,
    };

    let show_link_banner =
        matches!(state.operation_mode, OperationMode::Connected) && state.gateway_url.is_some();
    // Layout: Header | Description | Content | Error (optional) | Actions
    let sections = build_layout(
        portal_rect,
        state.setup_portal.error.is_some(),
        show_link_banner,
    );

    render_header(f, sections.header, state);
    render_description(f, sections.description, state);
    render_content(f, sections.content, state);

    if let Some(error_rect) = sections.error {
        render_error_box(f, error_rect, state);
    }

    render_actions(f, sections.actions, state);
}

/// Layout structure for all portal sections
struct PortalLayout {
    header: Rect,
    description: Rect,
    content: Rect,
    error: Option<Rect>,
    actions: Rect,
}

/// Build vertical layout with dynamic error section
fn build_layout(area: Rect, has_error: bool, show_link_banner: bool) -> PortalLayout {
    use ratatui::layout::{Constraint, Direction, Layout};

    let desc_h = if show_link_banner { 5u16 } else { 3u16 };
    let constraints = if has_error {
        vec![
            Constraint::Length(3),      // Header
            Constraint::Length(desc_h), // Description (+ linked banner)
            Constraint::Min(11),        // Content
            Constraint::Length(6),      // Error
            Constraint::Length(3),      // Actions
        ]
    } else {
        vec![
            Constraint::Length(3),      // Header
            Constraint::Length(desc_h), // Description
            Constraint::Min(13),        // Content
            Constraint::Length(3),      // Actions
        ]
    };

    let chunks = Layout::default()
        .direction(Direction::Vertical)
        .constraints(constraints)
        .split(area);

    if has_error {
        PortalLayout {
            header: chunks[0],
            description: chunks[1],
            content: chunks[2],
            error: Some(chunks[3]),
            actions: chunks[4],
        }
    } else {
        PortalLayout {
            header: chunks[0],
            description: chunks[1],
            content: chunks[2],
            error: None,
            actions: chunks[3],
        }
    }
}

// === SECTION RENDERERS ===

fn render_header(f: &mut Frame, area: Rect, state: &AppState) {
    let linked =
        matches!(state.operation_mode, OperationMode::Connected) && state.gateway_url.is_some();
    let title = if state.setup_portal.error.is_some() {
        " ⚙ Gateway Setup — Error "
    } else if state.setup_portal.detecting && state.setup_portal.detection_result.is_none() {
        " ⚙ Gateway Setup — Scanning… "
    } else if state.setup_portal.detecting {
        " ⚙ Gateway Setup — Refreshing… "
    } else if linked {
        " ⚙ Gateway Setup — Linked "
    } else {
        " ⚙ Gateway Setup "
    };

    let border_color = if state.setup_portal.error.is_some() {
        ERROR_RED
    } else {
        BRAND_PURPLE
    };

    let block = Block::default()
        .title(title)
        .borders(Borders::ALL)
        .border_style(Style::default().fg(border_color).bold())
        .style(Style::default().bg(BG_PANEL));

    f.render_widget(block, area);
}

fn render_description(f: &mut Frame, area: Rect, state: &AppState) {
    let block = Block::default()
        .borders(Borders::LEFT | Borders::RIGHT)
        .style(Style::default().bg(BG_PANEL));

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

    let mut s = String::from("Choose how you want to connect to a Gateway server.");
    if matches!(state.operation_mode, OperationMode::Connected) {
        if let Some(ref u) = state.gateway_url {
            s.push('\n');
            s.push_str("✓ CLI is linked to: ");
            s.push_str(u);
            s.push_str("\n  Use Connection Portal (Enter) to change URL; disconnect from Main.");
        }
    }
    let text = Paragraph::new(s)
        .style(Style::default().fg(TEXT_DIM).bg(BG_PANEL))
        .wrap(Wrap { trim: true })
        .alignment(ratatui::layout::Alignment::Center);

    f.render_widget(text, inner);
}

fn render_content(f: &mut Frame, area: Rect, state: &mut AppState) {
    use ratatui::layout::{Constraint, Direction, Layout};

    let left_w = (area.width.saturating_mul(38) / 100).clamp(28, 44);
    let chunks = Layout::default()
        .direction(Direction::Horizontal)
        .constraints([Constraint::Length(left_w), Constraint::Min(22)])
        .split(area);

    render_options_list(f, chunks[0], state);
    render_details_panel(f, chunks[1], state);
}

fn render_options_list(f: &mut Frame, area: Rect, state: &mut AppState) {
    // Clear to prevent artifacts
    f.render_widget(Clear, area);

    let options = [
        ("Local Bundle", GatewayOption::LocalBundle),
        ("4Runr Server", GatewayOption::CloudServer),
        ("Custom URL", GatewayOption::CustomUrl),
    ];

    let selected = &state.setup_portal.selected_option;

    let items: Vec<ListItem> = options
        .iter()
        .map(|(name, option)| {
            let is_selected = selected == option;
            let style = if is_selected {
                Style::default().fg(CYBER_CYAN).bold()
            } else {
                Style::default().fg(TEXT_MUTED)
            };

            let icon = get_option_icon(option);
            let prefix = if is_selected { "► " } else { "  " };
            let text = format!("{}{} {}", prefix, icon, name);

            ListItem::new(text).style(style)
        })
        .collect();

    let block = Block::default()
        .borders(Borders::ALL)
        .title(" Gateway Options ")
        .border_style(Style::default().fg(CYBER_CYAN))
        .style(Style::default().bg(BG_PANEL));

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

    // Background fill
    let fill = Block::default().style(Style::default().bg(BG_PANEL));
    f.render_widget(fill, inner);

    // Stateless list (selection shown via prefix and color)
    let list = List::new(items).style(Style::default().bg(BG_PANEL));
    f.render_widget(list, inner);
}

fn render_details_panel(f: &mut Frame, area: Rect, state: &AppState) {
    // Clear to prevent ghost text
    f.render_widget(Clear, area);

    let selected = &state.setup_portal.selected_option;
    let detection = &state.setup_portal.detection_result;

    let (title, lines) = build_details_content(selected, detection);

    let block = Block::default()
        .title(title)
        .borders(Borders::ALL)
        .border_style(Style::default().fg(TEXT_DIM))
        .style(Style::default().bg(BG_PANEL));

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

    // Validate inner area
    if inner.width == 0 || inner.height == 0 {
        return;
    }

    // Pad content to fill height (prevents ghost text from previous selection)
    let mut padded_lines = lines;
    while padded_lines.len() < inner.height as usize {
        padded_lines.push(Line::from(""));
    }

    // Background fill + content
    let fill = Block::default().style(Style::default().bg(BG_PANEL));
    f.render_widget(fill, inner);

    let paragraph = Paragraph::new(padded_lines)
        .wrap(Wrap { trim: true })
        .style(Style::default().bg(BG_PANEL));

    f.render_widget(paragraph, inner);
}

fn render_error_box(f: &mut Frame, area: Rect, state: &AppState) {
    if let Some(error) = &state.setup_portal.error {
        let block = Block::default()
            .title(" [✗] ERROR ")
            .borders(Borders::ALL)
            .border_style(Style::default().fg(ERROR_RED).bold())
            .style(Style::default().bg(BG_PANEL));

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

        let text = vec![
            Line::from(""),
            Line::from(Span::styled(
                format!("  {}", error),
                Style::default().fg(TEXT_PRIMARY),
            )),
            Line::from(""),
        ];

        let paragraph = Paragraph::new(text).wrap(Wrap { trim: true });
        f.render_widget(paragraph, inner);
    }
}

fn render_actions(f: &mut Frame, area: Rect, state: &AppState) {
    let block = Block::default()
        .borders(Borders::ALL)
        .border_style(Style::default().fg(TEXT_DIM))
        .style(Style::default().bg(BG_PANEL));

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

    let text = if state.setup_portal.detecting && state.setup_portal.detection_result.is_none() {
        Line::from(vec![Span::styled(
            "Scanning Gateway options… (first load)",
            Style::default().fg(AMBER_WARN),
        )])
    } else if state.setup_portal.detecting {
        Line::from(vec![
            Span::styled("Refreshing catalog…  ", Style::default().fg(AMBER_WARN)),
            Span::styled("↑↓", Style::default().fg(CYBER_CYAN).bold()),
            Span::styled(" change row  │  ", Style::default().fg(TEXT_DIM)),
            Span::styled("Enter", Style::default().fg(NEON_GREEN).bold()),
            Span::styled(" Connection Portal", Style::default().fg(TEXT_DIM)),
        ])
    } else {
        Line::from(vec![
            Span::styled("↑↓", Style::default().fg(CYBER_CYAN).bold()),
            Span::styled(" Navigate  │  ", Style::default().fg(TEXT_DIM)),
            Span::styled("Enter", Style::default().fg(NEON_GREEN).bold()),
            Span::styled(" Continue  │  ", Style::default().fg(TEXT_DIM)),
            Span::styled("ESC", Style::default().fg(BRAND_PURPLE).bold()),
            Span::styled(" Cancel", Style::default().fg(TEXT_DIM)),
        ])
    };

    let paragraph = Paragraph::new(text)
        .alignment(ratatui::layout::Alignment::Center)
        .style(Style::default().bg(BG_PANEL));

    f.render_widget(paragraph, inner);
}

fn render_too_small(f: &mut Frame, area: Rect) {
    f.render_widget(Clear, area);

    let bg = Block::default().style(Style::default().bg(BG_PANEL));
    f.render_widget(bg, area);

    let msg = vec![
        Line::from(""),
        Line::from(Span::styled(
            "Setup Portal",
            Style::default().fg(BRAND_PURPLE).bold(),
        )),
        Line::from(""),
        Line::from(Span::styled(
            "Terminal too small",
            Style::default().fg(ERROR_RED),
        )),
        Line::from(""),
        Line::from(Span::styled(
            format!("Current: {}x{}", area.width, area.height),
            Style::default().fg(TEXT_DIM),
        )),
        Line::from(Span::styled(
            "Required: 85x25",
            Style::default().fg(TEXT_PRIMARY),
        )),
    ];

    let paragraph = Paragraph::new(msg).alignment(ratatui::layout::Alignment::Center);

    f.render_widget(
        paragraph,
        Rect {
            x: area.x,
            y: area.y + (area.height / 3),
            width: area.width,
            height: area.height / 3,
        },
    );
}

// === HELPER FUNCTIONS ===

fn get_option_icon(option: &GatewayOption) -> &'static str {
    match option {
        GatewayOption::LocalBundle => "[■]",
        GatewayOption::CloudServer => "[≡]",
        GatewayOption::CustomUrl => "[◆]",
    }
}

fn build_details_content(
    option: &GatewayOption,
    detection: &Option<crate::app::DetectionResult>,
) -> (&'static str, Vec<Line<'static>>) {
    match option {
        GatewayOption::LocalBundle => build_local_bundle_details(detection),
        GatewayOption::CloudServer => build_cloud_server_details(),
        GatewayOption::CustomUrl => build_custom_url_details(),
    }
}

fn build_local_bundle_details(
    detection: &Option<crate::app::DetectionResult>,
) -> (&'static str, Vec<Line<'static>>) {
    let mut lines = vec![
        Line::from(""),
        Line::from(Span::styled(
            "Local Bundle Gateway",
            Style::default().fg(NEON_GREEN).bold(),
        )),
        Line::from(Span::styled(
            "Runs on your machine",
            Style::default().fg(TEXT_DIM),
        )),
        Line::from(""),
    ];

    if let Some(result) = detection {
        if result.local_bundle.running {
            lines.extend(vec![
                Line::from(vec![
                    Span::styled("[✓] ", Style::default().fg(NEON_GREEN)),
                    Span::styled("Running at ", Style::default().fg(TEXT_PRIMARY)),
                    Span::styled("localhost:3001", Style::default().fg(CYBER_CYAN)),
                ]),
                Line::from(""),
                Line::from(Span::styled(
                    "Press Enter to connect",
                    Style::default().fg(CYBER_CYAN),
                )),
            ]);
        } else if result.local_bundle.available {
            lines.extend(vec![
                Line::from(vec![
                    Span::styled("[!] ", Style::default().fg(AMBER_WARN)),
                    Span::styled("Found but not running", Style::default().fg(AMBER_WARN)),
                ]),
                Line::from(""),
                Line::from(Span::styled("Start with:", Style::default().fg(TEXT_DIM))),
                Line::from(Span::styled(
                    "  cd apps/gateway && pnpm start",
                    Style::default().fg(NEON_GREEN),
                )),
                Line::from(""),
                Line::from(Span::styled(
                    "Then press F2 to reconnect",
                    Style::default().fg(CYBER_CYAN),
                )),
            ]);
        } else {
            lines.extend(vec![
                Line::from(vec![
                    Span::styled("[✗] ", Style::default().fg(ERROR_RED)),
                    Span::styled("Bundle not found", Style::default().fg(ERROR_RED)),
                ]),
                Line::from(""),
                Line::from(Span::styled(
                    "Try 4Runr Server or Custom URL",
                    Style::default().fg(TEXT_DIM),
                )),
            ]);
        }
    } else {
        lines.push(Line::from(Span::styled(
            "Press Enter to connect",
            Style::default().fg(CYBER_CYAN),
        )));
    }

    (" [■] Local Bundle ", lines)
}

fn build_cloud_server_details() -> (&'static str, Vec<Line<'static>>) {
    let lines = vec![
        Line::from(""),
        Line::from(Span::styled(
            "4Runr Cloud Server",
            Style::default().fg(NEON_GREEN).bold(),
        )),
        Line::from(Span::styled(
            "Managed cloud hosting",
            Style::default().fg(TEXT_DIM),
        )),
        Line::from(""),
        Line::from(vec![
            Span::styled("[!] ", Style::default().fg(AMBER_WARN)),
            Span::styled("Coming Soon", Style::default().fg(AMBER_WARN).bold()),
        ]),
        Line::from(""),
        Line::from(Span::styled(
            "Service not yet available",
            Style::default().fg(TEXT_DIM),
        )),
        Line::from(""),
        Line::from(Span::styled(
            "Use Local Bundle or Custom URL",
            Style::default().fg(CYBER_CYAN),
        )),
    ];

    (" [≡] 4Runr Server ", lines)
}

fn build_custom_url_details() -> (&'static str, Vec<Line<'static>>) {
    let lines = vec![
        Line::from(""),
        Line::from(Span::styled(
            "Custom Gateway Server",
            Style::default().fg(NEON_GREEN).bold(),
        )),
        Line::from(Span::styled(
            "Your own deployment",
            Style::default().fg(TEXT_DIM),
        )),
        Line::from(""),
        Line::from(Span::styled("Requirements:", Style::default().fg(TEXT_DIM))),
        Line::from(Span::styled(
            "  • Running Gateway server",
            Style::default().fg(TEXT_DIM),
        )),
        Line::from(Span::styled(
            "  • Accessible URL (http:// or https://)",
            Style::default().fg(TEXT_DIM),
        )),
        Line::from(""),
        Line::from(Span::styled(
            "Press Enter to continue",
            Style::default().fg(CYBER_CYAN),
        )),
    ];

    (" [◆] Custom URL ", lines)
}
