//! Agent Pane: scrollable message list + prompt input.
//!
//! Shows user/assistant messages with different styling, tool call blocks,
//! status indicator, and a prompt input field at the bottom.

use gpui::*;

use crate::state::{AgentMessage, AgentSession, AgentStatus, MessageRole};
use crate::theme;

// ── Status Dot ──────────────────────────────────────────────────────

fn status_dot(status: AgentStatus) -> Div {
    let color = match status {
        AgentStatus::Idle => theme::OVERLAY0,
        AgentStatus::Running => theme::GREEN,
        AgentStatus::Done => theme::BLUE,
        AgentStatus::Error => theme::RED,
    };

    div()
        .w(px(8.0))
        .h(px(8.0))
        .rounded(px(4.0))
        .bg(color)
}

fn status_label(status: AgentStatus) -> &'static str {
    match status {
        AgentStatus::Idle => "Idle",
        AgentStatus::Running => "Running",
        AgentStatus::Done => "Done",
        AgentStatus::Error => "Error",
    }
}

// ── Message Bubble ──────────────────────────────────────────────────

fn render_message(msg: &AgentMessage) -> Div {
    let (bg, text_col) = match msg.role {
        MessageRole::User => (theme::SURFACE0, theme::TEXT),
        MessageRole::Assistant => (theme::with_alpha(theme::BLUE, 0.08), theme::TEXT),
        MessageRole::System => (theme::with_alpha(theme::MAUVE, 0.08), theme::SUBTEXT0),
    };

    let role_label = match msg.role {
        MessageRole::User => "You",
        MessageRole::Assistant => "Claude",
        MessageRole::System => "System",
    };

    let mut bubble = div()
        .max_w(rems(40.0))
        .rounded(px(8.0))
        .bg(bg)
        .px(px(12.0))
        .py(px(8.0))
        .flex()
        .flex_col()
        .gap(px(4.0));

    // Role label
    bubble = bubble.child(
        div()
            .text_size(px(11.0))
            .text_color(theme::OVERLAY1)
            .child(role_label.to_string()),
    );

    // Tool call indicator
    if let Some(ref tool_name) = msg.tool_name {
        bubble = bubble.child(
            div()
                .flex()
                .flex_row()
                .items_center()
                .gap(px(4.0))
                .px(px(6.0))
                .py(px(2.0))
                .rounded(px(4.0))
                .bg(theme::with_alpha(theme::PEACH, 0.12))
                .text_size(px(11.0))
                .text_color(theme::PEACH)
                .child(format!("\u{2699} {tool_name}")),
        );
    }

    // Content
    bubble = bubble.child(
        div()
            .text_size(px(13.0))
            .text_color(text_col)
            .child(msg.content.clone()),
    );

    // Tool result
    if let Some(ref result) = msg.tool_result {
        let truncated = if result.len() > 300 {
            format!("{}...", &result[..300])
        } else {
            result.clone()
        };
        bubble = bubble.child(
            div()
                .mt(px(4.0))
                .px(px(8.0))
                .py(px(6.0))
                .rounded(px(4.0))
                .bg(theme::MANTLE)
                .text_size(px(11.0))
                .text_color(theme::SUBTEXT0)
                .font_family("JetBrains Mono")
                .child(truncated),
        );
    }

    // Wrap in a row for alignment
    let mut row = div().w_full().flex();

    match msg.role {
        MessageRole::User => {
            // Push bubble to the right
            row = row
                .child(div().flex_1())
                .child(bubble);
        }
        _ => {
            // Push bubble to the left
            row = row
                .child(bubble)
                .child(div().flex_1());
        }
    }

    row
}

// ── Agent Pane View ─────────────────────────────────────────────────

pub struct AgentPane {
    pub session: AgentSession,
    pub prompt_text: String,
}

impl AgentPane {
    pub fn new(session: AgentSession) -> Self {
        Self {
            session,
            prompt_text: String::new(),
        }
    }

