use ratatui::{
    layout::{Alignment, Constraint, Direction, Layout, Rect},
    style::{Color, Modifier, Style},
    text::{Line, Span},
    widgets::{Block, Borders, Clear, Paragraph, Row, Table, TableState},
    Frame,
};

use chrono::DateTime;

use crate::{
    app::{App, LogViewDayOrder, LogViewGrouping, LogViewPeriod, LogViewSelection, NewEntryMode, Screen},
    state::TimeItem,
};

const ACTIVE_COLOR: Color = Color::Green;

pub fn render(frame: &mut Frame, app: &App) {
    match app.current_screen {
        Screen::Main => render_main(frame, app),
        Screen::Help => render_help(frame, app),
        Screen::ConfigHelp => render_config_help(frame, app),
        Screen::NewEntry => render_new_entry(frame, app),
        Screen::ReassignProject => render_reassign_project(frame, app),
        Screen::LogView => render_log_view(frame, app),
        Screen::LogViewHelp => render_log_view_help(frame, app),
        Screen::AddAnnotation => render_add_annotation(frame, app),
    }
}

fn render_main(frame: &mut Frame, app: &App) {
    // Calculate layout - accounting for bottom bar if needed
    let has_active_timer = app.state.active_timer.is_some();
    let has_status = app.status_message.is_some();
    let show_help_hint = app.config.show_help_hint;

    // Show bottom bar if we have any of: timer, status, or help hint
    let show_bottom_bar = has_active_timer || has_status || show_help_hint;

    let bottom_height = if show_bottom_bar {
        if has_status {
            2  // Need extra line for status
        } else {
            1  // Just tracking or help hint
        }
    } else {
        0
    };

    // Count enabled sections
    let enabled_sections = [
        app.config.show_permanent,
        app.config.show_recurring,
        app.config.show_recent,
    ]
    .iter()
    .filter(|&&x| x)
    .count();

    if enabled_sections == 0 {
        // No sections enabled - show a message
        let block = Block::default()
            .borders(Borders::ALL)
            .title("WAT")
            .style(Style::default().fg(ACTIVE_COLOR));

        let text = Paragraph::new("No sections enabled. Edit config (press 'c') to enable sections.")
            .block(block)
            .style(Style::default().fg(Color::Yellow))
            .alignment(Alignment::Center);

        frame.render_widget(text, frame.size());
        return;
    }

    // Build constraints for enabled sections
    let mut constraints = Vec::new();

    if bottom_height > 0 {
        // Reserve space for bottom bar first, then split remainder among sections
        constraints.push(Constraint::Min(0)); // Sections get remaining space
        constraints.push(Constraint::Length(bottom_height)); // Bottom bar gets fixed height

        let layout = Layout::default()
            .direction(Direction::Vertical)
            .constraints(constraints)
            .split(frame.size());

        // Split the top area among enabled sections
        let section_percentage = 100 / enabled_sections as u16;
        let section_constraints = vec![Constraint::Percentage(section_percentage); enabled_sections];

        let chunks = Layout::default()
            .direction(Direction::Vertical)
            .constraints(section_constraints)
            .split(layout[0]);

        // Render enabled sections
        let mut chunk_idx = 0;

        if app.config.show_permanent {
            render_section(
                frame,
                chunks[chunk_idx],
                "Permanent Items",
                &app.state.permanent_items,
                app.state.current_pane == 0,
                app.state.selected_indices[0],
                app.state.current_column,
                app.config.multi_column,
            );
            chunk_idx += 1;
        }

        if app.config.show_recurring {
            render_section(
                frame,
                chunks[chunk_idx],
                "Recurring Items",
                &app.state.recurring_items,
                app.state.current_pane == 1,
                app.state.selected_indices[1],
                app.state.current_column,
                app.config.multi_column,
            );
            chunk_idx += 1;
        }

        if app.config.show_recent {
            render_section(
                frame,
                chunks[chunk_idx],
                "Ad-Hoc Items",
                &app.state.recent_items,
                app.state.current_pane == 2,
                app.state.selected_indices[2],
                app.state.current_column,
                app.config.multi_column,
            );
        }

        // Render bottom bar
        render_bottom_bar(frame, layout[1], app);
    } else {
        // No bottom bar - just render sections
        let section_percentage = 100 / enabled_sections as u16;
        let constraints = vec![Constraint::Percentage(section_percentage); enabled_sections];

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

        let mut chunk_idx = 0;

        if app.config.show_permanent {
            render_section(
                frame,
                chunks[chunk_idx],
                "Permanent Items",
                &app.state.permanent_items,
                app.state.current_pane == 0,
                app.state.selected_indices[0],
                app.state.current_column,
                app.config.multi_column,
            );
            chunk_idx += 1;
        }

        if app.config.show_recurring {
            render_section(
                frame,
                chunks[chunk_idx],
                "Recurring Items",
                &app.state.recurring_items,
                app.state.current_pane == 1,
                app.state.selected_indices[1],
                app.state.current_column,
                app.config.multi_column,
            );
            chunk_idx += 1;
        }

        if app.config.show_recent {
            render_section(
                frame,
                chunks[chunk_idx],
                "Ad-Hoc Items",
                &app.state.recent_items,
                app.state.current_pane == 2,
                app.state.selected_indices[2],
                app.state.current_column,
                app.config.multi_column,
            );
        }
    }
}

