use crate::config::{CommandSequence, KeyBinding, TmuxConfig, Workspace, WorkspacePane, WorkspaceSession, WorkspaceWindow};
use crate::generate::{self, generate_conf};
use crate::registry::{self, CATEGORIES, ValueKind};
use anyhow::Result;
use crossterm::event::{self, Event, KeyCode, KeyEvent, KeyEventKind, KeyModifiers};
use std::time::{Duration as StdDuration, Instant};
use ratatui::{
    backend::CrosstermBackend,
    layout::{Constraint, Direction, Layout, Rect},
    style::{Color, Modifier, Style},
    text::{Line, Span},
    widgets::{Block, Borders, List, ListItem, Paragraph, Wrap},
    Terminal,
};
use std::io::Stdout;
use std::path::PathBuf;
use std::time::Duration;

#[derive(PartialEq, Eq, Clone, Copy)]
pub enum Screen {
    Options,
    Bindings,
    Plugins,
    Features,
    Extra,
    Preview,
    Workspaces,
    Commands,
}

#[derive(PartialEq, Eq, Clone, Copy)]
enum Mode {
    Normal,
    Search,
    Edit,
    AddCustom,
    BindingEdit,
}

#[derive(PartialEq, Eq, Clone, Copy)]
enum WorkspaceLevel {
    List,    // showing workspace list
    Session, // showing sessions inside a workspace
    Window,  // showing windows inside a session
    Pane,    // showing panes inside a window
}

#[derive(PartialEq, Eq, Clone, Copy)]
enum CommandsLevel {
    List,   // showing command sequences
    Detail, // showing commands inside a sequence
}

pub struct App {
    pub config: TmuxConfig,
    pub config_path: PathBuf,
    pub message: String,
    pub screen: Screen,
    pub category_idx: usize,
    pub list_idx: usize,
    mode: Mode,
    pub search_query: String,
    pub edit_buffer: String,
    pub binding_edit: BindingEditState,
    option_cache: Vec<CachedOption>,
    filtered_indices: Vec<usize>,
    last_key: Option<(Instant, KeyCode)>,

    // Workspace breadcrumb navigation
    ws_level: WorkspaceLevel,
    ws_idx: usize,
    ws_sess_idx: usize,
    ws_win_idx: usize,

    // Commands navigation
    cmd_level: CommandsLevel,
    cmd_idx: usize,

    // Completion shell type
    completion_shell: usize,
}

#[derive(Clone)]
struct CachedOption {
    name: String,
    category: String,
    value: String,
    kind: ValueKind,
    description: String,
    is_custom: bool,
}

#[derive(Default, Clone)]
pub struct BindingEditState {
    pub key: String,
    pub flags: String,
    pub command: String,
    pub editing_field: u8,
}

impl App {
    pub fn new(config: TmuxConfig, config_path: PathBuf) -> Self {
        let mut app = Self {
            config,
            config_path,
            message: "Tumix — full tmux configuration editor".into(),
            screen: Screen::Options,
            category_idx: 0,
            list_idx: 0,
            mode: Mode::Normal,
            search_query: String::new(),
            edit_buffer: String::new(),
            binding_edit: BindingEditState::default(),
            option_cache: Vec::new(),
            filtered_indices: Vec::new(),
            last_key: None,
            ws_level: WorkspaceLevel::List,
            ws_idx: 0,
            ws_sess_idx: 0,
            ws_win_idx: 0,
            cmd_level: CommandsLevel::List,
            cmd_idx: 0,
            completion_shell: 0,
        };
        app.refresh_option_cache();
        app.rebuild_filter();
        app
    }

    fn refresh_option_cache(&mut self) {
        self.option_cache.clear();
        for def in registry::REGISTRY {
            self.option_cache.push(CachedOption {
                name: def.name.to_string(),
                category: def.category.to_string(),
                value: self.config.get_option(def.name),
                kind: def.kind,
                description: def.description.to_string(),
                is_custom: false,
            });
        }
        for (name, value) in &self.config.options {
            if registry::find_option(name).is_some() {
                continue;
            }
            self.option_cache.push(CachedOption {
                name: name.clone(),
                category: "Custom".into(),
                value: value.clone(),
                kind: ValueKind::Text,
                description: "User-defined tmux option".into(),
                is_custom: true,
            });
        }
        self.option_cache.sort_by(|a, b| {
            (&a.category, &a.name).cmp(&(&b.category, &b.name))
        });
    }

    fn rebuild_filter(&mut self) {
        self.filtered_indices.clear();
        let category = self.current_category().to_string();
        let q = self.search_query.to_lowercase();

        match self.screen {
            Screen::Options => {
                for (i, entry) in self.option_cache.iter().enumerate() {
                    if entry.category != category {
                        continue;
                    }
                    if !q.is_empty()
                        && !entry.name.to_lowercase().contains(&q)
                        && !entry.value.to_lowercase().contains(&q)
                    {
                        continue;
                    }
                    self.filtered_indices.push(i);
                }
            }
            Screen::Bindings => {
                for i in 0..self.config.bindings.len() {
                    let b = &self.config.bindings[i];
                    let hay = format!("{} {} {}", b.key, b.flags, b.command).to_lowercase();
                    if q.is_empty() || hay.contains(&q) {
                        self.filtered_indices.push(i);
                    }
                }
            }
            Screen::Plugins => {
                for i in 0..self.config.plugins.len() {
                    let p = &self.config.plugins[i];
                    if q.is_empty() || p.name.to_lowercase().contains(&q) {
                        self.filtered_indices.push(i);
                    }
                }
            }
            Screen::Features => {
                for i in 0..6 {
                    self.filtered_indices.push(i);
                }
            }
            Screen::Extra => {
                for i in 0..self.config.extra_lines.len() {
                    if q.is_empty() || self.config.extra_lines[i].to_lowercase().contains(&q) {
                        self.filtered_indices.push(i);
                    }
                }
            }
            Screen::Preview => {}
            Screen::Workspaces => {
                for i in 0..self.config.workspaces.len() {
                    if q.is_empty() || self.config.workspaces[i].name.to_lowercase().contains(&q) {
                        self.filtered_indices.push(i);
                    }
                }
            }
            Screen::Commands => {
                for i in 0..self.config.command_sequences.len() {
                    if q.is_empty()
                        || self.config.command_sequences[i]
                            .name
                            .to_lowercase()
                            .contains(&q)
                    {
                        self.filtered_indices.push(i);
                    }
                }
            }
        }

        let uses_filtered = match self.screen {
            Screen::Workspaces => matches!(self.ws_level, WorkspaceLevel::List),
            Screen::Commands => matches!(self.cmd_level, CommandsLevel::List),
            _ => true,
        };
        if uses_filtered
            && self.list_idx >= self.filtered_indices.len()
            && !self.filtered_indices.is_empty()
        {
            self.list_idx = self.filtered_indices.len() - 1;
        }
    }

