use anyhow::Result;
use chrono::{Local, Timelike};
use crossterm::event::{self, Event, KeyCode, KeyEvent, KeyEventKind};
use log::debug;
use ratatui::{
    backend::Backend,
    buffer::Buffer,
    layout::{Alignment, Constraint, Direction, Layout, Rect},
    style::{Color, Modifier, Style},
    text::{Line, Span},
    widgets::{Block, Borders, Cell, List, ListItem, Paragraph, Row, Table, Widget},
    Frame, Terminal,
};
use std::time::{Duration, Instant};

use crate::{
    models::{Project, Session},
    ui::animations::{AnimatedSpinner, PulsingIndicator, ViewTransition, TransitionDirection},
    ui::formatter::Formatter,
    ui::widgets::{ColorScheme, Spinner},
    utils::ipc::{
        get_socket_path, is_daemon_running, IpcClient, IpcMessage, IpcResponse, ProjectWithStats,
    },
};

#[derive(Clone, PartialEq)]
pub enum DashboardView {
    FocusedSession,
    Overview,
    History,
    Projects,
}

#[derive(Clone)]
pub struct SessionFilter {
    pub start_date: Option<chrono::NaiveDate>,
    pub end_date: Option<chrono::NaiveDate>,
    pub project_filter: Option<String>,
    pub duration_filter: Option<(i64, i64)>, // min, max seconds
    pub search_text: String,
}

impl Default for SessionFilter {
    fn default() -> Self {
        Self {
            start_date: None,
            end_date: None,
            project_filter: None,
            duration_filter: None,
            search_text: String::new(),
        }
    }
}

pub struct Dashboard {
    client: IpcClient,
    current_session: Option<Session>,
    current_project: Option<Project>,
    daily_stats: (i64, i64, i64),
    weekly_stats: i64,
    today_sessions: Vec<Session>,
    recent_projects: Vec<ProjectWithStats>,
    available_projects: Vec<Project>,
    selected_project_index: usize,
    show_project_switcher: bool,
    current_view: DashboardView,

    // History browser state
    history_sessions: Vec<Session>,
    selected_session_index: usize,
    session_filter: SessionFilter,
    filter_input_mode: bool,

    // Project grid state
    selected_project_row: usize,
    selected_project_col: usize,
    projects_per_row: usize,

    spinner: Spinner,
    last_update: Instant,

    // Animation state
    animated_spinner: AnimatedSpinner,
    pulsing_indicator: PulsingIndicator,
    view_transition: Option<ViewTransition>,
    previous_view: DashboardView,
    frame_count: u64,
}

impl Dashboard {
    pub async fn new() -> Result<Self> {
        let socket_path = get_socket_path()?;
        let client = if socket_path.exists() && is_daemon_running() {
            IpcClient::connect(&socket_path)
                .await
                .unwrap_or_else(|_| IpcClient::new().unwrap())
        } else {
            IpcClient::new()?
        };
        Ok(Self {
            client,
            current_session: None,
            current_project: None,
            daily_stats: (0, 0, 0),
            weekly_stats: 0,
            today_sessions: Vec::new(),
            recent_projects: Vec::new(),
            available_projects: Vec::new(),
            selected_project_index: 0,
            show_project_switcher: false,
            current_view: DashboardView::FocusedSession,

            // Initialize history browser state
            history_sessions: Vec::new(),
            selected_session_index: 0,
            session_filter: SessionFilter::default(),
            filter_input_mode: false,

            // Initialize project grid state
            selected_project_row: 0,
            selected_project_col: 0,
            projects_per_row: 3,

            spinner: Spinner::new(),
            last_update: Instant::now(),

            // Initialize animation state
            animated_spinner: AnimatedSpinner::braille(),
            pulsing_indicator: PulsingIndicator::new(),
            view_transition: None,
            previous_view: DashboardView::FocusedSession,
            frame_count: 0,
        })
    }

    pub async fn run<B: Backend>(&mut self, terminal: &mut Terminal<B>) -> Result<()> {
        use tokio::time::{interval, Duration as TokioDuration};

        // 60 FPS frame loop (16.67ms per frame)
        let mut frame_interval = interval(TokioDuration::from_millis(16));

        loop {
            // Wait for next frame
            frame_interval.tick().await;

            // Update animations and state
            self.update_animations();
            self.update_state().await?;

            // Render current frame
            terminal.draw(|f| self.render_dashboard_sync(f))?;

            // Poll for input events (non-blocking)
            if event::poll(Duration::from_millis(0))? {
                match event::read()? {
                    Event::Key(key) if key.kind == KeyEventKind::Press => {
                        if self.show_project_switcher {
                            self.handle_project_switcher_input(key).await?;
                        } else {
                            // Handle global exit here
                            match key.code {
                                KeyCode::Char('q') => break,
                                KeyCode::Esc => {
                                    if self.current_view == DashboardView::FocusedSession {
                                        self.transition_to_view(DashboardView::Overview);
                                    } else {
                                        break;
                                    }
                                }
                                _ => self.handle_dashboard_input(key).await?,
                            }
                        }
                    }
                    _ => {}
                }
            }
        }
        Ok(())
    }

    /// Update all animation states (called every frame @ 60 FPS)
    fn update_animations(&mut self) {
        // Increment frame counter
        self.frame_count += 1;

        // Tick spinners
        self.animated_spinner.tick();

        // Update view transition if active
        if let Some(transition) = &self.view_transition {
            if transition.is_complete() {
                self.view_transition = None;
            }
        }
    }

    async fn update_state(&mut self) -> Result<()> {
        // Send activity heartbeat (throttled)
        if self.last_update.elapsed() >= Duration::from_secs(3) {
            if let Err(e) = self.send_activity_heartbeat().await {
                debug!("Heartbeat error: {}", e);
            }
            self.last_update = Instant::now();
        }

        // Tick legacy spinner for compatibility
        self.spinner.next();

        // Get current status
        self.current_session = self.get_current_session().await?;

        // Clone session to avoid borrow conflict
        let session_clone = self.current_session.clone();
        if let Some(session) = session_clone {
            self.current_project = self.get_project_by_session(&session).await?;
        } else {
            self.current_project = None;
        }

        self.daily_stats = self.get_today_stats().await.unwrap_or((0, 0, 0));
        self.weekly_stats = self.get_weekly_stats().await.unwrap_or(0);
        self.today_sessions = self.get_today_sessions().await.unwrap_or_default();
        self.recent_projects = self.get_recent_projects().await.unwrap_or_default();

        // Update history sessions if in history view
        if self.current_view == DashboardView::History {
            self.history_sessions = self.get_history_sessions().await.unwrap_or_default();
        }

        // Update project list if in project view
        if self.current_view == DashboardView::Projects && self.available_projects.is_empty() {
            if let Err(_) = self.refresh_projects().await {
                // Ignore errors and use empty list
            }
        }

        Ok(())
    }

    async fn get_weekly_stats(&mut self) -> Result<i64> {
        match self.client.send_message(&IpcMessage::GetWeeklyStats).await {
            Ok(IpcResponse::WeeklyStats { total_seconds }) => Ok(total_seconds),
            Ok(response) => {
                debug!("Unexpected response for GetWeeklyStats: {:?}", response);
                Err(anyhow::anyhow!("Unexpected response"))
            }
            Err(e) => {
                debug!("Failed to receive GetWeeklyStats response: {}", e);
                Err(anyhow::anyhow!("Failed to receive response"))
            }
        }
    }

    async fn get_recent_projects(&mut self) -> Result<Vec<ProjectWithStats>> {
        match self
            .client
            .send_message(&IpcMessage::GetRecentProjects)
            .await
        {
            Ok(IpcResponse::RecentProjects(projects)) => Ok(projects),
            Ok(response) => {
                debug!("Unexpected response for GetRecentProjects: {:?}", response);
                Err(anyhow::anyhow!("Unexpected response"))
            }
            Err(e) => {
                debug!("Failed to receive GetRecentProjects response: {}", e);
                Err(anyhow::anyhow!("Failed to receive response"))
            }
        }
    }

    /// Transition to a new view with animation
    fn transition_to_view(&mut self, new_view: DashboardView) {
        if self.current_view == new_view {
            return;
        }

        // Determine transition direction based on view order
        let direction = match (&self.current_view, &new_view) {
            (DashboardView::FocusedSession, _) => TransitionDirection::SlideLeft,
            (_, DashboardView::FocusedSession) => TransitionDirection::SlideRight,
            _ => TransitionDirection::FadeIn,
        };

        // Create transition animation (200ms duration for smooth, subtle effect)
        self.view_transition = Some(ViewTransition::new(direction, Duration::from_millis(200)));
        self.previous_view = self.current_view.clone();
        self.current_view = new_view;
    }