fn render_new_entry(frame: &mut Frame, app: &App) {
    let area = centered_rect(60, 6, frame.size());
    frame.render_widget(Clear, area);

    let chunks = Layout::default()
        .direction(Direction::Vertical)
        .constraints([Constraint::Length(3), Constraint::Length(3)])
        .split(area);

    // Tag input (first)
    let tag_block = Block::default()
        .title("Tag")
        .borders(Borders::ALL)
        .style(
            Style::default().fg(if matches!(app.new_entry_mode, NewEntryMode::Task) {
                ACTIVE_COLOR
            } else {
                Color::White
            }),
        );

    let tag_text = Paragraph::new(app.new_entry_project.as_str()).block(tag_block);

    frame.render_widget(tag_text, chunks[0]);

    // Project input (second)
    let project_block = Block::default()
        .title("Project")
        .borders(Borders::ALL)
        .style(
            Style::default().fg(if matches!(app.new_entry_mode, NewEntryMode::Project) {
                ACTIVE_COLOR
            } else {
                Color::White
            }),
        );

    let project_text = Paragraph::new(app.new_entry_buffer.as_str()).block(project_block);

    frame.render_widget(project_text, chunks[1]);

    // Render command bar
    let bar_area = Rect::new(0, frame.size().height - 1, frame.size().width, 1);

    let command_text = match app.new_entry_mode {
        NewEntryMode::Task => "Enter tag, press Enter to continue",
        NewEntryMode::Project => "Enter project, press Enter to save",
    };

    let command_bar = Paragraph::new(command_text)
        .style(Style::default().fg(Color::White))
        .alignment(Alignment::Left);

    frame.render_widget(command_bar, bar_area);
}

fn render_bottom_bar(frame: &mut Frame, area: Rect, app: &App) {
    // Split the bottom bar into left (tracking indicator) and right (help/status)
    let chunks = Layout::default()
        .direction(Direction::Horizontal)
        .constraints([Constraint::Percentage(70), Constraint::Percentage(30)])
        .split(area);

    // Left side: Tracking indicator (only when actively tracking)
    if let Some((active_item, _)) = &app.state.active_timer {
        let tracking_text = if !active_item.tags.is_empty() {
            format!("❯❯ Tracking {} [{}] ❯❯", active_item.tags.join(", "), active_item.name)
        } else {
            format!("❯❯ Tracking {} ❯❯", active_item.name)
        };

        let tracking = Paragraph::new(tracking_text)
            .alignment(Alignment::Left)
            .style(Style::default().fg(ACTIVE_COLOR).add_modifier(Modifier::BOLD));
        frame.render_widget(tracking, chunks[0]);
    }
    // No else - show nothing when not tracking

    // Right side: Status message or help hint
    if let Some((ref message, _)) = app.status_message {
        let text = Paragraph::new(message.as_str())
            .style(Style::default().fg(Color::Yellow))
            .alignment(Alignment::Right);
        frame.render_widget(text, chunks[1]);
    } else if app.config.show_help_hint {
        render_help_hint(frame, chunks[1]);
    }
}