    fn current_category(&self) -> &str {
        if self.screen != Screen::Options {
            return "";
        }
        CATEGORIES
            .get(self.category_idx)
            .copied()
            .unwrap_or("Session")
    }

    pub fn run(&mut self, terminal: &mut Terminal<CrosstermBackend<Stdout>>) -> Result<()> {
        loop {
            terminal.draw(|f| self.draw(f))?;

            if !event::poll(Duration::from_millis(50))? {
                continue;
            }

            let mut key_event: Option<KeyEvent> = None;
            loop {
                match event::read()? {
                    Event::Key(key) if key.kind == KeyEventKind::Press => {
                        key_event = Some(key);
                    }
                    Event::Key(_) | Event::FocusGained | Event::FocusLost => {}
                    _ => {}
                }
                if !event::poll(Duration::from_millis(0))? {
                    break;
                }
            }

            let Some(key) = key_event else {
                continue;
            };

            if self.is_duplicate_key(&key) {
                continue;
            }

            if key.modifiers.contains(KeyModifiers::CONTROL) {
                match key.code {
                    KeyCode::Char('s') => self.save_config()?,
                    KeyCode::Char('p') => self.screen = Screen::Preview,
                    _ => {}
                }
                continue;
            }

            match self.mode {
                Mode::Normal => self.handle_normal(key.code)?,
                Mode::Search => self.handle_search(key.code)?,
                Mode::Edit | Mode::AddCustom => self.handle_edit(key.code)?,
                Mode::BindingEdit => self.handle_binding_edit(key.code)?,
            }
        }
    }

    fn is_duplicate_key(&mut self, key: &KeyEvent) -> bool {
        let now = Instant::now();
        if let Some((prev, code)) = self.last_key {
            if code == key.code && now.duration_since(prev) < StdDuration::from_millis(80) {
                return true;
            }
        }
        self.last_key = Some((now, key.code));
        false
    }

    fn draw(&self, f: &mut ratatui::Frame) {
        let size = f.size();
        let chunks = Layout::default()
            .direction(Direction::Vertical)
            .constraints([
                Constraint::Length(3),
                Constraint::Min(0),
                Constraint::Length(3),
            ])
            .split(size);

        let title = Paragraph::new("TUMIX — interactive tmux.conf builder")
            .style(Style::default().fg(Color::Cyan))
            .block(Block::default().borders(Borders::ALL).title("tumix"));
        f.render_widget(title, chunks[0]);

        let body = Layout::default()
            .direction(Direction::Horizontal)
            .constraints([Constraint::Length(24), Constraint::Min(0)])
            .split(chunks[1]);

        self.draw_sidebar(f, body[0]);
        self.draw_main(f, body[1]);

        let help = match self.mode {
            Mode::Normal => self.help_text(),
            Mode::Search => format!("/{} | Enter/Esc: close", self.search_query),
            Mode::Edit => format!("Edit: {} | Enter: save | Esc: cancel", self.edit_buffer),
            Mode::AddCustom => {
                format!("New option name: {} | Enter: create", self.edit_buffer)
            }
            Mode::BindingEdit => format!(
                "Binding [{}] key={} flags={} cmd={} | Tab: field | Enter: save | Esc: cancel",
                ["key", "flags", "command"][self.binding_edit.editing_field as usize],
                self.binding_edit.key,
                self.binding_edit.flags,
                self.binding_edit.command
            ),
        };
        let footer = Paragraph::new(help).block(Block::default().borders(Borders::ALL).title("keys"));
        f.render_widget(footer, chunks[2]);
    }

    fn help_text(&self) -> String {
        let base = format!(
            "{} | 1-8: screen | Tab: next | /: search | Enter: edit | Space: toggle | a: add | d: del | s: apply | Ctrl+S: save | q: quit",
            self.message
        );
        match self.screen {
            Screen::Workspaces => format!(
                "{} | S: spawn | c: completions", base
            ),
            Screen::Commands => format!(
                "{} | r: run sequence | c: completions", base
            ),
            _ => base,
        }
    }

    fn draw_sidebar(&self, f: &mut ratatui::Frame, area: Rect) {
        let screens = [
            ("Options", Screen::Options),
            ("Bindings", Screen::Bindings),
            ("Plugins", Screen::Plugins),
            ("Features", Screen::Features),
            ("Extra", Screen::Extra),
            ("Preview", Screen::Preview),
            ("Workspaces", Screen::Workspaces),
            ("Commands", Screen::Commands),
        ];
        let items: Vec<ListItem> = screens
            .iter()
            .map(|(label, scr)| {
                let style = if self.screen == *scr {
                    Style::default()
                        .fg(Color::Yellow)
                        .add_modifier(Modifier::BOLD)
                } else {
                    Style::default()
                };
                ListItem::new(*label).style(style)
            })
            .collect();
        let block = Block::default().borders(Borders::ALL).title("Screens");
        f.render_widget(List::new(items).block(block), area);
    }

    fn draw_main(&self, f: &mut ratatui::Frame, area: Rect) {
        match self.screen {
            Screen::Options => self.draw_options(f, area),
            Screen::Bindings => self.draw_bindings(f, area),
            Screen::Plugins => self.draw_plugins(f, area),
            Screen::Features => self.draw_features(f, area),
            Screen::Extra => self.draw_extra(f, area),
            Screen::Preview => self.draw_preview(f, area),
            Screen::Workspaces => self.draw_workspaces(f, area),
            Screen::Commands => self.draw_commands(f, area),
        }
    }