    async fn handle_dashboard_input(&mut self, key: KeyEvent) -> Result<()> {
        // Handle view-specific inputs first
        match self.current_view {
            DashboardView::History => {
                return self.handle_history_input(key).await;
            }
            DashboardView::Projects => {
                return self.handle_project_grid_input(key).await;
            }
            _ => {}
        }

        // Handle global navigation
        match key.code {
            // View navigation with transitions
            KeyCode::Char('1') => self.transition_to_view(DashboardView::FocusedSession),
            KeyCode::Char('2') => self.transition_to_view(DashboardView::Overview),
            KeyCode::Char('3') => self.transition_to_view(DashboardView::History),
            KeyCode::Char('4') => self.transition_to_view(DashboardView::Projects),
            KeyCode::Char('f') => self.transition_to_view(DashboardView::FocusedSession),
            KeyCode::Tab => {
                let next_view = match self.current_view {
                    DashboardView::FocusedSession => DashboardView::Overview,
                    DashboardView::Overview => DashboardView::History,
                    DashboardView::History => DashboardView::Projects,
                    DashboardView::Projects => DashboardView::FocusedSession,
                };
                self.transition_to_view(next_view);
            }
            // Project switcher (only in certain views)
            KeyCode::Char('p') if self.current_view != DashboardView::Projects => {
                self.refresh_projects().await?;
                self.show_project_switcher = true;
            }
            _ => {}
        }
        Ok(())
    }

    async fn handle_history_input(&mut self, key: KeyEvent) -> Result<()> {
        match key.code {
            // Navigation in session list
            KeyCode::Up | KeyCode::Char('k') => {
                if !self.history_sessions.is_empty() && self.selected_session_index > 0 {
                    self.selected_session_index -= 1;
                }
            }
            KeyCode::Down | KeyCode::Char('j') => {
                if self.selected_session_index < self.history_sessions.len().saturating_sub(1) {
                    self.selected_session_index += 1;
                }
            }
            // Search mode
            KeyCode::Char('/') => {
                self.filter_input_mode = true;
            }
            KeyCode::Enter if self.filter_input_mode => {
                self.filter_input_mode = false;
                self.history_sessions = self.get_history_sessions().await.unwrap_or_default();
            }
            // Character input in search mode
            KeyCode::Char(c) if self.filter_input_mode => {
                self.session_filter.search_text.push(c);
            }
            KeyCode::Backspace if self.filter_input_mode => {
                self.session_filter.search_text.pop();
            }
            KeyCode::Esc if self.filter_input_mode => {
                self.filter_input_mode = false;
                self.session_filter.search_text.clear();
            }
            _ => {}
        }
        Ok(())
    }

    async fn handle_project_grid_input(&mut self, key: KeyEvent) -> Result<()> {
        match key.code {
            // Grid navigation
            KeyCode::Up | KeyCode::Char('k') => {
                if self.selected_project_row > 0 {
                    self.selected_project_row -= 1;
                }
            }
            KeyCode::Down | KeyCode::Char('j') => {
                let total_projects = self.available_projects.len();
                let total_rows =
                    (total_projects + self.projects_per_row - 1) / self.projects_per_row;
                if self.selected_project_row < total_rows.saturating_sub(1) {
                    // Only move down if there's a project on the next row
                    let next_row_first_index =
                        (self.selected_project_row + 1) * self.projects_per_row;
                    if next_row_first_index < total_projects {
                        self.selected_project_row += 1;
                    }
                }
            }
            KeyCode::Left | KeyCode::Char('h') => {
                if self.selected_project_col > 0 {
                    self.selected_project_col -= 1;
                }
            }
            KeyCode::Right | KeyCode::Char('l') => {
                let row_start = self.selected_project_row * self.projects_per_row;
                let row_end =
                    (row_start + self.projects_per_row).min(self.available_projects.len());
                let max_col = (row_end - row_start).saturating_sub(1);
                if self.selected_project_col < max_col {
                    self.selected_project_col += 1;
                }
            }
            // Project selection
            KeyCode::Enter => {
                self.switch_to_grid_selected_project().await?;
            }
            _ => {}
        }
        Ok(())
    }

    async fn handle_project_switcher_input(&mut self, key: KeyEvent) -> Result<()> {
        match key.code {
            KeyCode::Esc => {
                self.show_project_switcher = false;
            }
            KeyCode::Up | KeyCode::Char('k') => {
                self.navigate_projects(-1);
            }
            KeyCode::Down | KeyCode::Char('j') => {
                self.navigate_projects(1);
            }
            KeyCode::Enter => {
                self.switch_to_selected_project().await?;
            }
            _ => {}
        }
        Ok(())
    }

    async fn ensure_connected(&mut self) -> Result<()> {
        if !is_daemon_running() {
            return Err(anyhow::anyhow!("Daemon is not running"));
        }

        // Test if we have a working connection
        if self.client.stream.is_some() {
            return Ok(());
        }

        // Reconnect if needed
        let socket_path = get_socket_path()?;
        if socket_path.exists() {
            self.client = IpcClient::connect(&socket_path).await?;
        }
        Ok(())
    }

    async fn switch_to_grid_selected_project(&mut self) -> Result<()> {
        let selected_index =
            self.selected_project_row * self.projects_per_row + self.selected_project_col;
        if let Some(selected_project) = self.available_projects.get(selected_index) {
            let project_id = selected_project.id.unwrap_or(0);

            self.ensure_connected().await?;

            // Switch to the selected project
            let response = self
                .client
                .send_message(&IpcMessage::SwitchProject(project_id))
                .await?;
            match response {
                IpcResponse::Success => {
                    // Switch to focused view after selection with transition
                    self.transition_to_view(DashboardView::FocusedSession);
                }
                IpcResponse::Error(e) => {
                    return Err(anyhow::anyhow!("Failed to switch project: {}", e))
                }
                _ => return Err(anyhow::anyhow!("Unexpected response")),
            }
        }
        Ok(())
    }

    fn render_keyboard_hints(&self, area: Rect, buf: &mut Buffer) {
        let hints = match self.current_view {
            DashboardView::FocusedSession => vec![
                ("Esc", "Exit Focus"),
                ("Tab", "Next View"),
                ("p", "Projects"),
            ],
            DashboardView::History => vec![
                ("↑/↓", "Navigate"),
                ("/", "Search"),
                ("Tab", "Next View"),
                ("q", "Quit"),
            ],
            DashboardView::Projects => vec![
                ("↑/↓/←/→", "Navigate"),
                ("Enter", "Select"),
                ("Tab", "Next View"),
                ("q", "Quit"),
            ],
            _ => vec![
                ("q", "Quit"),
                ("f", "Focus"),
                ("Tab", "Next View"),
                ("1-4", "View"),
                ("p", "Projects"),
            ],
        };

        let spans: Vec<Span> = hints
            .iter()
            .flat_map(|(key, desc)| {
                vec![
                    Span::styled(
                        format!(" {} ", key),
                        Style::default()
                            .fg(Color::Yellow)
                            .add_modifier(Modifier::BOLD),
                    ),
                    Span::styled(format!("{} ", desc), Style::default().fg(Color::DarkGray)),
                ]
            })
            .collect();

        let line = Line::from(spans);
        let block = Block::default()
            .borders(Borders::TOP)
            .border_style(Style::default().fg(Color::DarkGray));
        Paragraph::new(line).block(block).render(area, buf);
    }

    fn render_dashboard_sync(&mut self, f: &mut Frame) {
        match self.current_view {
            DashboardView::FocusedSession => self.render_focused_session_view(f),
            DashboardView::Overview => self.render_overview_dashboard(f),
            DashboardView::History => self.render_history_browser(f),
            DashboardView::Projects => self.render_project_grid(f),
        }

        // Project switcher overlay (available on most views)
        if self.show_project_switcher {
            self.render_project_switcher(f, f.size());
        }
    }

