//! TUI widget for embedding a browser in terminal applications
//!
//! This module provides a ratatui widget that displays web content in the terminal.

use crate::OrbBrowser;
use color_eyre::Result;
use ratatui::{
    layout::Rect,
    widgets::{Block, Borders, Paragraph, Widget},
};
use std::sync::{Arc, Mutex};
use image::DynamicImage;

/// State for the browser widget
#[derive(Clone)]
pub struct BrowserState {
    /// Current URL being displayed
    pub current_url: Option<String>,
    /// Cached screenshot of current page
    screenshot: Arc<Mutex<Option<DynamicImage>>>,
    /// Scroll offset (for future scrolling support)
    pub scroll_offset: u16,
    /// Loading state
    pub is_loading: bool,
}

impl Default for BrowserState {
    fn default() -> Self {
        Self {
            current_url: None,
            screenshot: Arc::new(Mutex::new(None)),
            scroll_offset: 0,
            is_loading: false,
        }
    }
}

impl BrowserState {
    /// Create a new browser state
    pub fn new() -> Self {
        Self::default()
    }

    /// Navigate to a URL and capture screenshot
    pub async fn navigate(&mut self, browser: &OrbBrowser, url: String) -> Result<()> {
        self.is_loading = true;
        self.current_url = Some(url.clone());

        // Navigate and capture
        browser.goto(&url).await?;

        // Wait for page load
        tokio::time::sleep(tokio::time::Duration::from_millis(1000)).await;

        // Capture screenshot
        let screenshot_bytes = browser.client().screenshot().await?;
        let screenshot_data = base64::Engine::decode(
            &base64::prelude::BASE64_STANDARD,
            &screenshot_bytes
        )?;

        // Decode image
        let img = image::load_from_memory(&screenshot_data)?;

        // Store screenshot
        if let Ok(mut screenshot) = self.screenshot.lock() {
            *screenshot = Some(img);
        }

        self.is_loading = false;
        Ok(())
    }

    /// Get the current screenshot
    pub fn screenshot(&self) -> Option<DynamicImage> {
        self.screenshot.lock().ok()?.clone()
    }
}

/// Browser widget for ratatui
///
/// This widget displays web content in the terminal using screenshots.
///
/// ## Example
///
/// ```no_run
/// use orb_browse::{OrbBrowser, widget::{BrowserWidget, BrowserState}};
/// use ratatui::prelude::*;
///
/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
/// let browser = OrbBrowser::new().await?;
/// let mut state = BrowserState::new();
///
/// // Navigate to URL
/// state.navigate(&browser, "https://example.com".to_string()).await?;
///
/// // In your ratatui render loop:
/// // frame.render_widget(BrowserWidget::new(&state), area);
/// # Ok(())
/// # }
/// ```
pub struct BrowserWidget<'a> {
    state: &'a BrowserState,
    block: Option<Block<'a>>,
}

impl<'a> BrowserWidget<'a> {
    /// Create a new browser widget
    pub fn new(state: &'a BrowserState) -> Self {
        Self {
            state,
            block: None,
        }
    }

    /// Set the block to wrap the widget
    pub fn block(mut self, block: Block<'a>) -> Self {
        self.block = Some(block);
        self
    }
}

impl<'a> Widget for BrowserWidget<'a> {
    fn render(self, area: Rect, buf: &mut ratatui::buffer::Buffer) {
        // Render outer block if provided
        let inner_area = if let Some(block) = self.block {
            let inner = block.inner(area);
            block.render(area, buf);
            inner
        } else {
            area
        };

        // Render content based on state
        if self.state.is_loading {
            let loading = Paragraph::new("Loading...")
                .block(Block::default().borders(Borders::NONE));
            loading.render(inner_area, buf);
        } else if let Some(ref url) = self.state.current_url {
            // For now, render a placeholder showing the URL
            // In a full implementation, this would use ratatui-image to render the screenshot
            let content = if let Some(_screenshot) = self.state.screenshot() {
                format!("📸 Displaying: {}\n\n[Screenshot rendering requires ratatui-image integration]\n\nUse ratatui_image::Image to render the screenshot", url)
            } else {
                format!("🌐 {}\n\n[No screenshot available]", url)
            };

            let paragraph = Paragraph::new(content)
                .block(Block::default().borders(Borders::NONE));
            paragraph.render(inner_area, buf);
        } else {
            let placeholder = Paragraph::new("No page loaded. Call state.navigate() to load a page.")
                .block(Block::default().borders(Borders::NONE));
            placeholder.render(inner_area, buf);
        }
    }
}

/// Event handler for browser interactions
pub enum BrowserEvent {
    /// Navigate to a new URL
    Navigate(String),
    /// Scroll up
    ScrollUp,
    /// Scroll down
    ScrollDown,
    /// Refresh current page
    Refresh,
    /// Go back in history
    Back,
    /// Go forward in history
    Forward,
}

impl BrowserState {
    /// Handle browser events
    pub async fn handle_event(&mut self, browser: &OrbBrowser, event: BrowserEvent) -> Result<()> {
        match event {
            BrowserEvent::Navigate(url) => {
                self.navigate(browser, url).await?;
            }
            BrowserEvent::ScrollUp => {
                self.scroll_offset = self.scroll_offset.saturating_sub(5);
            }
            BrowserEvent::ScrollDown => {
                self.scroll_offset = self.scroll_offset.saturating_add(5);
            }
            BrowserEvent::Refresh => {
                if let Some(url) = self.current_url.clone() {
                    self.navigate(browser, url).await?;
                }
            }
            BrowserEvent::Back => {
                // Browser history navigation would go here
                // Requires storing history stack
            }
            BrowserEvent::Forward => {
                // Browser history navigation would go here
            }
        }
        Ok(())
    }
}