    fn draw_options(&self, f: &mut ratatui::Frame, area: Rect) {
        let split = Layout::default()
            .direction(Direction::Horizontal)
            .constraints([Constraint::Length(18), Constraint::Min(0)])
            .split(area);

        let cats: Vec<ListItem> = CATEGORIES
            .iter()
            .enumerate()
            .map(|(i, c)| {
                let style = if i == self.category_idx {
                    Style::default().fg(Color::Green).add_modifier(Modifier::BOLD)
                } else {
                    Style::default()
                };
                ListItem::new(*c).style(style)
            })
            .collect();
        f.render_widget(
            List::new(cats).block(Block::default().borders(Borders::ALL).title("Category")),
            split[0],
        );

        let items: Vec<ListItem> = self
            .filtered_indices
            .iter()
            .enumerate()
            .map(|(display_i, &cache_i)| {
                let entry = &self.option_cache[cache_i];
                let style = if display_i == self.list_idx {
                    Style::default().fg(Color::Yellow).add_modifier(Modifier::BOLD)
                } else {
                    Style::default()
                };
                let kind = match entry.kind {
                    ValueKind::Bool => "bool",
                    ValueKind::Enum => "enum",
                    ValueKind::Integer => "int",
                    ValueKind::Key => "key",
                    ValueKind::Style => "style",
                    ValueKind::Text => "text",
                };
                ListItem::new(format!(
                    "{:<28} [{}] {}",
                    entry.name, kind, entry.value
                ))
                .style(style)
            })
            .collect();

        let selected_desc = self
            .filtered_indices
            .get(self.list_idx)
            .map(|&i| self.option_cache[i].description.as_str())
            .unwrap_or("");

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

        let title = if self.mode == Mode::Search {
            format!("Options (/{})", self.search_query)
        } else {
            format!("Options — {}", self.current_category())
        };
        f.render_widget(
            List::new(items).block(Block::default().borders(Borders::ALL).title(title)),
            main_split[0],
        );
        let desc = Paragraph::new(selected_desc)
            .wrap(Wrap { trim: true })
            .block(Block::default().borders(Borders::ALL).title("Help"));
        f.render_widget(desc, main_split[1]);
    }

    fn draw_bindings(&self, f: &mut ratatui::Frame, area: Rect) {
        let items: Vec<ListItem> = self
            .filtered_indices
            .iter()
            .enumerate()
            .map(|(i, &bi)| {
                let b = &self.config.bindings[bi];
                let style = if i == self.list_idx {
                    Style::default().fg(Color::Yellow)
                } else {
                    Style::default()
                };
                ListItem::new(format!(
                    "{:<16} {:<12} {}",
                    b.key,
                    if b.flags.is_empty() { "-" } else { &b.flags },
                    b.command
                ))
                .style(style)
            })
            .collect();
        f.render_widget(
            List::new(items).block(Block::default().borders(Borders::ALL).title("Key bindings (a: add, d: del)")),
            area,
        );
    }

    fn draw_plugins(&self, f: &mut ratatui::Frame, area: Rect) {
        let items: Vec<ListItem> = self
            .filtered_indices
            .iter()
            .enumerate()
            .map(|(i, &pi)| {
                let p = &self.config.plugins[pi];
                let mark = if p.enabled { "[x]" } else { "[ ]" };
                let style = if i == self.list_idx {
                    Style::default().fg(Color::Yellow)
                } else {
                    Style::default()
                };
                ListItem::new(format!("{} {}", mark, p.name)).style(style)
            })
            .collect();
        f.render_widget(
            List::new(items).block(Block::default().borders(Borders::ALL).title("Plugins (Space: toggle)")),
            area,
        );
    }

    fn draw_features(&self, f: &mut ratatui::Frame, area: Rect) {
        let flags = [
            ("vim_navigation", self.config.features.vim_navigation),
            ("aggressive_resize (preset)", self.config.features.aggressive_resize),
            ("automatic_rename (preset)", self.config.features.automatic_rename),
            ("system_monitor snippet", self.config.features.system_monitor),
            ("rebind_prefix", self.config.features.rebind_prefix),
            ("reload_config_key", self.config.features.reload_config_key),
        ];
        let items: Vec<ListItem> = flags
            .iter()
            .enumerate()
            .map(|(i, (name, on))| {
                let style = if i == self.list_idx {
                    Style::default().fg(Color::Yellow)
                } else {
                    Style::default()
                };
                ListItem::new(format!("[{}] {}", if *on { "x" } else { " " }, name)).style(style)
            })
            .collect();
        f.render_widget(
            List::new(items).block(Block::default().borders(Borders::ALL).title("Feature presets")),
            area,
        );
    }

    fn draw_extra(&self, f: &mut ratatui::Frame, area: Rect) {
        let items: Vec<ListItem> = self
            .config
            .extra_lines
            .iter()
            .enumerate()
            .map(|(i, line)| {
                let style = if i == self.list_idx {
                    Style::default().fg(Color::Yellow)
                } else {
                    Style::default()
                };
                ListItem::new(line.clone()).style(style)
            })
            .collect();
        f.render_widget(
            List::new(items).block(Block::default().borders(Borders::ALL).title("Raw tmux.conf lines (a: add, e: edit)")),
            area,
        );
    }

    fn draw_preview(&self, f: &mut ratatui::Frame, area: Rect) {
        let conf = generate_conf(&self.config);
        let lines: Vec<Line> = conf
            .lines()
            .take(500)
            .map(|l| Line::from(Span::raw(l)))
            .collect();
        let p = Paragraph::new(lines)
            .wrap(Wrap { trim: false })
            .block(Block::default().borders(Borders::ALL).title("~/.tmux.conf preview"));
        f.render_widget(p, area);
    }