    fn render_focused_session_view(&mut self, f: &mut Frame) {
        let chunks = Layout::default()
            .direction(Direction::Vertical)
            .constraints([
                Constraint::Length(3), // Header with ESC hint
                Constraint::Length(2), // Spacer
                Constraint::Length(6), // Project info box
                Constraint::Length(2), // Spacer
                Constraint::Length(8), // Large timer box
                Constraint::Length(2), // Spacer
                Constraint::Length(8), // Session details
                Constraint::Min(0),    // Bottom spacer
                Constraint::Length(1), // Footer
            ])
            .split(f.size());

        // Top header with ESC hint
        let header_layout = Layout::default()
            .direction(Direction::Horizontal)
            .constraints([Constraint::Percentage(100)])
            .split(chunks[0]);

        f.render_widget(
            Paragraph::new("Press ESC to exit focused mode.")
                .alignment(Alignment::Center)
                .style(Style::default().fg(ColorScheme::GRAY_TEXT)),
            header_layout[0],
        );

        if let (Some(session), Some(project)) = (&self.current_session, &self.current_project) {
            // Project info box
            let project_area = self.centered_rect(60, 20, chunks[2]);
            let project_block = Block::default()
                .borders(Borders::ALL)
                .border_style(Style::default().fg(ColorScheme::GRAY_TEXT))
                .style(Style::default().bg(ColorScheme::CLEAN_BG));

            let project_layout = Layout::default()
                .direction(Direction::Vertical)
                .constraints([
                    Constraint::Length(1),
                    Constraint::Length(1),
                    Constraint::Length(1),
                    Constraint::Length(1),
                ])
                .margin(1)
                .split(project_area);

            f.render_widget(project_block, project_area);

            // Project name
            f.render_widget(
                Paragraph::new(project.name.clone())
                    .alignment(Alignment::Center)
                    .style(
                        Style::default()
                            .fg(ColorScheme::WHITE_TEXT)
                            .add_modifier(Modifier::BOLD),
                    ),
                project_layout[0],
            );

            // Project description or refactor info
            let default_description = "Refactor authentication module".to_string();
            let description = project.description.as_ref().unwrap_or(&default_description);
            f.render_widget(
                Paragraph::new(description.clone())
                    .alignment(Alignment::Center)
                    .style(Style::default().fg(ColorScheme::GRAY_TEXT)),
                project_layout[1],
            );

            // Large timer box with pulsing border (breathing effect)
            let timer_area = self.centered_rect(40, 20, chunks[4]);

            // Calculate pulsing border color for active session
            use crate::ui::animations::pulse_color;
            let pulse_start = ColorScheme::CLEAN_GREEN;
            let pulse_end = ColorScheme::PRIMARY_FOCUS;
            let border_color = pulse_color(
                pulse_start,
                pulse_end,
                self.pulsing_indicator.start_time.elapsed(),
                Duration::from_millis(2000),
            );

            let timer_block = Block::default()
                .borders(Borders::ALL)
                .border_style(Style::default().fg(border_color))
                .style(Style::default().bg(Color::Black));

            let timer_inner = timer_block.inner(timer_area);
            f.render_widget(timer_block, timer_area);

            // Calculate and display large timer
            let now = Local::now();
            let elapsed_seconds = (now.timestamp() - session.start_time.timestamp())
                - session.paused_duration.num_seconds();
            let duration_str = Formatter::format_duration_clock(elapsed_seconds);

            f.render_widget(
                Paragraph::new(duration_str)
                    .alignment(Alignment::Center)
                    .style(
                        Style::default()
                            .fg(ColorScheme::CLEAN_GREEN)
                            .add_modifier(Modifier::BOLD),
                    ),
                timer_inner,
            );

            // Session details box
            let details_area = self.centered_rect(60, 25, chunks[6]);
            let details_block = Block::default()
                .borders(Borders::ALL)
                .border_style(Style::default().fg(ColorScheme::GRAY_TEXT))
                .style(Style::default().bg(ColorScheme::CLEAN_BG));

            let details_layout = Layout::default()
                .direction(Direction::Vertical)
                .constraints([
                    Constraint::Length(2), // Start time
                    Constraint::Length(2), // Session type
                    Constraint::Length(2), // Tags
                ])
                .margin(1)
                .split(details_area);

            f.render_widget(details_block, details_area);

            // Start time
            let start_time_layout = Layout::default()
                .direction(Direction::Horizontal)
                .constraints([Constraint::Percentage(30), Constraint::Percentage(70)])
                .split(details_layout[0]);

            f.render_widget(
                Paragraph::new("Start Time").style(Style::default().fg(ColorScheme::GRAY_TEXT)),
                start_time_layout[0],
            );
            f.render_widget(
                Paragraph::new(
                    session
                        .start_time
                        .with_timezone(&Local)
                        .format("%H:%M")
                        .to_string(),
                )
                .alignment(Alignment::Right)
                .style(Style::default().fg(ColorScheme::WHITE_TEXT)),
                start_time_layout[1],
            );

            // Session type
            let session_type_layout = Layout::default()
                .direction(Direction::Horizontal)
                .constraints([Constraint::Percentage(30), Constraint::Percentage(70)])
                .split(details_layout[1]);

            f.render_widget(
                Paragraph::new("Session Type").style(Style::default().fg(ColorScheme::GRAY_TEXT)),
                session_type_layout[0],
            );
            f.render_widget(
                Paragraph::new("Deep Work")
                    .alignment(Alignment::Right)
                    .style(Style::default().fg(ColorScheme::WHITE_TEXT)),
                session_type_layout[1],
            );

            // Tags
            let tags_layout = Layout::default()
                .direction(Direction::Horizontal)
                .constraints([Constraint::Percentage(30), Constraint::Percentage(70)])
                .split(details_layout[2]);

            f.render_widget(
                Paragraph::new("Tags").style(Style::default().fg(ColorScheme::GRAY_TEXT)),
                tags_layout[0],
            );

            // Create tag spans
            let tag_spans = vec![
                Span::styled(
                    " Backend ",
                    Style::default()
                        .fg(ColorScheme::CLEAN_BG)
                        .bg(ColorScheme::GRAY_TEXT),
                ),
                Span::raw(" "),
                Span::styled(
                    " Refactor ",
                    Style::default()
                        .fg(ColorScheme::CLEAN_BG)
                        .bg(ColorScheme::GRAY_TEXT),
                ),
                Span::raw(" "),
                Span::styled(
                    " Security ",
                    Style::default()
                        .fg(ColorScheme::CLEAN_BG)
                        .bg(ColorScheme::GRAY_TEXT),
                ),
            ];

            f.render_widget(
                Paragraph::new(Line::from(tag_spans)).alignment(Alignment::Right),
                tags_layout[1],
            );
        } else {
            // No active session - show idle state
            let idle_area = self.centered_rect(50, 20, chunks[4]);
            let idle_block = Block::default()
                .borders(Borders::ALL)
                .border_style(Style::default().fg(ColorScheme::GRAY_TEXT))
                .style(Style::default().bg(ColorScheme::CLEAN_BG));

            f.render_widget(idle_block.clone(), idle_area);

            let idle_inner = idle_block.inner(idle_area);
            f.render_widget(
                Paragraph::new("No Active Session\n\nPress 's' to start tracking")
                    .alignment(Alignment::Center)
                    .style(Style::default().fg(ColorScheme::GRAY_TEXT)),
                idle_inner,
            );
        }
    }

    fn render_overview_dashboard(&mut self, f: &mut Frame) {
        let chunks = Layout::default()
            .direction(Direction::Vertical)
            .constraints([
                Constraint::Length(3), // Header
                Constraint::Min(10),   // Main Content
                Constraint::Length(1), // Bottom bar
            ])
            .split(f.size());

        // Header
        self.render_header(f, chunks[0]);

        // Main Content Grid (Left: 8 cols, Right: 4 cols)
        let grid_chunks = Layout::default()
            .direction(Direction::Horizontal)
            .constraints([
                Constraint::Percentage(66), // Left Column
                Constraint::Percentage(34), // Right Column
            ])
            .split(chunks[1]);

        let left_col = grid_chunks[0];
        let right_col = grid_chunks[1];

        // Left Column Layout
        let left_chunks = Layout::default()
            .direction(Direction::Vertical)
            .constraints([
                Constraint::Length(12), // Active Session Panel
                Constraint::Min(10),    // Project List Table
            ])
            .split(left_col);

        let current_session = &self.current_session;
        let current_project = &self.current_project;

        // 1. Active Session Panel
        self.render_active_session_panel(f, left_chunks[0], current_session, current_project);

        // 2. Project List Table
        self.render_projects_table(f, left_chunks[1]);

        // Right Column Layout
        let right_chunks = Layout::default()
            .direction(Direction::Vertical)
            .constraints([
                Constraint::Length(10), // Quick Stats
                Constraint::Min(10),    // Activity Timeline
            ])
            .split(right_col);

        // 3. Quick Stats
        let daily_stats = self.get_daily_stats();
        self.render_quick_stats(f, right_chunks[0], daily_stats);

        // 4. Activity Timeline
        self.render_activity_timeline(f, right_chunks[1]);

        // 5. Bottom Bar
        self.render_keyboard_hints(chunks[2], f.buffer_mut());
    }