fn render_help_hint(frame: &mut Frame, area: Rect) {
    let help_hint = Paragraph::new("(?) for help")
        .alignment(Alignment::Right)
        .style(Style::default().fg(Color::DarkGray));
    frame.render_widget(help_hint, area);
}

fn render_help_command_bar(frame: &mut Frame) {
    let commands = vec![("c", "configuration help"), ("q/ESC", "back")];

    let command_text = format!(
        "  {}",
        commands
            .iter()
            .map(|(key, desc)| format!("{} ({})", key, desc))
            .collect::<Vec<_>>()
            .join(" · ")
    );

    let bar_area = Rect::new(
        0,
        frame.size().height.saturating_sub(1),
        frame.size().width,
        1,
    );

    let command_bar = Paragraph::new(command_text)
        .style(Style::default().fg(Color::White))
        .alignment(Alignment::Left);

    frame.render_widget(command_bar, bar_area);
}

fn render_help(frame: &mut Frame, app: &App) {
    let width = frame.size().width.saturating_sub(4).min(60);
    let area = centered_rect(width, frame.size().height.saturating_sub(2), frame.size());

    frame.render_widget(Clear, area);

    let help_text = vec![
        "WAT - Watson Time Tracker Interface",
        "",
        "This tool helps you track time using Watson with a convenient interface.",
        "",
        "The interface is divided into three sections:",
        "1. Permanent Items: Configured tasks that are always available",
        "2. Recurring Items: Frequently used tasks that you might return to",
        "3. Ad-Hoc Items: One-off tasks and quick entries",
        "",
        "Navigation:",
        "- j/k or ↑/↓: Move selection up/down (wraps between sections)",
        "- Ctrl+n/Ctrl+p: Switch between sections (Permanent/Recurring/Ad-Hoc)",
        "- Enter: Start/stop time tracking for selected item",
        "- n: Create a new task in the current section",
        "",
        "Main Commands:",
        "Enter      - Start/stop timer",
        "x          - Delete task from list",
        "p          - Reassign project name",
        "v          - View Watson log",
        "Ctrl+e     - Edit tasks config file",
        "c          - Edit app config file",
        "n          - New task",
        "q          - Quit",
        "?          - Show/hide this help (ESC also works)",
        "",
        "Log View (press 'v'):",
        "Once in log view, you can:",
        "- Switch time periods: d (day), w (week), m (month)",
        "- Toggle grouping: p (by date or by project)",
        "- Toggle day order: r (newest first ↔ oldest first)",
        "- Change selection: h/l (entry → project → day → all)",
        "- Navigate: j/k to move through selections",
        "- Go to top/bottom: g/G (go to first/last entry)",
        "- Edit entry: e (entry level only)",
        "- Delete entry: x (entry level only)",
        "- Copy to clipboard: y (works at all levels)",
        "- Press ? for detailed log view help",
    ];

    let text = help_text.join("\n");

    let block = Block::default()
        .title("Help (j/k to scroll)")
        .borders(Borders::ALL)
        .style(Style::default().fg(Color::White));

    let paragraph = Paragraph::new(text)
        .block(block)
        .style(Style::default().fg(Color::White))
        .scroll((app.help_scroll as u16, 0))
        .wrap(ratatui::widgets::Wrap { trim: true });

    frame.render_widget(paragraph, area);
    render_help_command_bar(frame);
}