    fn draw_workspaces(&self, f: &mut ratatui::Frame, area: Rect) {
        match self.ws_level {
            WorkspaceLevel::List => {
                let items: Vec<ListItem> = self
                    .filtered_indices
                    .iter()
                    .enumerate()
                    .map(|(i, &wi)| {
                        let ws = &self.config.workspaces[wi];
                        let style = if i == self.list_idx {
                            Style::default().fg(Color::Yellow).add_modifier(Modifier::BOLD)
                        } else {
                            Style::default()
                        };
                        let sc = ws.sessions.len();
                        let wins: usize = ws.sessions.iter().map(|s| s.windows.len()).sum();
                        ListItem::new(format!(
                            "{} ({} sessions, {} windows)",
                            ws.name, sc, wins
                        ))
                        .style(style)
                    })
                    .collect();
                f.render_widget(
                    List::new(items).block(
                        Block::default().borders(Borders::ALL).title("Workspaces (Enter: drill in, a: add, d: del, e: rename, S: spawn, c: completions)"),
                    ),
                    area,
                );
            }
            WorkspaceLevel::Session => {
                if let Some(ws) = self.config.workspaces.get(self.ws_idx) {
                    let items: Vec<ListItem> = ws
                        .sessions
                        .iter()
                        .enumerate()
                        .map(|(i, sess)| {
                            let style = if i == self.ws_sess_idx {
                                Style::default().fg(Color::Yellow).add_modifier(Modifier::BOLD)
                            } else {
                                Style::default()
                            };
                            ListItem::new(format!(
                                "{} ({} windows)",
                                sess.name,
                                sess.windows.len()
                            ))
                            .style(style)
                        })
                        .collect();
                    f.render_widget(
                        List::new(items).block(
                            Block::default().borders(Borders::ALL).title(format!(
                                "Workspace: {} (Esc: back, Enter: drill, a: add session, d: del, e: rename)",
                                ws.name
                            )),
                        ),
                        area,
                    );
                }
            }
            WorkspaceLevel::Window => {
                if let Some(ws) = self.config.workspaces.get(self.ws_idx) {
                    if let Some(sess) = ws.sessions.get(self.ws_sess_idx) {
                        let items: Vec<ListItem> = sess
                            .windows
                            .iter()
                            .enumerate()
                            .map(|(i, win)| {
                                let style = if i == self.ws_win_idx {
                                    Style::default().fg(Color::Yellow).add_modifier(Modifier::BOLD)
                                } else {
                                    Style::default()
                                };
                                let layout = win
                                    .layout
                                    .as_deref()
                                    .unwrap_or("even-horizontal");
                                ListItem::new(format!(
                                    "{} ({} panes, layout: {})",
                                    win.name,
                                    win.panes.len(),
                                    layout
                                ))
                                .style(style)
                            })
                            .collect();
                        f.render_widget(
                            List::new(items).block(
                                Block::default()
                                    .borders(Borders::ALL)
                                    .title(format!("{} > {} (Esc: back, Enter: panes, a: add window, d: del, e: rename)", ws.name, sess.name)),
                            ),
                            area,
                        );
                    }
                }
            }
            WorkspaceLevel::Pane => {
                if let Some(ws) = self.config.workspaces.get(self.ws_idx) {
                    if let Some(sess) = ws.sessions.get(self.ws_sess_idx) {
                        if let Some(win) = sess.windows.get(self.ws_win_idx) {
                            let items: Vec<ListItem> = win
                                .panes
                                .iter()
                                .enumerate()
                                .map(|(i, pane)| {
                                    let style = if i == self.list_idx {
                                        Style::default().fg(Color::Yellow).add_modifier(Modifier::BOLD)
                                    } else {
                                        Style::default()
                                    };
                                    let cmds = if pane.commands.is_empty() {
                                        "(no commands)".into()
                                    } else {
                                        pane.commands.join(" && ")
                                    };
                                    ListItem::new(format!("Pane {}: {}", i, cmds)).style(style)
                                })
                                .collect();
                            f.render_widget(
                                List::new(items).block(
                                    Block::default()
                                        .borders(Borders::ALL)
                                        .title(format!(
                                            "{} > {} > {} (Esc: back, Enter: edit cmds, a: add pane, d: del)",
                                            ws.name, sess.name, win.name
                                        )),
                                ),
                                area,
                            );
                        }
                    }
                }
            }
        }
    }

    fn draw_commands(&self, f: &mut ratatui::Frame, area: Rect) {
        match self.cmd_level {
            CommandsLevel::List => {
                let items: Vec<ListItem> = self
                    .filtered_indices
                    .iter()
                    .enumerate()
                    .map(|(i, &si)| {
                        let seq = &self.config.command_sequences[si];
                        let style = if i == self.list_idx {
                            Style::default().fg(Color::Yellow).add_modifier(Modifier::BOLD)
                        } else {
                            Style::default()
                        };
                        ListItem::new(format!(
                            "{} ({} commands)",
                            seq.name,
                            seq.commands.len()
                        ))
                        .style(style)
                    })
                    .collect();
                f.render_widget(
                    List::new(items).block(
                        Block::default()
                            .borders(Borders::ALL)
                            .title("Command Sequences (Enter: view, a: add, d: del, e: rename, r: run, c: completions)"),
                    ),
                    area,
                );
            }
            CommandsLevel::Detail => {
                if let Some(seq) = self.config.command_sequences.get(self.cmd_idx) {
                    let items: Vec<ListItem> = seq
                        .commands
                        .iter()
                        .enumerate()
                        .map(|(i, cmd)| {
                            let style = if i == self.list_idx {
                                Style::default().fg(Color::Yellow).add_modifier(Modifier::BOLD)
                            } else {
                                Style::default()
                            };
                            ListItem::new(format!("{}. {}", i + 1, cmd)).style(style)
                        })
                        .collect();
                    f.render_widget(
                        List::new(items).block(
                            Block::default()
                                .borders(Borders::ALL)
                                .title(format!("Sequence: {} (Esc: back, Enter: edit cmd, a: add cmd, d: del cmd)", seq.name)),
                        ),
                        area,
                    );
                }
            }
        }
    }