    fn render_history_browser(&mut self, f: &mut Frame) {
        let chunks = Layout::default()
            .direction(Direction::Horizontal)
            .constraints([Constraint::Percentage(70), Constraint::Percentage(30)])
            .split(f.size());

        let left_chunks = Layout::default()
            .direction(Direction::Vertical)
            .constraints([
                Constraint::Length(3), // Header
                Constraint::Length(8), // Filters
                Constraint::Min(10),   // Session list
            ])
            .split(chunks[0]);

        let right_chunks = Layout::default()
            .direction(Direction::Vertical)
            .constraints([
                Constraint::Percentage(60), // Session details
                Constraint::Length(4),      // Action buttons
                Constraint::Min(0),         // Summary
            ])
            .split(chunks[1]);

        // Header
        f.render_widget(
            Paragraph::new("Tempo TUI :: History Browser")
                .style(
                    Style::default()
                        .fg(ColorScheme::CLEAN_BLUE)
                        .add_modifier(Modifier::BOLD),
                )
                .block(
                    Block::default()
                        .borders(Borders::BOTTOM)
                        .border_style(Style::default().fg(ColorScheme::GRAY_TEXT)),
                ),
            left_chunks[0],
        );

        // Filters panel
        self.render_history_filters(f, left_chunks[1]);

        // Session list
        self.render_session_list(f, left_chunks[2]);

        // Session details
        self.render_session_details(f, right_chunks[0]);

        // Action buttons
        self.render_session_actions(f, right_chunks[1]);

        // Summary
        self.render_history_summary(f, right_chunks[2]);
    }

    fn render_history_filters(&self, f: &mut Frame, area: Rect) {
        let block = Block::default()
            .borders(Borders::ALL)
            .title(" Filters ")
            .border_style(Style::default().fg(ColorScheme::GRAY_TEXT));

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

        let filter_chunks = Layout::default()
            .direction(Direction::Vertical)
            .constraints([
                Constraint::Length(2), // Date filters
                Constraint::Length(1), // Project filter
                Constraint::Length(1), // Duration filter
                Constraint::Length(1), // Search
            ])
            .split(inner_area);

        // Date range
        let date_layout = Layout::default()
            .direction(Direction::Horizontal)
            .constraints([
                Constraint::Percentage(30),
                Constraint::Percentage(35),
                Constraint::Percentage(35),
            ])
            .split(filter_chunks[0]);

        f.render_widget(
            Paragraph::new("Start Date\nEnd Date")
                .style(Style::default().fg(ColorScheme::GRAY_TEXT)),
            date_layout[0],
        );
        f.render_widget(
            Paragraph::new("2023-10-01\n2023-10-31")
                .style(Style::default().fg(ColorScheme::WHITE_TEXT)),
            date_layout[1],
        );
        f.render_widget(
            Paragraph::new("Project\nDuration Filter")
                .style(Style::default().fg(ColorScheme::GRAY_TEXT)),
            date_layout[2],
        );

        // Project filter
        let project_layout = Layout::default()
            .direction(Direction::Horizontal)
            .constraints([Constraint::Length(15), Constraint::Min(0)])
            .split(filter_chunks[1]);

        f.render_widget(
            Paragraph::new("Project").style(Style::default().fg(ColorScheme::GRAY_TEXT)),
            project_layout[0],
        );
        f.render_widget(
            Paragraph::new("Filter by project ▼")
                .style(Style::default().fg(ColorScheme::WHITE_TEXT)),
            project_layout[1],
        );

        // Duration filter
        let duration_layout = Layout::default()
            .direction(Direction::Horizontal)
            .constraints([Constraint::Length(15), Constraint::Min(0)])
            .split(filter_chunks[2]);

        f.render_widget(
            Paragraph::new("Duration Filter").style(Style::default().fg(ColorScheme::GRAY_TEXT)),
            duration_layout[0],
        );
        f.render_widget(
            Paragraph::new(">1h, <30m").style(Style::default().fg(ColorScheme::WHITE_TEXT)),
            duration_layout[1],
        );

        // Free-text search
        let search_layout = Layout::default()
            .direction(Direction::Horizontal)
            .constraints([Constraint::Length(15), Constraint::Min(0)])
            .split(filter_chunks[3]);

        f.render_widget(
            Paragraph::new("Free-text Search").style(Style::default().fg(ColorScheme::GRAY_TEXT)),
            search_layout[0],
        );

        let search_style = if self.filter_input_mode {
            Style::default().fg(ColorScheme::CLEAN_BLUE)
        } else {
            Style::default().fg(ColorScheme::WHITE_TEXT)
        };

        let search_text = if self.session_filter.search_text.is_empty() {
            "Search session notes and context..."
        } else {
            &self.session_filter.search_text
        };

        f.render_widget(
            Paragraph::new(search_text).style(search_style),
            search_layout[1],
        );
    }

    fn render_session_list(&self, f: &mut Frame, area: Rect) {
        let block = Block::default()
            .borders(Borders::ALL)
            .border_style(Style::default().fg(ColorScheme::GRAY_TEXT));

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

        // Header row
        let header_row = Row::new(vec![
            Cell::from("DATE").style(Style::default().add_modifier(Modifier::BOLD)),
            Cell::from("PROJECT").style(Style::default().add_modifier(Modifier::BOLD)),
            Cell::from("DURATION").style(Style::default().add_modifier(Modifier::BOLD)),
            Cell::from("START").style(Style::default().add_modifier(Modifier::BOLD)),
            Cell::from("END").style(Style::default().add_modifier(Modifier::BOLD)),
            Cell::from("STATUS").style(Style::default().add_modifier(Modifier::BOLD)),
        ])
        .style(Style::default().fg(ColorScheme::GRAY_TEXT))
        .bottom_margin(1);

        // Create sample session rows
        let rows: Vec<Row> = self
            .history_sessions
            .iter()
            .enumerate()
            .map(|(i, session)| {
                let is_selected = i == self.selected_session_index;
                let style = if is_selected {
                    Style::default()
                        .bg(ColorScheme::CLEAN_BLUE)
                        .fg(Color::Black)
                } else {
                    Style::default().fg(ColorScheme::WHITE_TEXT)
                };

                let status = if session.end_time.is_some() {
                    "[✓] Completed"
                } else {
                    "[▶] Running"
                };

                let start_time = session
                    .start_time
                    .with_timezone(&Local)
                    .format("%H:%M")
                    .to_string();
                let end_time = if let Some(end) = session.end_time {
                    end.with_timezone(&Local).format("%H:%M").to_string()
                } else {
                    "--:--".to_string()
                };

                let duration = if let Some(_) = session.end_time {
                    let duration_secs =
                        (session.start_time.timestamp() - session.start_time.timestamp()).abs();
                    Formatter::format_duration(duration_secs)
                } else {
                    "0h 0m".to_string()
                };

                Row::new(vec![
                    Cell::from(
                        session
                            .start_time
                            .with_timezone(&Local)
                            .format("%Y-%m-%d")
                            .to_string(),
                    ),
                    Cell::from("Project Phoenix"), // TODO: Get actual project name
                    Cell::from(duration),
                    Cell::from(start_time),
                    Cell::from(end_time),
                    Cell::from(status),
                ])
                .style(style)
            })
            .collect();

        if rows.is_empty() {
            // Show sample data
            let sample_rows = vec![
                Row::new(vec![
                    Cell::from("2023-10-26"),
                    Cell::from("Project Phoenix"),
                    Cell::from("2h 15m"),
                    Cell::from("09:03"),
                    Cell::from("11:18"),
                    Cell::from("[✓] Completed"),
                ])
                .style(
                    Style::default()
                        .bg(ColorScheme::CLEAN_BLUE)
                        .fg(Color::Black),
                ),
                Row::new(vec![
                    Cell::from("2023-10-26"),
                    Cell::from("Internal Tools"),
                    Cell::from("0h 45m"),
                    Cell::from("11:30"),
                    Cell::from("12:15"),
                    Cell::from("[✓] Completed"),
                ]),
                Row::new(vec![
                    Cell::from("2023-10-25"),
                    Cell::from("Project Phoenix"),
                    Cell::from("4h 05m"),
                    Cell::from("13:00"),
                    Cell::from("17:05"),
                    Cell::from("[✓] Completed"),
                ]),
                Row::new(vec![
                    Cell::from("2023-10-25"),
                    Cell::from("Client Support"),
                    Cell::from("1h 00m"),
                    Cell::from("10:00"),
                    Cell::from("11:00"),
                    Cell::from("[✓] Completed"),
                ]),
                Row::new(vec![
                    Cell::from("2023-10-24"),
                    Cell::from("Project Phoenix"),
                    Cell::from("8h 00m"),
                    Cell::from("09:00"),
                    Cell::from("17:00"),
                    Cell::from("[✓] Completed"),
                ]),
                Row::new(vec![
                    Cell::from("2023-10-27"),
                    Cell::from("Project Nova"),
                    Cell::from("0h 22m"),
                    Cell::from("14:00"),
                    Cell::from("--:--"),
                    Cell::from("[▶] Running"),
                ]),
            ];

            let table = Table::new(sample_rows).header(header_row).widths(&[
                Constraint::Length(12),
                Constraint::Min(15),
                Constraint::Length(10),
                Constraint::Length(8),
                Constraint::Length(8),
                Constraint::Min(12),
            ]);

            f.render_widget(table, inner_area);
        }
    }