fn render_config_help(frame: &mut Frame, app: &App) {
    let width = frame.size().width.saturating_sub(4).min(60);
    let area = centered_rect(width, frame.size().height.saturating_sub(2), frame.size());

    frame.render_widget(Clear, area);

    let help_text = vec![
        "WAT Configuration",
        "",
        "Configuration file location:",
        "  ~/.config/wat/config.yaml",
        "",
        "Available options:",
        "",
        "show_help_hint: true/false",
        "  Default: true",
        "  Shows '(?) for help' hint in the bottom-right corner",
        "",
        "projects: [list of project names]",
        "  Default: [] (empty)",
        "  List of available project names shown when reassigning",
        "  Example: [\"work\", \"personal\", \"client-a\"]",
        "",
        "strict_projects: true/false",
        "  Default: false",
        "  When true, only allows projects from the 'projects' list",
        "  When false, any project name can be used",
        "",
        "multi_column: true/false",
        "  Default: true",
        "  When true, sections with many items display in two columns",
        "  When false, always use single column with scrolling",
        "",
        "show_permanent: true/false",
        "  Default: true",
        "  Show the 'Permanent Items' section",
        "",
        "show_recurring: true/false",
        "  Default: true",
        "  Show the 'Recurring Items' section",
        "",
        "show_recent: true/false",
        "  Default: true",
        "  Show the 'Ad-Hoc Items' section",
        "",
        "show_time_gaps: true/false",
        "  Default: true",
        "  In log view (by date), show '---' separator for 5+ minute gaps",
        "",
        "Example configuration:",
        "---",
        "show_help_hint: true",
        "strict_projects: false",
        "multi_column: true",
        "show_permanent: true",
        "show_recurring: true",
        "show_recent: false",
        "show_time_gaps: true",
        "projects:",
        "  - work",
        "  - personal",
        "  - open-source",
        "",
        "Note: The config file is created automatically on first run.",
        "Edit it with 'c' from the main screen or manually with your editor.",
    ];

    let text = help_text.join("\n");

    let block = Block::default()
        .title("Configuration Help (j/k to scroll)")
        .borders(Borders::ALL)
        .style(Style::default().fg(Color::White));

    let paragraph = Paragraph::new(text)
        .block(block)
        .style(Style::default().fg(Color::White))
        .scroll((app.help_scroll as u16, 0))
        .wrap(ratatui::widgets::Wrap { trim: true });

    frame.render_widget(paragraph, area);
    render_help_command_bar(frame);
}

fn render_section(
    frame: &mut Frame,
    area: Rect,
    title: &str,
    items: &[TimeItem],
    is_active: bool,
    selected: usize,
    current_column: usize,
    multi_column: bool,
) {
    let block = Block::default()
        .borders(Borders::ALL)
        .title(title)
        .style(Style::default().fg(if is_active { ACTIVE_COLOR } else { Color::White }));

    // Check if we should use two-column layout
    let use_two_columns = multi_column && items.len() > 6;

    if use_two_columns {
        // Split items into two halves
        let mid_point = (items.len() + 1) / 2;
        let left_items = &items[..mid_point];
        let right_items = &items[mid_point..];

        // Create inner area for columns
        let inner_area = block.inner(area);
        let columns = Layout::default()
            .direction(Direction::Horizontal)
            .constraints([Constraint::Percentage(50), Constraint::Percentage(50)])
            .split(inner_area);

        // Render the block first
        frame.render_widget(block, area);

        // Calculate which row to show (same for both columns)
        let row_in_column = if current_column == 0 {
            selected  // Left column: row = selected index
        } else {
            selected.saturating_sub(mid_point)  // Right column: row = index - mid_point
        };

        // Left column
        let left_rows: Vec<Row> = left_items
            .iter()
            .map(|item| {
                let display = if !item.tags.is_empty() {
                    format!("{} [{}]", item.tags.join(", "), item.name)
                } else {
                    item.name.clone()
                };
                Row::new(vec![display])
            })
            .collect();

        let left_table = Table::new(left_rows)
            .widths(&[Constraint::Percentage(100)])
            .highlight_style(if is_active && current_column == 0 {
                Style::default()
                    .fg(ACTIVE_COLOR)
                    .add_modifier(Modifier::REVERSED)
            } else {
                Style::default()  // No highlight for inactive column
            });

        // Both columns use the same row offset for synchronized scrolling
        let mut left_state = TableState::default();
        if !left_items.is_empty() {
            // Always select the same row to force scrolling, but only highlight if active
            left_state.select(Some(row_in_column.min(left_items.len() - 1)));
        }

        // Right column
        let right_rows: Vec<Row> = right_items
            .iter()
            .map(|item| {
                let display = if !item.tags.is_empty() {
                    format!("{} [{}]", item.tags.join(", "), item.name)
                } else {
                    item.name.clone()
                };
                Row::new(vec![display])
            })
            .collect();

        let right_table = Table::new(right_rows)
            .widths(&[Constraint::Percentage(100)])
            .highlight_style(if is_active && current_column == 1 {
                Style::default()
                    .fg(ACTIVE_COLOR)
                    .add_modifier(Modifier::REVERSED)
            } else {
                Style::default()  // No highlight for inactive column
            });

        let mut right_state = TableState::default();
        if !right_items.is_empty() {
            // Always select the same row to force scrolling, but only highlight if active
            right_state.select(Some(row_in_column.min(right_items.len() - 1)));
        }

        frame.render_stateful_widget(left_table, columns[0], &mut left_state);
        frame.render_stateful_widget(right_table, columns[1], &mut right_state);
    } else {
        // Single column mode
        let rows: Vec<Row> = items
            .iter()
            .map(|item| {
                let display = if !item.tags.is_empty() {
                    format!("{} [{}]", item.tags.join(", "), item.name)
                } else {
                    item.name.clone()
                };
                Row::new(vec![display])
            })
            .collect();

        let table = Table::new(rows)
            .block(block)
            .widths(&[Constraint::Percentage(100)])
            .highlight_style(
                Style::default()
                    .fg(ACTIVE_COLOR)
                    .add_modifier(Modifier::REVERSED),
            );

        let mut table_state = TableState::default();
        if !items.is_empty() && is_active {
            table_state.select(Some(selected.min(items.len() - 1)));
        }

        frame.render_stateful_widget(table, area, &mut table_state);
    }
}