    fn handle_normal(&mut self, code: KeyCode) -> Result<()> {
        match code {
            KeyCode::Char('q') => return Err(anyhow::anyhow!("quit")),
            KeyCode::Char(c @ '1'..='8') => {
                let idx = (c as u8 - b'1') as usize;
                let screens = [
                    Screen::Options,
                    Screen::Bindings,
                    Screen::Plugins,
                    Screen::Features,
                    Screen::Extra,
                    Screen::Preview,
                    Screen::Workspaces,
                    Screen::Commands,
                ];
                if let Some(&scr) = screens.get(idx) {
                    self.screen = scr;
                    self.list_idx = 0;
                    self.ws_level = WorkspaceLevel::List;
                    self.cmd_level = CommandsLevel::List;
                    self.rebuild_filter();
                }
            }
            KeyCode::Char('/') => {
                let can_search = match self.screen {
                    Screen::Workspaces => matches!(self.ws_level, WorkspaceLevel::List),
                    Screen::Commands => matches!(self.cmd_level, CommandsLevel::List),
                    _ => true,
                };
                if can_search {
                    self.mode = Mode::Search;
                    self.search_query.clear();
                }
            }
            KeyCode::Char('s') => {
                self.apply_config()?;
            }
            KeyCode::Char('a') => self.action_add(),
            KeyCode::Char('d') => self.action_delete(),
            KeyCode::Char('e') => self.start_edit(),
            KeyCode::Tab => self.cycle_screen(1),
            KeyCode::BackTab => self.cycle_screen(-1),
            KeyCode::Left => {
                if self.screen == Screen::Options && self.category_idx > 0 {
                    self.category_idx -= 1;
                    self.list_idx = 0;
                    self.rebuild_filter();
                }
            }
            KeyCode::Right => {
                if self.screen == Screen::Options && self.category_idx + 1 < CATEGORIES.len() {
                    self.category_idx += 1;
                    self.list_idx = 0;
                    self.rebuild_filter();
                }
            }
            KeyCode::Up | KeyCode::Char('k') => self.nav_up(),
            KeyCode::Down | KeyCode::Char('j') => self.nav_down(),
            KeyCode::Enter => self.start_edit(),
            KeyCode::Char(' ') => self.toggle_current(),
            KeyCode::Esc => self.nav_escape(),
            KeyCode::Char('S') => {
                if self.screen == Screen::Workspaces && self.ws_level == WorkspaceLevel::List {
                    self.spawn_selected_workspace()?;
                }
            }
            KeyCode::Char('c') => {
                if self.screen == Screen::Workspaces || self.screen == Screen::Commands {
                    self.generate_completions()?;
                }
            }
            KeyCode::Char('r') => {
                if self.screen == Screen::Commands {
                    self.run_selected_sequence()?;
                }
            }
            _ => {}
        }
        Ok(())
    }

    fn nav_up(&mut self) {
        match self.screen {
            Screen::Workspaces => match self.ws_level {
                WorkspaceLevel::List => {
                    self.list_idx = self.list_idx.saturating_sub(1);
                }
                WorkspaceLevel::Session => {
                    self.ws_sess_idx = self.ws_sess_idx.saturating_sub(1);
                }
                WorkspaceLevel::Window => {
                    self.ws_win_idx = self.ws_win_idx.saturating_sub(1);
                }
                WorkspaceLevel::Pane => {
                    self.list_idx = self.list_idx.saturating_sub(1);
                }
            },
            Screen::Commands => match self.cmd_level {
                CommandsLevel::List => {
                    self.list_idx = self.list_idx.saturating_sub(1);
                }
                CommandsLevel::Detail => {
                    self.list_idx = self.list_idx.saturating_sub(1);
                }
            },
            _ => {
                self.list_idx = self.list_idx.saturating_sub(1);
            }
        }
    }

    fn nav_down(&mut self) {
        match self.screen {
            Screen::Workspaces => match self.ws_level {
                WorkspaceLevel::List => {
                    if self.list_idx + 1 < self.filtered_indices.len() {
                        self.list_idx += 1;
                    }
                }
                WorkspaceLevel::Session => {
                    if let Some(ws) = self.config.workspaces.get(self.ws_idx) {
                        if self.ws_sess_idx + 1 < ws.sessions.len() {
                            self.ws_sess_idx += 1;
                        }
                    }
                }
                WorkspaceLevel::Window => {
                    if let Some(ws) = self.config.workspaces.get(self.ws_idx) {
                        if let Some(sess) = ws.sessions.get(self.ws_sess_idx) {
                            if self.ws_win_idx + 1 < sess.windows.len() {
                                self.ws_win_idx += 1;
                            }
                        }
                    }
                }
                WorkspaceLevel::Pane => {
                    if let Some(ws) = self.config.workspaces.get(self.ws_idx) {
                        if let Some(sess) = ws.sessions.get(self.ws_sess_idx) {
                            if let Some(win) = sess.windows.get(self.ws_win_idx) {
                                if self.list_idx + 1 < win.panes.len() {
                                    self.list_idx += 1;
                                }
                            }
                        }
                    }
                }
            },
            Screen::Commands => match self.cmd_level {
                CommandsLevel::List => {
                    if self.list_idx + 1 < self.filtered_indices.len() {
                        self.list_idx += 1;
                    }
                    if let Some(&si) = self.filtered_indices.get(self.list_idx) {
                        self.cmd_idx = si;
                    }
                }
                CommandsLevel::Detail => {
                    if let Some(seq) = self.config.command_sequences.get(self.cmd_idx) {
                        if self.list_idx + 1 < seq.commands.len() {
                            self.list_idx += 1;
                        }
                    }
                }
            },
            _ => {
                if self.list_idx + 1 < self.filtered_indices.len() {
                    self.list_idx += 1;
                }
            }
        }
    }

    fn nav_escape(&mut self) {
        match self.screen {
            Screen::Workspaces => match self.ws_level {
                WorkspaceLevel::Session => {
                    self.ws_level = WorkspaceLevel::List;
                    self.list_idx = self.ws_idx;
                    self.rebuild_filter();
                }
                WorkspaceLevel::Window => {
                    self.ws_level = WorkspaceLevel::Session;
                    self.ws_win_idx = 0;
                }
                WorkspaceLevel::Pane => {
                    self.ws_level = WorkspaceLevel::Window;
                    self.list_idx = 0;
                }
                _ => {}
            },
            Screen::Commands => match self.cmd_level {
                CommandsLevel::Detail => {
                    self.cmd_level = CommandsLevel::List;
                    self.list_idx = self.cmd_idx;
                    self.rebuild_filter();
                }
                _ => {}
            },
            _ => {}
        }
    }

    fn cycle_screen(&mut self, delta: i32) {
        let screens = [
            Screen::Options,
            Screen::Bindings,
            Screen::Plugins,
            Screen::Features,
            Screen::Extra,
            Screen::Preview,
            Screen::Workspaces,
            Screen::Commands,
        ];
        let current = screens.iter().position(|s| *s == self.screen).unwrap_or(0);
        let next = (current as i32 + delta).rem_euclid(screens.len() as i32) as usize;
        self.screen = screens[next];
        self.list_idx = 0;
        self.ws_level = WorkspaceLevel::List;
        self.cmd_level = CommandsLevel::List;
        self.rebuild_filter();
    }

    fn handle_search(&mut self, code: KeyCode) -> Result<()> {
        match code {
            KeyCode::Esc | KeyCode::Enter => {
                self.mode = Mode::Normal;
            }
            KeyCode::Char(c) => {
                self.search_query.push(c);
                self.list_idx = 0;
                self.rebuild_filter();
            }
            KeyCode::Backspace => {
                self.search_query.pop();
                self.list_idx = 0;
                self.rebuild_filter();
            }
            _ => {}
        }
        Ok(())
    }