    /// Create a pane pre-populated with demo messages for visual testing.
    pub fn with_demo_messages() -> Self {
        let messages = vec![
            AgentMessage {
                id: "1".into(),
                role: MessageRole::User,
                content: "Add error handling to the PTY spawn function. It should log failures and return a Result.".into(),
                timestamp: 1710000000,
                tool_name: None,
                tool_result: None,
                collapsed: false,
            },
            AgentMessage {
                id: "2".into(),
                role: MessageRole::Assistant,
                content: "I'll add proper error handling to the PTY spawn function. Let me first read the current implementation.".into(),
                timestamp: 1710000001,
                tool_name: None,
                tool_result: None,
                collapsed: false,
            },
            AgentMessage {
                id: "3".into(),
                role: MessageRole::Assistant,
                content: "Reading the PTY module...".into(),
                timestamp: 1710000002,
                tool_name: Some("Read".into()),
                tool_result: Some("pub fn spawn(&self, options: PtyOptions) -> Result<String, String> {\n    let pty_system = native_pty_system();\n    // ...\n}".into()),
                collapsed: false,
            },
            AgentMessage {
                id: "4".into(),
                role: MessageRole::Assistant,
                content: "The function already returns `Result<String, String>`. I'll improve the error types and add logging.".into(),
                timestamp: 1710000003,
                tool_name: None,
                tool_result: None,
                collapsed: false,
            },
            AgentMessage {
                id: "5".into(),
                role: MessageRole::Assistant,
                content: "Applying changes to agor-core/src/pty.rs".into(),
                timestamp: 1710000004,
                tool_name: Some("Edit".into()),
                tool_result: Some("Applied 3 edits to agor-core/src/pty.rs".into()),
                collapsed: false,
            },
            AgentMessage {
                id: "6".into(),
                role: MessageRole::Assistant,
                content: "Done. I've added:\n1. Structured PtyError enum replacing raw String errors\n2. log::error! calls on spawn failure with context\n3. Graceful fallback when SHELL env var is missing".into(),
                timestamp: 1710000005,
                tool_name: None,
                tool_result: None,
                collapsed: false,
            },
        ];

        let mut session = AgentSession::new();
        session.messages = messages;
        session.status = AgentStatus::Done;
        session.cost_usd = 0.0142;
        session.tokens_used = 3847;

        Self {
            session,
            prompt_text: String::new(),
        }
    }
}

impl Render for AgentPane {
    fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
        let status = self.session.status;

        // Build message list
        let mut message_list = div()
            .id("message-list")
            .flex_1()
            .w_full()
            .flex()
            .flex_col()
            .gap(px(8.0))
            .p(px(12.0))
            .overflow_y_scroll();

        if self.session.messages.is_empty() {
            message_list = message_list.child(
                div()
                    .flex_1()
                    .flex()
                    .items_center()
                    .justify_center()
                    .text_size(px(14.0))
                    .text_color(theme::OVERLAY0)
                    .child("Start a conversation with your agent..."),
            );
        } else {
            for msg in &self.session.messages {
                message_list = message_list.child(render_message(msg));
            }
        }

        div()
            .id("agent-pane")
            .w_full()
            .flex_1()
            .flex()
            .flex_col()
            .bg(theme::BASE)
            // ── Status strip ────────────────────────────────────
            .child(
                div()
                    .w_full()
                    .h(px(28.0))
                    .flex()
                    .flex_row()
                    .items_center()
                    .px(px(10.0))
                    .gap(px(6.0))
                    .bg(theme::MANTLE)
                    .border_b_1()
                    .border_color(theme::SURFACE0)
                    .child(status_dot(status))
                    .child(
                        div()
                            .text_size(px(11.0))
                            .text_color(theme::SUBTEXT0)
                            .child(status_label(status).to_string()),
                    )
                    .child(div().flex_1())
                    // Cost
                    .child(
                        div()
                            .text_size(px(11.0))
                            .text_color(theme::OVERLAY0)
                            .child(format!("${:.4}", self.session.cost_usd)),
                    )
                    // Tokens
                    .child(
                        div()
                            .text_size(px(11.0))
                            .text_color(theme::OVERLAY0)
                            .child(format!("{}tok", self.session.tokens_used)),
                    )
                    // Model
                    .child(
                        div()
                            .text_size(px(10.0))
                            .text_color(theme::OVERLAY0)
                            .px(px(6.0))
                            .py(px(1.0))
                            .rounded(px(3.0))
                            .bg(theme::SURFACE0)
                            .child(self.session.model.clone()),
                    ),
            )
            // ── Message list (scrollable) ───────────────────────
            .child(message_list)
            // ── Prompt input ────────────────────────────────────
            .child(
                div()
                    .w_full()
                    .px(px(12.0))
                    .py(px(8.0))
                    .border_t_1()
                    .border_color(theme::SURFACE0)
                    .child(
                        div()
                            .id("prompt-input")
                            .w_full()
                            .min_h(px(36.0))
                            .px(px(12.0))
                            .py(px(8.0))
                            .rounded(px(8.0))
                            .bg(theme::SURFACE0)
                            .border_1()
                            .border_color(theme::SURFACE1)
                            .text_size(px(13.0))
                            .text_color(theme::TEXT)
                            .child(
                                if self.prompt_text.is_empty() {
                                    div()
                                        .text_color(theme::OVERLAY0)
                                        .child("Ask Claude anything... (Enter to send)")
                                } else {
                                    div().child(self.prompt_text.clone())
                                },
                            ),
                    ),
            )
    }
}