fn centered_rect(width: u16, height: u16, r: Rect) -> Rect {
    let x = (r.width.saturating_sub(width)) / 2;
    let y = (r.height.saturating_sub(height)) / 2;

    Rect {
        x: r.x + x,
        y: r.y + y,
        width: width.min(r.width),
        height: height.min(r.height),
    }
}

fn render_reassign_project(frame: &mut Frame, app: &App) {
    let area = centered_rect(60, 5, frame.size());
    frame.render_widget(Clear, area);

    let chunks = Layout::default()
        .direction(Direction::Vertical)
        .constraints([Constraint::Length(3), Constraint::Length(2)])
        .split(area);

    // Get current item to show in title
    let items = match app.state.current_pane {
        0 => &app.state.permanent_items,
        1 => &app.state.recurring_items,
        2 => &app.state.recent_items,
        _ => &app.state.permanent_items,
    };

    let current_item_display = items
        .get(app.state.selected_indices[app.state.current_pane])
        .map(|item| {
            if !item.tags.is_empty() {
                format!("{} [{}]", item.tags.join(", "), item.name)
            } else {
                item.name.clone()
            }
        })
        .unwrap_or_default();

    // Project input
    let project_block = Block::default()
        .title(format!("Reassign Project for: {}", current_item_display))
        .borders(Borders::ALL)
        .style(Style::default().fg(ACTIVE_COLOR));

    let project_text = if !app.config.projects.is_empty() {
        format!(
            "{} (available: {})",
            app.reassign_project_buffer,
            app.config.projects.join(", ")
        )
    } else {
        app.reassign_project_buffer.clone()
    };

    let project_paragraph = Paragraph::new(project_text).block(project_block);

    frame.render_widget(project_paragraph, chunks[0]);

    // Help text
    let help_text = Paragraph::new("Enter new project name, press Enter to save, Esc to cancel")
        .style(Style::default().fg(Color::DarkGray))
        .alignment(Alignment::Center);

    frame.render_widget(help_text, chunks[1]);
}