    fn handle_edit(&mut self, code: KeyCode) -> Result<()> {
        match code {
            KeyCode::Esc => {
                self.mode = Mode::Normal;
                self.message = "Cancelled".into();
            }
            KeyCode::Enter => {
                if self.mode == Mode::AddCustom {
                    let name = self.edit_buffer.trim().to_string();
                    if !name.is_empty() {
                        self.config.set_option(&name, String::new());
                        self.refresh_option_cache();
                        self.rebuild_filter();
                        self.message = format!("Added custom option {}", name);
                    }
                } else {
                    self.commit_edit()?;
                }
                self.mode = Mode::Normal;
            }
            KeyCode::Char(c) => self.edit_buffer.push(c),
            KeyCode::Backspace => {
                self.edit_buffer.pop();
            }
            _ => {}
        }
        Ok(())
    }

    fn handle_binding_edit(&mut self, code: KeyCode) -> Result<()> {
        let field = &mut self.binding_edit;
        match code {
            KeyCode::Esc => {
                self.mode = Mode::Normal;
            }
            KeyCode::Tab => {
                field.editing_field = (field.editing_field + 1) % 3;
            }
            KeyCode::Enter => {
                self.config.bindings.push(KeyBinding {
                    key: field.key.clone(),
                    flags: field.flags.clone(),
                    command: field.command.clone(),
                });
                self.mode = Mode::Normal;
                self.rebuild_filter();
                self.message = "Binding added".into();
            }
            KeyCode::Char(c) => match field.editing_field {
                0 => field.key.push(c),
                1 => field.flags.push(c),
                _ => field.command.push(c),
            },
            KeyCode::Backspace => match field.editing_field {
                0 => {
                    field.key.pop();
                }
                1 => {
                    field.flags.pop();
                }
                _ => {
                    field.command.pop();
                }
            },
            _ => {}
        }
        Ok(())
    }

    fn start_edit(&mut self) {
        match self.screen {
            Screen::Options => {
                if let Some(&ci) = self.filtered_indices.get(self.list_idx) {
                    let entry = &self.option_cache[ci];
                    self.edit_buffer = entry.value.clone();
                    self.mode = Mode::Edit;
                }
            }
            Screen::Bindings => {
                self.binding_edit = BindingEditState::default();
                self.mode = Mode::BindingEdit;
            }
            Screen::Extra => {
                if let Some(&i) = self.filtered_indices.get(self.list_idx) {
                    self.edit_buffer = self.config.extra_lines[i].clone();
                    self.mode = Mode::Edit;
                }
            }
            Screen::Workspaces => match self.ws_level {
                WorkspaceLevel::List => {
                    if let Some(&wi) = self.filtered_indices.get(self.list_idx) {
                        self.ws_idx = wi;
                        self.ws_level = WorkspaceLevel::Session;
                        self.ws_sess_idx = 0;
                        self.ws_win_idx = 0;
                        self.message = format!("Drilled into '{}'", self.config.workspaces[wi].name);
                    }
                }
                WorkspaceLevel::Session => {
                    if let Some(ws) = self.config.workspaces.get(self.ws_idx) {
                        if let Some(sess) = ws.sessions.get(self.ws_sess_idx) {
                            self.ws_level = WorkspaceLevel::Window;
                            self.ws_win_idx = 0;
                            self.message = format!("Drilled into '{}'", sess.name);
                        }
                    }
                }
                WorkspaceLevel::Window => {
                    if let Some(ws) = self.config.workspaces.get(self.ws_idx) {
                        if let Some(sess) = ws.sessions.get(self.ws_sess_idx) {
                            if let Some(_win) = sess.windows.get(self.ws_win_idx) {
                                self.ws_level = WorkspaceLevel::Pane;
                                self.list_idx = 0;
                            }
                        }
                    }
                }
                WorkspaceLevel::Pane => {
                    if let Some(ws) = self.config.workspaces.get(self.ws_idx) {
                        if let Some(sess) = ws.sessions.get(self.ws_sess_idx) {
                            if let Some(win) = sess.windows.get(self.ws_win_idx) {
                                if let Some(pane) = win.panes.get(self.list_idx) {
                                    self.edit_buffer = pane.commands.join(" && ");
                                    self.mode = Mode::Edit;
                                }
                            }
                        }
                    }
                }
            },
            Screen::Commands => match self.cmd_level {
                CommandsLevel::List => {
                    if let Some(&si) = self.filtered_indices.get(self.list_idx) {
                        self.cmd_idx = si;
                        self.cmd_level = CommandsLevel::Detail;
                        self.list_idx = 0;
                        self.message = format!("Viewing sequence '{}'", self.config.command_sequences[si].name);
                    }
                }
                CommandsLevel::Detail => {
                    if let Some(seq) = self.config.command_sequences.get(self.cmd_idx) {
                        if let Some(cmd) = seq.commands.get(self.list_idx) {
                            self.edit_buffer = cmd.clone();
                            self.mode = Mode::Edit;
                        }
                    }
                }
            },
            _ => {}
        }
    }

    fn commit_edit(&mut self) -> Result<()> {
        match self.screen {
            Screen::Options => {
                if let Some(&ci) = self.filtered_indices.get(self.list_idx) {
                    let name = self.option_cache[ci].name.clone();
                    self.config.set_option(&name, self.edit_buffer.clone());
                    self.refresh_option_cache();
                    self.rebuild_filter();
                    self.message = format!("Set {} = {}", name, self.edit_buffer);
                }
            }
            Screen::Extra => {
                if let Some(&i) = self.filtered_indices.get(self.list_idx) {
                    self.config.extra_lines[i] = self.edit_buffer.clone();
                    self.message = "Updated extra line".into();
                }
            }
            Screen::Workspaces => {
                if self.ws_level == WorkspaceLevel::Pane {
                    if let Some(ws) = self.config.workspaces.get_mut(self.ws_idx) {
                        if let Some(sess) = ws.sessions.get_mut(self.ws_sess_idx) {
                            if let Some(win) = sess.windows.get_mut(self.ws_win_idx) {
                                if let Some(pane) = win.panes.get_mut(self.list_idx) {
                                    pane.commands = self
                                        .edit_buffer
                                        .split(" && ")
                                        .map(|s| s.trim().to_string())
                                        .filter(|s| !s.is_empty())
                                        .collect();
                                    self.message = "Updated pane commands".into();
                                }
                            }
                        }
                    }
                }
            }
            Screen::Commands => {
                if self.cmd_level == CommandsLevel::Detail {
                    if let Some(seq) = self.config.command_sequences.get_mut(self.cmd_idx) {
                        if let Some(cmd) = seq.commands.get_mut(self.list_idx) {
                            *cmd = self.edit_buffer.clone();
                            self.message = "Updated command".into();
                        }
                    }
                }
            }
            _ => {}
        }
        Ok(())
    }