    fn render_session_details(&self, f: &mut Frame, area: Rect) {
        let block = Block::default()
            .borders(Borders::ALL)
            .title(" Session Details ")
            .border_style(Style::default().fg(ColorScheme::GRAY_TEXT));

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

        let details_chunks = Layout::default()
            .direction(Direction::Vertical)
            .constraints([
                Constraint::Length(3), // Session notes
                Constraint::Length(2), // Tags
                Constraint::Length(3), // Context
            ])
            .split(inner_area);

        // Session notes
        f.render_widget(
            Paragraph::new("SESSION NOTES\n\nWorked on the new authentication flow.\nImplemented JWT token refresh logic and fixed\nthe caching issue on the user profile page.\nReady for QA review.")
                .style(Style::default().fg(ColorScheme::WHITE_TEXT))
                .wrap(ratatui::widgets::Wrap { trim: true }),
            details_chunks[0],
        );

        // Tags
        let tag_spans = vec![
            Span::styled(
                " #backend ",
                Style::default()
                    .fg(Color::Black)
                    .bg(ColorScheme::CLEAN_BLUE),
            ),
            Span::raw(" "),
            Span::styled(
                " #auth ",
                Style::default()
                    .fg(Color::Black)
                    .bg(ColorScheme::CLEAN_BLUE),
            ),
            Span::raw(" "),
            Span::styled(
                " #bugfix ",
                Style::default()
                    .fg(Color::Black)
                    .bg(ColorScheme::CLEAN_BLUE),
            ),
        ];

        f.render_widget(
            Paragraph::new(vec![Line::from("TAGS"), Line::from(tag_spans)])
                .style(Style::default().fg(ColorScheme::WHITE_TEXT)),
            details_chunks[1],
        );

        // Context
        let context_chunks = Layout::default()
            .direction(Direction::Vertical)
            .constraints([Constraint::Length(1), Constraint::Min(0)])
            .split(details_chunks[2]);

        f.render_widget(
            Paragraph::new("CONTEXT").style(Style::default().fg(ColorScheme::WHITE_TEXT)),
            context_chunks[0],
        );

        let context_layout = Layout::default()
            .direction(Direction::Horizontal)
            .constraints([Constraint::Percentage(50), Constraint::Percentage(50)])
            .split(context_chunks[1]);

        f.render_widget(
            Paragraph::new("Git\nBranch:\nIssue ID:\nCommit:")
                .style(Style::default().fg(ColorScheme::GRAY_TEXT)),
            context_layout[0],
        );
        f.render_widget(
            Paragraph::new("feature/PHX-123-auth\nPHX-123\na1b2c3d")
                .style(Style::default().fg(ColorScheme::WHITE_TEXT)),
            context_layout[1],
        );
    }

    fn render_session_actions(&self, f: &mut Frame, area: Rect) {
        let button_layout = Layout::default()
            .direction(Direction::Horizontal)
            .constraints([
                Constraint::Percentage(25),
                Constraint::Percentage(25),
                Constraint::Percentage(25),
                Constraint::Percentage(25),
            ])
            .split(area);

        let buttons = [
            ("[ Edit ]", ColorScheme::GRAY_TEXT),
            ("[ Duplicate ]", ColorScheme::GRAY_TEXT),
            ("[ Delete ]", Color::Red),
            ("", ColorScheme::GRAY_TEXT),
        ];

        for (i, (text, color)) in buttons.iter().enumerate() {
            if !text.is_empty() {
                f.render_widget(
                    Paragraph::new(*text)
                        .alignment(Alignment::Center)
                        .style(Style::default().fg(*color)),
                    button_layout[i],
                );
            }
        }
    }

    fn render_history_summary(&self, f: &mut Frame, area: Rect) {
        let block = Block::default()
            .borders(Borders::ALL)
            .title(" Summary ")
            .border_style(Style::default().fg(ColorScheme::GRAY_TEXT));

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

        f.render_widget(
            Paragraph::new("Showing 7 of 128 sessions. Total Duration: 17h 40m")
                .style(Style::default().fg(ColorScheme::WHITE_TEXT))
                .alignment(Alignment::Center),
            inner_area,
        );
    }

    fn render_project_grid(&mut self, f: &mut Frame) {
        let area = f.size();

        let main_layout = Layout::default()
            .direction(Direction::Vertical)
            .constraints([
                Constraint::Length(3), // Header
                Constraint::Min(10),   // Project grid
                Constraint::Length(3), // Stats summary
                Constraint::Length(1), // Bottom hints
            ])
            .split(area);

        // Header
        f.render_widget(
            Paragraph::new("Project Dashboard")
                .style(
                    Style::default()
                        .fg(ColorScheme::CLEAN_BLUE)
                        .add_modifier(Modifier::BOLD),
                )
                .block(
                    Block::default()
                        .borders(Borders::BOTTOM)
                        .border_style(Style::default().fg(ColorScheme::GRAY_TEXT)),
                ),
            main_layout[0],
        );

        // Project grid area
        self.render_project_cards(f, main_layout[1]);

        // Stats summary
        self.render_project_stats_summary(f, main_layout[2]);

        // Bottom hints
        let hints = vec![
            ("↑/↓/←/→", "Navigate"),
            ("Enter", "Select"),
            ("Tab", "Next View"),
            ("q", "Quit"),
        ];

        let spans: Vec<Span> = hints
            .iter()
            .flat_map(|(key, desc)| {
                vec![
                    Span::styled(
                        format!(" {} ", key),
                        Style::default()
                            .fg(Color::Yellow)
                            .add_modifier(Modifier::BOLD),
                    ),
                    Span::styled(format!("{} ", desc), Style::default().fg(Color::DarkGray)),
                ]
            })
            .collect();

        let line = Line::from(spans);
        let block = Block::default()
            .borders(Borders::TOP)
            .border_style(Style::default().fg(Color::DarkGray));
        Paragraph::new(line)
            .block(block)
            .render(main_layout[3], f.buffer_mut());
    }

    fn render_project_cards(&mut self, f: &mut Frame, area: Rect) {
        if self.available_projects.is_empty() {
            // Show empty state
            let empty_block = Block::default()
                .borders(Borders::ALL)
                .border_style(Style::default().fg(ColorScheme::GRAY_TEXT))
                .title(" No Projects Found ");

            let empty_area = self.centered_rect(50, 30, area);
            f.render_widget(empty_block.clone(), empty_area);

            let inner = empty_block.inner(empty_area);
            f.render_widget(
                Paragraph::new("No projects available.\n\nStart a session to create a project.")
                    .alignment(Alignment::Center)
                    .style(Style::default().fg(ColorScheme::GRAY_TEXT)),
                inner,
            );
            return;
        }

        // Calculate grid layout
        let margin = 2;
        let card_height = 8;
        let card_spacing = 1;

        // Calculate how many rows we can fit
        let available_height = area.height.saturating_sub(margin * 2);
        let total_rows =
            (self.available_projects.len() + self.projects_per_row - 1) / self.projects_per_row;
        let visible_rows =
            (available_height / (card_height + card_spacing)).min(total_rows as u16) as usize;

        // Render visible rows
        for row in 0..visible_rows {
            let y_offset = margin + row as u16 * (card_height + card_spacing);

            // Create horizontal layout for this row
            let row_area = Rect::new(area.x, area.y + y_offset, area.width, card_height);
            let card_constraints = vec![
                Constraint::Percentage(100 / self.projects_per_row as u16);
                self.projects_per_row
            ];
            let row_layout = Layout::default()
                .direction(Direction::Horizontal)
                .constraints(card_constraints)
                .margin(1)
                .split(row_area);

            // Render cards in this row
            for col in 0..self.projects_per_row {
                let project_index = row * self.projects_per_row + col;
                if project_index >= self.available_projects.len() {
                    break;
                }

                let is_selected =
                    row == self.selected_project_row && col == self.selected_project_col;
                self.render_project_card(f, row_layout[col], project_index, is_selected);
            }
        }
    }