fn render_log_view(frame: &mut Frame, app: &App) {
    let area = frame.size();

    // Create the main content area (leave space for command bar at bottom)
    let chunks = Layout::default()
        .direction(Direction::Vertical)
        .constraints([Constraint::Min(3), Constraint::Length(1)])
        .split(area);

    let period_str = match app.log_view_period {
        LogViewPeriod::Day => "Day",
        LogViewPeriod::Week => "Week",
        LogViewPeriod::Month => "31 Days",
    };

    let grouping_str = match app.log_view_grouping {
        LogViewGrouping::ByDate => "by Date",
        LogViewGrouping::ByProject => "by Project",
    };

    let order_str = match app.log_view_day_order {
        LogViewDayOrder::Chronological => "↑",
        LogViewDayOrder::ReverseChronological => "↓",
    };

    let rounded_indicator = if app.log_view_rounded { " [ROUNDED]" } else { "" };
    let title = format!("Watson Log - {} View ({}) [{}]{}", period_str, grouping_str, order_str, rounded_indicator);

    let block = Block::default()
        .title(title)
        .borders(Borders::ALL)
        .style(Style::default().fg(ACTIVE_COLOR));

    // Build text lines with selection highlighting based on selection level
    let text_lines: Vec<Line> = {
        // Pre-calculate which line indices should be highlighted
        let mut selected_date = String::new();
        let mut selected_project = String::new();
        let mut frame_count = 0;
        let mut selected_line_start = 0;
        let mut selected_line_end = 0;

        // First pass: find the date/project containing the selected frame
        let mut current_date = String::new();
        let mut current_project = String::new();

        // Determine what counts as an entry based on grouping mode
        let is_by_project = matches!(app.log_view_grouping, LogViewGrouping::ByProject);

        for (_idx, line) in app.log_view_content.iter().enumerate() {
            if !line.starts_with("    ") && !line.is_empty() && !line.starts_with("  ") {
                current_date = line.clone();
            } else if line.starts_with("  ") && !line.starts_with("    ") {
                current_project = line.clone();
            }

            // Only count actual entries (not all tab-indented lines)
            let is_entry = if is_by_project {
                line.starts_with("        ")  // 8 spaces for ByProject
            } else {
                line.starts_with("    ") && !line.starts_with("        ")  // 4 spaces for ByDate
            };

            if is_entry {
                if frame_count == app.log_view_selected {
                    selected_date = current_date.clone();
                    selected_project = current_project.clone();
                    break;
                }
                frame_count += 1;
            }
        }

        // Second pass: determine the range of lines to highlight
        match app.log_view_selection_level {
            LogViewSelection::Entry => {
                // Just find the specific entry line
                frame_count = 0;
                for (idx, line) in app.log_view_content.iter().enumerate() {
                    // Use is_entry_line logic which excludes separator lines
                    let is_entry = if is_by_project {
                        line.starts_with("        ")
                    } else {
                        line.starts_with("    ") && !line.starts_with("        ") && line.trim() != "---"
                    };

                    if is_entry {
                        if frame_count == app.log_view_selected {
                            selected_line_start = idx;
                            selected_line_end = idx;
                            break;
                        }
                        frame_count += 1;
                    }
                }
            }
            LogViewSelection::Project => {
                // Find the range of the selected project (within the same day)
                let mut in_target_project = false;
                current_date = String::new();

                for (idx, line) in app.log_view_content.iter().enumerate() {
                    if !line.starts_with("    ") && !line.is_empty() && !line.starts_with("  ") {
                        current_date = line.clone();
                        if in_target_project {
                            break; // End of project group
                        }
                    } else if line.starts_with("  ") && !line.starts_with("    ") {
                        if current_date == selected_date && line == &selected_project {
                            selected_line_start = idx;
                            in_target_project = true;
                        } else if in_target_project {
                            break; // Different project
                        }
                    } else if in_target_project && line.starts_with("    ") {
                        selected_line_end = idx;
                    }
                }
            }
            LogViewSelection::Day => {
                // Find the range of the selected day
                let mut in_target_day = false;

                for (idx, line) in app.log_view_content.iter().enumerate() {
                    if !line.starts_with("    ") && !line.is_empty() && !line.starts_with("  ") {
                        if line == &selected_date {
                            selected_line_start = idx;
                            in_target_day = true;
                        } else if in_target_day {
                            break; // End of day
                        }
                    } else if in_target_day && !line.is_empty() {
                        selected_line_end = idx;
                    }
                }
            }
            LogViewSelection::All => {
                // Select everything
                selected_line_start = 0;
                selected_line_end = app.log_view_content.len().saturating_sub(1);
            }
        }

        // Third pass: render with highlighting and overlap detection
        let is_by_date = matches!(app.log_view_grouping, LogViewGrouping::ByDate);

        // Pre-calculate overlaps for efficiency - check consecutive entries within same day
        let mut overlap_entry_indices = std::collections::HashSet::new();
        if is_by_date && app.log_view_frame_indices.len() > 1 {
            // Track which day we're in to avoid comparing across days
            let mut current_day_start_entry = 0;
            let mut in_day = false;

            for (line_idx, line) in app.log_view_content.iter().enumerate() {
                // New day header
                if !line.starts_with("    ") && !line.is_empty() && !line.starts_with("  ") {
                    current_day_start_entry = app.log_view_content[..line_idx]
                        .iter()
                        .filter(|l| l.starts_with("    ") && !l.is_empty() && l.trim() != "---")
                        .count();
                    in_day = true;
                } else if in_day && line.starts_with("    ") && !line.is_empty() && line.trim() != "---" {
                    // This is an entry line
                    let entry_idx = app.log_view_content[..=line_idx]
                        .iter()
                        .filter(|l| l.starts_with("    ") && !l.is_empty() && l.trim() != "---")
                        .count()
                        .saturating_sub(1);

                    // Only check overlap if not the first entry of the day
                    if entry_idx > current_day_start_entry {
                        let current_frame_idx = app.log_view_frame_indices[entry_idx];
                        let prev_frame_idx = app.log_view_frame_indices[entry_idx - 1];

                        if let (Some(current), Some(prev)) = (
                            app.log_view_frames.get(current_frame_idx),
                            app.log_view_frames.get(prev_frame_idx),
                        ) {
                            if let (Ok(curr_start), Ok(prev_stop)) = (
                                DateTime::parse_from_rfc3339(&current.start),
                                DateTime::parse_from_rfc3339(&prev.stop),
                            ) {
                                // Overlap if current starts before previous ends
                                if curr_start < prev_stop {
                                    overlap_entry_indices.insert(entry_idx);
                                }
                            }
                        }
                    }
                }
            }
        }

        app.log_view_content
            .iter()
            .enumerate()
            .map(|(idx, line)| {
                let is_selected = idx >= selected_line_start && idx <= selected_line_end;

                // Skip styling for separator lines
                let is_separator = line.trim() == "---";

                // Check if this line corresponds to an overlapping entry
                let has_overlap = if !is_separator && is_by_date && line.starts_with("    ") && !line.is_empty() {
                    // Count which entry this is (0-based in display order)
                    // Only count actual entry lines, not separator lines
                    let entry_idx = app.log_view_content[..=idx]
                        .iter()
                        .filter(|l| l.starts_with("    ") && !l.is_empty() && l.trim() != "---")
                        .count()
                        .saturating_sub(1);

                    overlap_entry_indices.contains(&entry_idx)
                } else {
                    false
                };

                let style = if is_separator {
                    Style::default().fg(Color::DarkGray)  // Dim the separator
                } else if is_selected {
                    Style::default()
                        .fg(ACTIVE_COLOR)
                        .add_modifier(Modifier::REVERSED)
                } else if has_overlap {
                    Style::default().fg(Color::Yellow)
                } else {
                    Style::default().fg(Color::White)
                };

                Line::from(vec![Span::styled(line.clone(), style)])
            })
            .collect()
    };

    // Use the scroll position calculated by the app
    let paragraph = Paragraph::new(text_lines)
        .block(block)
        .wrap(ratatui::widgets::Wrap { trim: false })
        .scroll((app.log_view_scroll as u16, 0));

    frame.render_widget(paragraph, chunks[0]);

    // Render help hint at bottom if enabled
    if app.config.show_help_hint {
        render_help_hint(frame, chunks[1]);
    }
}