    fn toggle_current(&mut self) {
        match self.screen {
            Screen::Options => {
                if let Some(&ci) = self.filtered_indices.get(self.list_idx) {
                    let entry = self.option_cache[ci].clone();
                    if entry.kind == ValueKind::Bool {
                        let new = if entry.value == "on" || entry.value == "true" {
                            "off".to_string()
                        } else {
                            "on".to_string()
                        };
                        self.config.set_option(&entry.name, new.clone());
                        self.refresh_option_cache();
                        self.rebuild_filter();
                        self.message = format!("{} → {}", entry.name, new);
                    } else if entry.kind == ValueKind::Enum {
                        if let Some(def) = registry::find_option(&entry.name) {
                            if !def.choices.is_empty() {
                                let choices = def.choices;
                                let next = choices
                                    .iter()
                                    .position(|c| *c == entry.value.as_str())
                                    .map(|i| choices[(i + 1) % choices.len()])
                                    .unwrap_or(choices[0]);
                                self.config
                                    .set_option(&entry.name, (*next).to_string());
                                self.refresh_option_cache();
                                self.rebuild_filter();
                                self.message = format!("{} → {}", entry.name, next);
                            }
                        }
                    }
                }
            }
            Screen::Plugins => {
                if let Some(&pi) = self.filtered_indices.get(self.list_idx) {
                    self.config.plugins[pi].enabled = !self.config.plugins[pi].enabled;
                    self.message = format!("Toggled {}", self.config.plugins[pi].name);
                }
            }
            Screen::Features => {
                if let Some(&fi) = self.filtered_indices.get(self.list_idx) {
                    match fi {
                        0 => self.config.features.vim_navigation ^= true,
                        1 => self.config.features.aggressive_resize ^= true,
                        2 => self.config.features.automatic_rename ^= true,
                        3 => self.config.features.system_monitor ^= true,
                        4 => self.config.features.rebind_prefix ^= true,
                        5 => self.config.features.reload_config_key ^= true,
                        _ => {}
                    }
                    self.rebuild_filter();
                }
            }
            _ => {}
        }
    }

    fn action_add(&mut self) {
        match self.screen {
            Screen::Options => {
                self.edit_buffer.clear();
                self.mode = Mode::AddCustom;
            }
            Screen::Bindings => {
                self.binding_edit = BindingEditState::default();
                self.mode = Mode::BindingEdit;
            }
            Screen::Extra => {
                self.config.extra_lines.push(String::new());
                self.filtered_indices.push(self.config.extra_lines.len() - 1);
                self.list_idx = self.filtered_indices.len().saturating_sub(1);
                self.edit_buffer.clear();
                self.mode = Mode::Edit;
            }
            Screen::Workspaces => match self.ws_level {
                WorkspaceLevel::List => {
                    let n = self.config.workspaces.len() + 1;
                    self.config.workspaces.push(Workspace {
                        name: format!("workspace_{}", n),
                        sessions: vec![WorkspaceSession {
                            name: "default".into(),
                            windows: vec![WorkspaceWindow {
                                name: "main".into(),
                                layout: None,
                                panes: vec![WorkspacePane {
                                    commands: vec![],
                                }],
                            }],
                        }],
                    });
                    self.rebuild_filter();
                    self.list_idx = self.config.workspaces.len() - 1;
                    self.ws_idx = self.list_idx;
                    self.message = format!("Added workspace {}", n);
                }
                WorkspaceLevel::Session => {
                    if let Some(ws) = self.config.workspaces.get_mut(self.ws_idx) {
                        let n = ws.sessions.len() + 1;
                        ws.sessions.push(WorkspaceSession {
                            name: format!("session_{}", n),
                            windows: vec![],
                        });
                        self.ws_sess_idx = ws.sessions.len() - 1;
                        self.message = format!("Added session {}", n);
                    }
                }
                WorkspaceLevel::Window => {
                    if let Some(ws) = self.config.workspaces.get_mut(self.ws_idx) {
                        if let Some(sess) = ws.sessions.get_mut(self.ws_sess_idx) {
                            let n = sess.windows.len() + 1;
                            sess.windows.push(WorkspaceWindow {
                                name: format!("win_{}", n),
                                layout: None,
                                panes: vec![],
                            });
                            self.ws_win_idx = sess.windows.len() - 1;
                            self.message = format!("Added window {}", n);
                        }
                    }
                }
                WorkspaceLevel::Pane => {
                    if let Some(ws) = self.config.workspaces.get_mut(self.ws_idx) {
                        if let Some(sess) = ws.sessions.get_mut(self.ws_sess_idx) {
                            if let Some(win) = sess.windows.get_mut(self.ws_win_idx) {
                                win.panes.push(WorkspacePane {
                                    commands: vec![],
                                });
                                self.list_idx = win.panes.len() - 1;
                                self.message = "Added pane".into();
                            }
                        }
                    }
                }
            },
            Screen::Commands => match self.cmd_level {
                CommandsLevel::List => {
                    let n = self.config.command_sequences.len() + 1;
                    self.config.command_sequences.push(CommandSequence {
                        name: format!("seq_{}", n),
                        commands: vec![],
                    });
                    self.rebuild_filter();
                    self.list_idx = self.config.command_sequences.len() - 1;
                    self.cmd_idx = self.list_idx;
                    self.message = format!("Added sequence {}", n);
                }
                CommandsLevel::Detail => {
                    if let Some(seq) = self.config.command_sequences.get_mut(self.cmd_idx) {
                        seq.commands.push(String::new());
                        self.list_idx = seq.commands.len() - 1;
                        self.edit_buffer.clear();
                        self.mode = Mode::Edit;
                        self.message = "Added command".into();
                    }
                }
            },
            _ => {}
        }
    }