    fn render_project_card(
        &self,
        f: &mut Frame,
        area: Rect,
        project_index: usize,
        is_selected: bool,
    ) {
        if let Some(project) = self.available_projects.get(project_index) {
            // Card styling based on selection
            let border_style = if is_selected {
                Style::default().fg(ColorScheme::CLEAN_BLUE)
            } else {
                Style::default().fg(ColorScheme::GRAY_TEXT)
            };

            let bg_color = if is_selected {
                ColorScheme::CLEAN_BG
            } else {
                Color::Black
            };

            let card_block = Block::default()
                .borders(Borders::ALL)
                .border_style(border_style)
                .style(Style::default().bg(bg_color));

            f.render_widget(card_block.clone(), area);

            let inner_area = card_block.inner(area);
            let card_layout = Layout::default()
                .direction(Direction::Vertical)
                .constraints([
                    Constraint::Length(1), // Project name
                    Constraint::Length(1), // Path
                    Constraint::Length(1), // Spacer
                    Constraint::Length(2), // Stats
                    Constraint::Length(1), // Status
                ])
                .split(inner_area);

            // Project name
            let name = if project.name.len() > 20 {
                format!("{}...", &project.name[..17])
            } else {
                project.name.clone()
            };

            f.render_widget(
                Paragraph::new(name)
                    .style(
                        Style::default()
                            .fg(ColorScheme::WHITE_TEXT)
                            .add_modifier(Modifier::BOLD),
                    )
                    .alignment(Alignment::Center),
                card_layout[0],
            );

            // Path (shortened)
            let path_str = project.path.to_string_lossy();
            let short_path = if path_str.len() > 25 {
                format!("...{}", &path_str[path_str.len() - 22..])
            } else {
                path_str.to_string()
            };

            f.render_widget(
                Paragraph::new(short_path)
                    .style(Style::default().fg(ColorScheme::GRAY_TEXT))
                    .alignment(Alignment::Center),
                card_layout[1],
            );

            // Stats placeholder - in real implementation, we'd fetch these
            let stats_layout = Layout::default()
                .direction(Direction::Horizontal)
                .constraints([Constraint::Percentage(50), Constraint::Percentage(50)])
                .split(card_layout[3]);

            f.render_widget(
                Paragraph::new("Sessions\n42")
                    .style(Style::default().fg(ColorScheme::WHITE_TEXT))
                    .alignment(Alignment::Center),
                stats_layout[0],
            );

            f.render_widget(
                Paragraph::new("Time\n24h 15m")
                    .style(Style::default().fg(ColorScheme::WHITE_TEXT))
                    .alignment(Alignment::Center),
                stats_layout[1],
            );

            // Status
            let status = if project.is_archived {
                (" Archived ", Color::Red)
            } else {
                (" Active ", ColorScheme::CLEAN_GREEN)
            };

            f.render_widget(
                Paragraph::new(status.0)
                    .style(Style::default().fg(status.1))
                    .alignment(Alignment::Center),
                card_layout[4],
            );
        }
    }

    fn render_project_stats_summary(&self, f: &mut Frame, area: Rect) {
        let block = Block::default()
            .borders(Borders::ALL)
            .title(" Summary ")
            .border_style(Style::default().fg(ColorScheme::GRAY_TEXT));

        f.render_widget(block.clone(), area);

        let inner = block.inner(area);
        let stats_layout = Layout::default()
            .direction(Direction::Horizontal)
            .constraints([
                Constraint::Percentage(25),
                Constraint::Percentage(25),
                Constraint::Percentage(25),
                Constraint::Percentage(25),
            ])
            .split(inner);

        let total_projects = self.available_projects.len();
        let active_projects = self
            .available_projects
            .iter()
            .filter(|p| !p.is_archived)
            .count();
        let archived_projects = total_projects - active_projects;

        let stats = [
            ("Total Projects", total_projects.to_string()),
            ("Active", active_projects.to_string()),
            ("Archived", archived_projects.to_string()),
            (
                "Selected",
                format!(
                    "{}/{}",
                    self.selected_project_row * self.projects_per_row
                        + self.selected_project_col
                        + 1,
                    total_projects
                ),
            ),
        ];

        for (i, (label, value)) in stats.iter().enumerate() {
            let content = Paragraph::new(vec![
                Line::from(Span::styled(
                    *label,
                    Style::default().fg(ColorScheme::GRAY_TEXT),
                )),
                Line::from(Span::styled(
                    value.as_str(),
                    Style::default()
                        .fg(ColorScheme::WHITE_TEXT)
                        .add_modifier(Modifier::BOLD),
                )),
            ])
            .alignment(Alignment::Center);

            f.render_widget(content, stats_layout[i]);
        }
    }

    fn render_active_session_panel(
        &self,
        f: &mut Frame,
        area: Rect,
        session: &Option<Session>,
        project: &Option<Project>,
    ) {
        // Use pulsing border color when session is active
        use crate::ui::animations::pulse_color;
        let border_color = if session.is_some() {
            pulse_color(
                ColorScheme::PRIMARY_DASHBOARD,
                ColorScheme::PRIMARY_FOCUS,
                self.pulsing_indicator.start_time.elapsed(),
                Duration::from_millis(2000),
            )
        } else {
            ColorScheme::BORDER_DARK
        };

        let block = Block::default()
            .borders(Borders::ALL)
            .border_style(Style::default().fg(border_color))
            .style(Style::default().bg(ColorScheme::BG_DARK));

        f.render_widget(block.clone(), area);

        let inner_area = block.inner(area);
        let layout = Layout::default()
            .direction(Direction::Vertical)
            .constraints([
                Constraint::Length(1), // "Active Session" header
                Constraint::Length(1), // Spacer
                Constraint::Min(4),    // Content (Project + Status + Timer)
            ])
            .margin(1)
            .split(inner_area);

        // Header
        f.render_widget(
            Paragraph::new("Active Session")
                .style(
                    Style::default()
                        .fg(ColorScheme::TEXT_MAIN)
                        .add_modifier(Modifier::BOLD),
                )
                .block(
                    Block::default()
                        .borders(Borders::BOTTOM)
                        .border_style(Style::default().fg(ColorScheme::BORDER_DARK)),
                ),
            layout[0],
        );

        if let Some(session) = session {
            let project_name = project
                .as_ref()
                .map(|p| p.name.as_str())
                .unwrap_or("Unknown Project");

            let content_layout = Layout::default()
                .direction(Direction::Vertical)
                .constraints([
                    Constraint::Length(3), // Project Name + Status
                    Constraint::Min(3),    // Timer
                ])
                .split(layout[2]);

            // Project Name + Status
            f.render_widget(
                Paragraph::new(vec![
                    Line::from(Span::styled(
                        project_name,
                        Style::default()
                            .fg(ColorScheme::TEXT_MAIN)
                            .add_modifier(Modifier::BOLD)
                            .add_modifier(Modifier::UNDERLINED), // Make it look like a title
                    )),
                    Line::from(Span::styled(
                        "▶ RUNNING",
                        Style::default().fg(ColorScheme::SUCCESS),
                    )),
                ])
                .alignment(Alignment::Center),
                content_layout[0],
            );

            // Timer
            let now = Local::now();
            let elapsed_seconds = (now.timestamp() - session.start_time.timestamp())
                - session.paused_duration.num_seconds();

            let hours = elapsed_seconds / 3600;
            let minutes = (elapsed_seconds % 3600) / 60;
            let seconds = elapsed_seconds % 60;

            // Render large timer digits (simplified for TUI)
            // Ideally we'd use tui-big-text or similar, but standard text is fine for now
            // We'll mimic the design with boxes

            let timer_layout = Layout::default()
                .direction(Direction::Horizontal)
                .constraints([
                    Constraint::Ratio(1, 3),
                    Constraint::Ratio(1, 3),
                    Constraint::Ratio(1, 3),
                ])
                .split(content_layout[1]);

            self.render_timer_digit(f, timer_layout[0], hours, "Hours");
            self.render_timer_digit(f, timer_layout[1], minutes, "Minutes");
            self.render_timer_digit(f, timer_layout[2], seconds, "Seconds");
        } else {
            // Idle State
            f.render_widget(
                Paragraph::new("No Active Session\n\nPress 's' to start tracking")
                    .alignment(Alignment::Center)
                    .style(Style::default().fg(ColorScheme::TEXT_SECONDARY)),
                layout[2],
            );
        }
    }

    fn render_timer_digit(&self, f: &mut Frame, area: Rect, value: i64, label: &str) {
        let block = Block::default()
            .borders(Borders::ALL)
            .border_style(Style::default().fg(ColorScheme::BORDER_DARK))
            .style(Style::default().bg(ColorScheme::PANEL_DARK));

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

        let layout = Layout::default()
            .direction(Direction::Vertical)
            .constraints([
                Constraint::Min(1),    // Digit
                Constraint::Length(1), // Label
            ])
            .split(inner);

        f.render_widget(
            Paragraph::new(format!("{:02}", value))
                .alignment(Alignment::Center)
                .style(
                    Style::default()
                        .fg(ColorScheme::TEXT_MAIN)
                        .add_modifier(Modifier::BOLD),
                ),
            layout[0],
        );

        f.render_widget(
            Paragraph::new(label)
                .alignment(Alignment::Center)
                .style(Style::default().fg(ColorScheme::TEXT_SECONDARY)),
            layout[1],
        );
    }

