use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
pub enum ClientMsg {
    Input(Vec<u8>),
    NewTab,
    NewSession(String),
    SwitchTab(usize),
    SwitchSession(usize),
    Resize { cols: u16, rows: u16 },
    Scroll(i32),
    RenameTab { index: usize, name: String },
    CloseTab(usize),
    RenameSession { index: usize, name: String },
    Exit,
    Detach,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum TermColor {
    Default,
    Indexed(u8),
    Rgb(u8, u8, u8),
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum MouseMode {
    None,
    Press,
    PressRelease,
    ButtonMotion,
    AnyMotion,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum MouseEncoding {
    Default,
    Utf8,
    Sgr,
}

/// One run of characters that share the same style.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StyledSpan {
    pub text: String,
    pub fg: TermColor,
    pub bg: TermColor,
    pub bold: bool,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TabInfo {
    pub name: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SessionInfo {
    pub name: String,
    pub tabs: Vec<TabInfo>,
    pub active_tab: usize,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DaemonState {
    pub sessions: Vec<SessionInfo>,
    pub active_session: usize,
    /// Screen rendered as rows of styled spans (already processed by vt100).
    pub screen: Vec<Vec<StyledSpan>>,
    pub cursor_row: u16,
    pub cursor_col: u16,
    pub cursor_hidden: bool,
    pub mouse_mode: MouseMode,
    pub mouse_encoding: MouseEncoding,
}

pub fn socket_path() -> String {
    let user = std::env::var("USER").unwrap_or_else(|_| "user".to_string());
    format!("/tmp/fafnir-{}.sock", user)
}