    fn action_delete(&mut self) {
        match self.screen {
            Screen::Bindings => {
                if let Some(&bi) = self.filtered_indices.get(self.list_idx) {
                    self.config.bindings.remove(bi);
                    self.rebuild_filter();
                    self.message = "Removed binding".into();
                }
            }
            Screen::Extra => {
                if let Some(&i) = self.filtered_indices.get(self.list_idx) {
                    self.config.extra_lines.remove(i);
                    self.rebuild_filter();
                    self.message = "Removed line".into();
                }
            }
            Screen::Options => {
                if let Some(&ci) = self.filtered_indices.get(self.list_idx) {
                    let name = self.option_cache[ci].name.clone();
                    if self.option_cache[ci].is_custom {
                        self.config.options.remove(&name);
                        self.refresh_option_cache();
                        self.rebuild_filter();
                        self.message = format!("Removed custom option {}", name);
                    }
                }
            }
            Screen::Workspaces => match self.ws_level {
                WorkspaceLevel::List => {
                    if let Some(&wi) = self.filtered_indices.get(self.list_idx) {
                        self.config.workspaces.remove(wi);
                        self.rebuild_filter();
                        self.message = "Removed workspace".into();
                    }
                }
                WorkspaceLevel::Session => {
                    if let Some(ws) = self.config.workspaces.get_mut(self.ws_idx) {
                        if self.ws_sess_idx < ws.sessions.len() {
                            ws.sessions.remove(self.ws_sess_idx);
                            if self.ws_sess_idx >= ws.sessions.len() && !ws.sessions.is_empty() {
                                self.ws_sess_idx = ws.sessions.len() - 1;
                            }
                            self.message = "Removed session".into();
                        }
                    }
                }
                WorkspaceLevel::Window => {
                    if let Some(ws) = self.config.workspaces.get_mut(self.ws_idx) {
                        if let Some(sess) = ws.sessions.get_mut(self.ws_sess_idx) {
                            if self.ws_win_idx < sess.windows.len() {
                                sess.windows.remove(self.ws_win_idx);
                                if self.ws_win_idx >= sess.windows.len() && !sess.windows.is_empty() {
                                    self.ws_win_idx = sess.windows.len() - 1;
                                }
                                self.message = "Removed window".into();
                            }
                        }
                    }
                }
                WorkspaceLevel::Pane => {
                    if let Some(ws) = self.config.workspaces.get_mut(self.ws_idx) {
                        if let Some(sess) = ws.sessions.get_mut(self.ws_sess_idx) {
                            if let Some(win) = sess.windows.get_mut(self.ws_win_idx) {
                                if self.list_idx < win.panes.len() {
                                    win.panes.remove(self.list_idx);
                                    if self.list_idx >= win.panes.len() && !win.panes.is_empty() {
                                        self.list_idx = win.panes.len() - 1;
                                    }
                                    self.message = "Removed pane".into();
                                }
                            }
                        }
                    }
                }
            },
            Screen::Commands => match self.cmd_level {
                CommandsLevel::List => {
                    if let Some(&si) = self.filtered_indices.get(self.list_idx) {
                        self.config.command_sequences.remove(si);
                        self.rebuild_filter();
                        self.message = "Removed sequence".into();
                    }
                }
                CommandsLevel::Detail => {
                    if let Some(seq) = self.config.command_sequences.get_mut(self.cmd_idx) {
                        if self.list_idx < seq.commands.len() {
                            seq.commands.remove(self.list_idx);
                            if self.list_idx >= seq.commands.len() && !seq.commands.is_empty() {
                                self.list_idx = seq.commands.len() - 1;
                            }
                            self.message = "Removed command".into();
                        }
                    }
                }
            },
            _ => {}
        }
    }

    fn spawn_selected_workspace(&mut self) -> Result<()> {
        if let Some(&wi) = self.filtered_indices.get(self.list_idx) {
            let ws = self.config.workspaces[wi].clone();
            match self.config.spawn_workspace(&ws) {
                Ok(()) => self.message = format!("Spawned workspace '{}'", ws.name),
                Err(e) => self.message = format!("Spawn failed: {}", e),
            }
        }
        Ok(())
    }

    fn run_selected_sequence(&mut self) -> Result<()> {
        let seq_idx = match self.cmd_level {
            CommandsLevel::List => {
                if let Some(&si) = self.filtered_indices.get(self.list_idx) {
                    si
                } else {
                    return Ok(());
                }
            }
            CommandsLevel::Detail => self.cmd_idx,
        };
        if let Some(seq) = self.config.command_sequences.get(seq_idx) {
            for cmd in &seq.commands {
                let status = std::process::Command::new("sh")
                    .arg("-c")
                    .arg(cmd)
                    .status();
                match status {
                    Ok(s) if s.success() => {}
                    Ok(s) => {
                        self.message = format!("Command failed (exit {}): {}", s.code().unwrap_or(-1), cmd);
                        return Ok(());
                    }
                    Err(e) => {
                        self.message = format!("Command error: {}", e);
                        return Ok(());
                    }
                }
            }
            self.message = format!("Sequence '{}' completed", seq.name);
        }
        Ok(())
    }

    fn generate_completions(&mut self) -> Result<()> {
        let shells = ["bash", "zsh", "powershell"];
        let shell = shells[self.completion_shell % shells.len()];
        let content = match shell {
            "bash" => generate::generate_bash_completions(
                &self.config.workspaces,
                &self.config.command_sequences,
            ),
            "zsh" => generate::generate_zsh_completions(
                &self.config.workspaces,
                &self.config.command_sequences,
            ),
            _ => generate::generate_powershell_completions(
                &self.config.workspaces,
                &self.config.command_sequences,
            ),
        };

        let out_path = PathBuf::from(format!("tumix_completions.{}", shell));
        std::fs::write(&out_path, &content)?;
        self.completion_shell += 1;
        let next = shells[self.completion_shell % shells.len()];
        self.message = format!(
            "Wrote {} completions to {:?} (press c again for {})",
            shell, out_path, next
        );
        Ok(())
    }

    fn save_config(&mut self) -> Result<()> {
        self.config.save_to_file(&self.config_path)?;
        self.message = format!("Saved {}", self.config_path.display());
        Ok(())
    }

    fn apply_config(&mut self) -> Result<()> {
        self.config.save_to_file(&self.config_path)?;
        match self.config.apply() {
            Ok(()) => self.message = "Saved & applied ~/.tmux.conf".into(),
            Err(e) => self.message = format!("Saved; apply: {}", e),
        }
        Ok(())
    }
}