    fn render_quick_stats(&self, f: &mut Frame, area: Rect, daily_stats: &(i64, i64, i64)) {
        let (_sessions_count, total_seconds, _avg_seconds) = *daily_stats;

        let block = Block::default()
            .borders(Borders::ALL)
            .border_style(Style::default().fg(ColorScheme::BORDER_DARK));

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

        let layout = Layout::default()
            .direction(Direction::Vertical)
            .constraints([
                Constraint::Length(2), // Header
                Constraint::Min(1),    // Stats
            ])
            .split(inner_area);

        // Header
        f.render_widget(
            Paragraph::new("Quick Stats")
                .style(
                    Style::default()
                        .fg(ColorScheme::TEXT_MAIN)
                        .add_modifier(Modifier::BOLD),
                )
                .block(
                    Block::default()
                        .borders(Borders::BOTTOM)
                        .border_style(Style::default().fg(ColorScheme::BORDER_DARK)),
                ),
            layout[0],
        );

        // Stats Grid
        let stats_layout = Layout::default()
            .direction(Direction::Vertical)
            .constraints([
                Constraint::Length(3), // Today
                Constraint::Length(3), // Week
                Constraint::Length(3), // Active Projects
            ])
            .margin(1)
            .split(layout[1]);

        let stats = [
            (
                "Today's Total",
                Formatter::format_duration(total_seconds),
                stats_layout[0],
            ),
            (
                "This Week's Total",
                Formatter::format_duration(self.weekly_stats),
                stats_layout[1],
            ),
            (
                "Active Projects",
                self.available_projects
                    .iter()
                    .filter(|p| !p.is_archived)
                    .count()
                    .to_string(),
                stats_layout[2],
            ),
        ];

        for (label, value, chunk) in stats.iter() {
            let item_block = Block::default()
                .borders(Borders::ALL)
                .border_style(Style::default().fg(ColorScheme::BORDER_DARK))
                .style(Style::default().bg(ColorScheme::PANEL_DARK));

            f.render_widget(item_block.clone(), *chunk);
            let item_inner = item_block.inner(*chunk);

            let item_layout = Layout::default()
                .direction(Direction::Vertical)
                .constraints([
                    Constraint::Length(1), // Label
                    Constraint::Length(1), // Value
                ])
                .split(item_inner);

            f.render_widget(
                Paragraph::new(*label).style(Style::default().fg(ColorScheme::TEXT_SECONDARY)),
                item_layout[0],
            );

            f.render_widget(
                Paragraph::new(value.as_str()).style(
                    Style::default()
                        .fg(ColorScheme::TEXT_MAIN)
                        .add_modifier(Modifier::BOLD),
                ),
                item_layout[1],
            );
        }
    }

    fn render_projects_table(&self, f: &mut Frame, area: Rect) {
        let block = Block::default()
            .borders(Borders::ALL)
            .border_style(Style::default().fg(ColorScheme::BORDER_DARK));

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

        let layout = Layout::default()
            .direction(Direction::Vertical)
            .constraints([
                Constraint::Length(2), // Header
                Constraint::Min(1),    // Table
            ])
            .split(inner_area);

        // Header
        f.render_widget(
            Paragraph::new("Project List")
                .style(
                    Style::default()
                        .fg(ColorScheme::TEXT_MAIN)
                        .add_modifier(Modifier::BOLD),
                )
                .block(
                    Block::default()
                        .borders(Borders::BOTTOM)
                        .border_style(Style::default().fg(ColorScheme::BORDER_DARK)),
                ),
            layout[0],
        );

        // Table
        let header_row = Row::new(vec![
            Cell::from("PROJECT NAME").style(Style::default().fg(ColorScheme::TEXT_SECONDARY)),
            Cell::from("TIME TODAY").style(Style::default().fg(ColorScheme::TEXT_SECONDARY)),
            Cell::from("TOTAL TIME").style(Style::default().fg(ColorScheme::TEXT_SECONDARY)),
            Cell::from("LAST ACTIVITY").style(Style::default().fg(ColorScheme::TEXT_SECONDARY)),
        ])
        .bottom_margin(1);

        let rows: Vec<Row> = self
            .recent_projects
            .iter()
            .map(|p| {
                let time_today = Formatter::format_duration(p.today_seconds);
                let total_time = Formatter::format_duration(p.total_seconds);
                let last_activity = if let Some(last) = p.last_active {
                    let now = chrono::Utc::now();
                    let diff = now - last;
                    if diff.num_days() == 0 {
                        format!("Today, {}", last.with_timezone(&Local).format("%H:%M"))
                    } else if diff.num_days() == 1 {
                        "Yesterday".to_string()
                    } else {
                        format!("{} days ago", diff.num_days())
                    }
                } else {
                    "Never".to_string()
                };

                Row::new(vec![
                    Cell::from(p.project.name.clone()).style(
                        Style::default()
                            .fg(ColorScheme::TEXT_MAIN)
                            .add_modifier(Modifier::BOLD),
                    ),
                    Cell::from(time_today).style(Style::default().fg(if p.today_seconds > 0 {
                        ColorScheme::SUCCESS
                    } else {
                        ColorScheme::TEXT_SECONDARY
                    })),
                    Cell::from(total_time).style(Style::default().fg(ColorScheme::TEXT_SECONDARY)),
                    Cell::from(last_activity)
                        .style(Style::default().fg(ColorScheme::TEXT_SECONDARY)),
                ])
            })
            .collect();

        let table = Table::new(rows)
            .header(header_row)
            .widths(&[
                Constraint::Percentage(30),
                Constraint::Percentage(20),
                Constraint::Percentage(20),
                Constraint::Percentage(30),
            ])
            .column_spacing(1);

        f.render_widget(table, layout[1]);
    }

    fn render_activity_timeline(&self, f: &mut Frame, area: Rect) {
        let block = Block::default()
            .borders(Borders::ALL)
            .border_style(Style::default().fg(ColorScheme::BORDER_DARK));

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

        let layout = Layout::default()
            .direction(Direction::Vertical)
            .constraints([
                Constraint::Length(2), // Header
                Constraint::Min(1),    // Timeline
            ])
            .split(inner_area);

        // Header
        f.render_widget(
            Paragraph::new("Activity Timeline")
                .style(
                    Style::default()
                        .fg(ColorScheme::TEXT_MAIN)
                        .add_modifier(Modifier::BOLD),
                )
                .block(
                    Block::default()
                        .borders(Borders::BOTTOM)
                        .border_style(Style::default().fg(ColorScheme::BORDER_DARK)),
                ),
            layout[0],
        );

        let timeline_area = layout[1];
        let bar_area = Rect::new(
            timeline_area.x,
            timeline_area.y + 1,
            timeline_area.width,
            2, // Height of the bar
        );

        // Draw background bar
        f.render_widget(
            Block::default().style(Style::default().bg(ColorScheme::PANEL_DARK)),
            bar_area,
        );

        // Draw session segments
        let total_width = bar_area.width as f64;
        let seconds_in_day = 86400.0;

        for session in &self.today_sessions {
            let start_seconds = session
                .start_time
                .with_timezone(&Local)
                .num_seconds_from_midnight() as f64;
            let end_seconds = if let Some(end) = session.end_time {
                end.with_timezone(&Local).num_seconds_from_midnight() as f64
            } else {
                Local::now().num_seconds_from_midnight() as f64
            };

            let start_x = (start_seconds / seconds_in_day * total_width).floor() as u16;
            let width =
                ((end_seconds - start_seconds) / seconds_in_day * total_width).ceil() as u16;

            let draw_width = width.min(bar_area.width.saturating_sub(start_x));

            if draw_width > 0 {
                let segment_area = Rect::new(
                    bar_area.x + start_x,
                    bar_area.y,
                    draw_width,
                    bar_area.height,
                );

                let color = if session.end_time.is_none() {
                    ColorScheme::SUCCESS
                } else {
                    ColorScheme::SUCCESS // Just use success color for now
                };

                f.render_widget(
                    Block::default().style(Style::default().bg(color)),
                    segment_area,
                );
            }
        }

        // Time Labels
        let labels_y = bar_area.y + bar_area.height + 1;
        let labels = ["00:00", "06:00", "12:00", "18:00", "24:00"];
        let positions = [0.0, 0.25, 0.5, 0.75, 1.0];

        for (label, pos) in labels.iter().zip(positions.iter()) {
            let x = (timeline_area.x as f64 + (timeline_area.width as f64 * pos)
                - (label.len() as f64 / 2.0)) as u16;
            let x = x
                .max(timeline_area.x)
                .min(timeline_area.x + timeline_area.width - label.len() as u16);

            f.render_widget(
                Paragraph::new(*label).style(Style::default().fg(ColorScheme::TEXT_SECONDARY)),
                Rect::new(x, labels_y, label.len() as u16, 1),
            );
        }
    }