fn render_log_view_help(frame: &mut Frame, app: &App) {
    let width = frame.size().width.saturating_sub(4).min(60);
    let area = centered_rect(width, frame.size().height.saturating_sub(2), frame.size());

    frame.render_widget(Clear, area);

    let help_text = vec![
        "Watson Log Viewer Help",
        "",
        "This view displays your Watson time tracking logs with various options",
        "for viewing and managing your tracked time.",
        "",
        "Time Periods:",
        "- d: Switch to Day view (current day)",
        "- w: Switch to Week view (current week)",
        "- m: Switch to Month view (last 31 days)",
        "",
        "Grouping:",
        "- p: Toggle between grouping by Date or by Project",
        "  - By Date: Shows all entries chronologically",
        "  - By Project: Groups entries by project within each date",
        "",
        "Day Order:",
        "- r: Toggle day order between newest first (↓) and oldest first (↑)",
        "  - Days are shown in the chosen order",
        "  - Entries within each day are always chronological (earliest to latest)",
        "",
        "Display Mode:",
        "- R: Toggle 15-minute rounding (for estimates/reports)",
        "  - When enabled, all times are rounded to nearest 15-minute interval",
        "  - Shows [ROUNDED] indicator in title bar",
        "  - Affects display and clipboard copy, does not modify Watson data",
        "",
        "Navigation:",
        "- j/k or ↑/↓: Navigate selection",
        "  - At Entry level: Move to next/previous entry",
        "  - At Project level: Jump to next/previous project group",
        "  - At Day level: Jump to next/previous day",
        "  - At All level: No navigation (entire view selected)",
        "- h/l or ←/→: Change selection level",
        "  - l (right): Zoom in (All → Day → Project → Entry)",
        "  - h (left): Zoom out (Entry → Project → Day → All)",
        "- g: Go to top entry",
        "- G: Go to bottom entry",
        "- PageUp/PageDown: Jump 10 entries (Entry level only)",
        "",
        "Selection Levels (use h/l to change):",
        "- Entry: Select individual entry (can edit/delete/copy)",
        "- Project: Select whole project group (can copy only)",
        "- Day: Select entire day (can copy only)",
        "- All: Select entire view/period (can copy only)",
        "",
        "Actions:",
        "- e: Edit the selected entry (Entry level only)",
        "- a: Add annotation tag to the selected entry (Entry level only)",
        "- x: Delete the selected entry (Entry level only)",
        "- b: Backfill - set entry start time to previous entry's end time",
        "     (Entry level, By Date view only)",
        "- y: Copy selection to clipboard (works at all levels)",
        "     Copies based on current selection level",
        "",
        "Visual Indicators (By Date view only):",
        "- Yellow highlight: Entry overlaps with previous entry's time",
        "  (starts before the previous entry ended)",
        "- '---' separator: 5+ minute gap between entries",
        "  (can be disabled with show_time_gaps: false in config)",
        "",
        "Other:",
        "- ?: Show/hide this help",
        "- q or ESC: Return to main screen",
        "",
        "Tip: Use h/l to quickly select larger blocks for copying!",
    ];

    let text = help_text.join("\n");

    let block = Block::default()
        .title("Log View Help (j/k to scroll)")
        .borders(Borders::ALL)
        .style(Style::default().fg(Color::White));

    let paragraph = Paragraph::new(text)
        .block(block)
        .style(Style::default().fg(Color::White))
        .scroll((app.help_scroll as u16, 0))
        .wrap(ratatui::widgets::Wrap { trim: true });

    frame.render_widget(paragraph, area);

    // Render command bar
    let bar_area = Rect::new(
        0,
        frame.size().height.saturating_sub(1),
        frame.size().width,
        1,
    );

    let command_bar = Paragraph::new("  q/ESC/? (back to log view)")
        .style(Style::default().fg(Color::White))
        .alignment(Alignment::Left);

    frame.render_widget(command_bar, bar_area);
}

fn render_add_annotation(frame: &mut Frame, app: &App) {
    let area = centered_rect(60, 5, frame.size());
    frame.render_widget(Clear, area);

    let chunks = Layout::default()
        .direction(Direction::Vertical)
        .constraints([Constraint::Length(3), Constraint::Length(2)])
        .split(area);

    // Get current entry to show in title
    let current_entry = if app.log_view_selected < app.log_view_frame_indices.len() {
        let frame_idx = app.log_view_frame_indices[app.log_view_selected];
        app.log_view_frames.get(frame_idx).map(|frame| {
            if frame.tags.is_empty() {
                frame.project.clone()
            } else {
                format!("{} [{}]", frame.tags.join(", "), frame.project)
            }
        })
    } else {
        None
    };

    let title = if let Some(entry) = current_entry {
        format!("Add Annotation to: {}", entry)
    } else {
        "Add Annotation".to_string()
    };

    // Annotation input
    let annotation_block = Block::default()
        .title(title)
        .borders(Borders::ALL)
        .style(Style::default().fg(ACTIVE_COLOR));

    let annotation_text = Paragraph::new(app.annotation_buffer.as_str())
        .block(annotation_block);

    frame.render_widget(annotation_text, chunks[0]);

    // Help text
    let help_text = Paragraph::new("Enter annotation text, press Enter to save, Esc to cancel")
        .style(Style::default().fg(Color::DarkGray))
        .alignment(Alignment::Center);

    frame.render_widget(help_text, chunks[1]);
}