    fn render_project_switcher(&self, f: &mut Frame, area: Rect) {
        let popup_area = self.centered_rect(60, 50, area);

        let block = Block::default()
            .borders(Borders::ALL)
            .border_style(Style::default().fg(ColorScheme::CLEAN_BLUE))
            .title(" Select Project ")
            .title_alignment(Alignment::Center)
            .style(Style::default().bg(ColorScheme::CLEAN_BG));

        f.render_widget(block.clone(), popup_area);

        let list_area = block.inner(popup_area);

        if self.available_projects.is_empty() {
            let no_projects = Paragraph::new("No projects found")
                .alignment(Alignment::Center)
                .style(Style::default().fg(ColorScheme::GRAY_TEXT));
            f.render_widget(no_projects, list_area);
        } else {
            let items: Vec<ListItem> = self
                .available_projects
                .iter()
                .enumerate()
                .map(|(i, p)| {
                    let style = if i == self.selected_project_index {
                        Style::default()
                            .fg(ColorScheme::CLEAN_BG)
                            .bg(ColorScheme::CLEAN_BLUE)
                    } else {
                        Style::default().fg(ColorScheme::WHITE_TEXT)
                    };
                    ListItem::new(format!(" {} ", p.name)).style(style)
                })
                .collect();

            let list = List::new(items);
            f.render_widget(list, list_area);
        }
    }

    fn centered_rect(&self, 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]
    }

    async fn get_current_session(&mut self) -> Result<Option<Session>> {
        if !is_daemon_running() {
            return Ok(None);
        }

        self.ensure_connected().await?;

        let response = self
            .client
            .send_message(&IpcMessage::GetActiveSession)
            .await?;
        match response {
            IpcResponse::ActiveSession(session) => Ok(session),
            IpcResponse::Error(e) => Err(anyhow::anyhow!("Failed to get active session: {}", e)),
            _ => Ok(None),
        }
    }

    async fn get_project_by_session(&mut self, session: &Session) -> Result<Option<Project>> {
        if !is_daemon_running() {
            return Ok(None);
        }

        self.ensure_connected().await?;

        let response = self
            .client
            .send_message(&IpcMessage::GetProject(session.project_id))
            .await?;
        match response {
            IpcResponse::Project(project) => Ok(project),
            IpcResponse::Error(e) => Err(anyhow::anyhow!("Failed to get project: {}", e)),
            _ => Ok(None),
        }
    }

    async fn get_today_stats(&mut self) -> Result<(i64, i64, i64)> {
        // (sessions_count, total_seconds, avg_seconds)
        if !is_daemon_running() {
            return Ok((0, 0, 0));
        }

        self.ensure_connected().await?;

        let today = chrono::Local::now().date_naive();
        let response = self
            .client
            .send_message(&IpcMessage::GetDailyStats(today))
            .await?;
        match response {
            IpcResponse::DailyStats {
                sessions_count,
                total_seconds,
                avg_seconds,
            } => Ok((sessions_count, total_seconds, avg_seconds)),
            IpcResponse::Error(e) => Err(anyhow::anyhow!("Failed to get daily stats: {}", e)),
            _ => Ok((0, 0, 0)),
        }
    }

    async fn get_today_sessions(&mut self) -> Result<Vec<Session>> {
        if !is_daemon_running() {
            return Ok(Vec::new());
        }

        self.ensure_connected().await?;

        let today = chrono::Local::now().date_naive();
        let response = self
            .client
            .send_message(&IpcMessage::GetSessionsForDate(today))
            .await?;
        match response {
            IpcResponse::SessionList(sessions) => Ok(sessions),
            IpcResponse::Error(e) => Err(anyhow::anyhow!("Failed to get sessions: {}", e)),
            _ => Ok(Vec::new()),
        }
    }

    async fn get_history_sessions(&mut self) -> Result<Vec<Session>> {
        if !is_daemon_running() {
            return Ok(Vec::new());
        }

        self.ensure_connected().await?;

        // For now, get a date range of the last 30 days
        let end_date = chrono::Local::now().date_naive();
        let _start_date = end_date - chrono::Duration::days(30);

        // Get sessions for the date range (simplified - in a real implementation,
        // this would use a new IPC message like GetSessionsInRange)
        let mut all_sessions = Vec::new();
        for days_ago in 0..30 {
            let date = end_date - chrono::Duration::days(days_ago);
            if let Ok(IpcResponse::SessionList(sessions)) = self
                .client
                .send_message(&IpcMessage::GetSessionsForDate(date))
                .await
            {
                all_sessions.extend(sessions);
            }
        }

        // Apply filters
        let filtered_sessions: Vec<Session> = all_sessions
            .into_iter()
            .filter(|session| {
                // Apply search filter if set
                if !self.session_filter.search_text.is_empty() {
                    if let Some(notes) = &session.notes {
                        if !notes
                            .to_lowercase()
                            .contains(&self.session_filter.search_text.to_lowercase())
                        {
                            return false;
                        }
                    } else {
                        return false;
                    }
                }
                true
            })
            .collect();

        Ok(filtered_sessions)
    }

    async fn send_activity_heartbeat(&mut self) -> Result<()> {
        if !is_daemon_running() {
            return Ok(());
        }

        self.ensure_connected().await?;

        let _response = self
            .client
            .send_message(&IpcMessage::ActivityHeartbeat)
            .await?;
        Ok(())
    }

    // Helper methods for project switcher navigation

    fn navigate_projects(&mut self, direction: i32) {
        if self.available_projects.is_empty() {
            return;
        }

        let new_index = self.selected_project_index as i32 + direction;
        if new_index >= 0 && new_index < self.available_projects.len() as i32 {
            self.selected_project_index = new_index as usize;
        }
    }

    async fn refresh_projects(&mut self) -> Result<()> {
        if !is_daemon_running() {
            return Ok(());
        }

        self.ensure_connected().await?;

        let response = self.client.send_message(&IpcMessage::ListProjects).await?;
        if let IpcResponse::ProjectList(projects) = response {
            self.available_projects = projects;
            self.selected_project_index = 0;
        }
        Ok(())
    }

    async fn switch_to_selected_project(&mut self) -> Result<()> {
        if let Some(selected_project) = self.available_projects.get(self.selected_project_index) {
            let project_id = selected_project.id.unwrap_or(0);

            self.ensure_connected().await?;

            // Switch to the selected project
            let response = self
                .client
                .send_message(&IpcMessage::SwitchProject(project_id))
                .await?;
            match response {
                IpcResponse::Success => {
                    self.show_project_switcher = false;
                }
                IpcResponse::Error(e) => {
                    return Err(anyhow::anyhow!("Failed to switch project: {}", e))
                }
                _ => return Err(anyhow::anyhow!("Unexpected response")),
            }
        }
        Ok(())
    }

    fn render_header(&self, f: &mut Frame, area: Rect) {
        let time_str = Local::now().format("%Y-%m-%d %H:%M:%S").to_string();

        let header_layout = Layout::default()
            .direction(Direction::Horizontal)
            .constraints([
                Constraint::Min(20), // Title
                Constraint::Min(30), // Date/Time + Daemon Status
            ])
            .split(area);

        // Title
        let title_block = Block::default()
            .borders(Borders::BOTTOM)
            .border_style(Style::default().fg(ColorScheme::BORDER_DARK));

        let title_inner = title_block.inner(header_layout[0]);
        f.render_widget(title_block, header_layout[0]);

        f.render_widget(
            Paragraph::new("Tempo TUI").style(
                Style::default()
                    .fg(ColorScheme::TEXT_MAIN)
                    .add_modifier(Modifier::BOLD),
            ),
            title_inner,
        );

        // Right side: Date/Time + Daemon Status
        let status_block = Block::default()
            .borders(Borders::BOTTOM)
            .border_style(Style::default().fg(ColorScheme::BORDER_DARK));

        let status_inner = status_block.inner(header_layout[1]);
        f.render_widget(status_block, header_layout[1]);

        let status_layout = Layout::default()
            .direction(Direction::Horizontal)
            .constraints([
                Constraint::Min(20),    // Date/Time
                Constraint::Length(15), // Daemon Status
            ])
            .split(status_inner);

        f.render_widget(
            Paragraph::new(time_str)
                .alignment(Alignment::Right)
                .style(Style::default().fg(ColorScheme::TEXT_MAIN)),
            status_layout[0],
        );

        // Daemon status with animated spinner when running
        let daemon_status_line = if is_daemon_running() {
            let spinner_frame = self.animated_spinner.current();
            Line::from(vec![
                Span::raw("Daemon: "),
                Span::styled(
                    spinner_frame,
                    Style::default().fg(ColorScheme::SUCCESS),
                ),
                Span::raw(" "),
                Span::styled(
                    "Running",
                    Style::default()
                        .fg(ColorScheme::SUCCESS)
                        .add_modifier(Modifier::BOLD),
                ),
            ])
        } else {
            Line::from(vec![
                Span::raw("Daemon: "),
                Span::styled(
                    "Offline",
                    Style::default()
                        .fg(ColorScheme::ERROR)
                        .add_modifier(Modifier::BOLD),
                ),
            ])
        };

        f.render_widget(
            Paragraph::new(daemon_status_line)
                .alignment(Alignment::Right),
            status_layout[1],
        );
    }

    fn get_daily_stats(&self) -> &(i64, i64, i64) {
        &self.daily_stats
    }
}
