use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct ClaudeStartOptions {
    #[serde(default)]
    pub working_dir: String,

    #[serde(default)]
    pub model: Option<String>,

    #[serde(default)]
    pub api_key: Option<String>,

    #[serde(default)]
    pub custom_instructions: Option<String>,

    #[serde(default)]
    pub mcp_servers_json: Option<String>,

    #[serde(default)]
    pub allowed_tools: Vec<String>,

    #[serde(default)]
    pub skip_greeting: bool,

    #[serde(default)]
    pub resume_session_id: Option<String>,

    #[serde(default)]
    pub use_worktree: bool,

    #[serde(default)]
    pub disable_1m_context: bool,

    #[serde(default)]
    pub max_output_tokens: Option<u64>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(default)]
pub struct HikariConfig {
    #[serde(default)]
    pub model: Option<String>,

    #[serde(default)]
    pub api_key: Option<String>,

    #[serde(default)]
    pub custom_instructions: Option<String>,

    #[serde(default)]
    pub mcp_servers_json: Option<String>,

    #[serde(default)]
    pub auto_granted_tools: Vec<String>,

    #[serde(default)]
    pub theme: Theme,

    #[serde(default = "default_greeting_enabled")]
    pub greeting_enabled: bool,

    #[serde(default)]
    pub greeting_custom_prompt: Option<String>,

    #[serde(default = "default_notifications_enabled")]
    pub notifications_enabled: bool,

    #[serde(default = "default_notification_volume")]
    pub notification_volume: f32,

    #[serde(default)]
    pub always_on_top: bool,

    #[serde(default = "default_update_checks_enabled")]
    pub update_checks_enabled: bool,

    #[serde(default)]
    pub character_panel_width: Option<u32>,

    #[serde(default = "default_font_size")]
    pub font_size: u32,

    #[serde(default)]
    pub streamer_mode: bool,

    #[serde(default)]
    pub streamer_hide_paths: bool,

    #[serde(default)]
    pub compact_mode: bool,

    // Profile fields
    #[serde(default)]
    pub profile_name: Option<String>,

    #[serde(default)]
    pub profile_avatar_path: Option<String>,

    #[serde(default)]
    pub profile_bio: Option<String>,

    // Custom theme colors
    #[serde(default)]
    pub custom_theme_colors: CustomThemeColors,

    // Token budget settings
    #[serde(default)]
    pub budget_enabled: bool,

    #[serde(default)]
    pub session_token_budget: Option<u64>,

    #[serde(default)]
    pub session_cost_budget: Option<f64>,

    #[serde(default = "default_budget_action")]
    pub budget_action: BudgetAction,

    #[serde(default = "default_budget_warning_threshold")]
    pub budget_warning_threshold: f32,

    #[serde(default = "default_discord_rpc_enabled")]
    pub discord_rpc_enabled: bool,

    #[serde(default)]
    pub use_worktree: bool,

    #[serde(default)]
    pub disable_1m_context: bool,

    #[serde(default)]
    pub max_output_tokens: Option<u64>,

    #[serde(default)]
    pub trusted_workspaces: Vec<String>,

    // Background image settings
    #[serde(default)]
    pub background_image_path: Option<String>,

    #[serde(default = "default_background_image_opacity")]
    pub background_image_opacity: f32,

    #[serde(default)]
    pub show_thinking_blocks: bool,

    // Custom terminal font settings
    #[serde(default)]
    pub custom_font_path: Option<String>,

    #[serde(default)]
    pub custom_font_family: Option<String>,

    // Custom UI font settings
    #[serde(default)]
    pub custom_ui_font_path: Option<String>,

    #[serde(default)]
    pub custom_ui_font_family: Option<String>,

    // Task Loop auto-commit settings
    #[serde(default)]
    pub task_loop_auto_commit: bool,

    #[serde(default = "default_task_loop_commit_prefix")]
    pub task_loop_commit_prefix: String,

    #[serde(default)]
    pub task_loop_include_summary: bool,
}

impl Default for HikariConfig {
    fn default() -> Self {
        Self {
            model: None,
            api_key: None,
            custom_instructions: None,
            mcp_servers_json: None,
            auto_granted_tools: Vec::new(),
            theme: Theme::default(),
            greeting_enabled: true,
            greeting_custom_prompt: None,
            notifications_enabled: true,
            notification_volume: 0.7,
            always_on_top: false,
            update_checks_enabled: true,
            character_panel_width: None,
            font_size: 14,
            streamer_mode: false,
            streamer_hide_paths: false,
            compact_mode: false,
            profile_name: None,
            profile_avatar_path: None,
            profile_bio: None,
            custom_theme_colors: CustomThemeColors::default(),
            budget_enabled: false,
            session_token_budget: None,
            session_cost_budget: None,
            budget_action: BudgetAction::Warn,
            budget_warning_threshold: 0.8,
            discord_rpc_enabled: true,
            use_worktree: false,
            disable_1m_context: false,
            max_output_tokens: None,
            trusted_workspaces: Vec::new(),
            background_image_path: None,
            background_image_opacity: 0.3,
            show_thinking_blocks: false,
            custom_font_path: None,
            custom_font_family: None,
            custom_ui_font_path: None,
            custom_ui_font_family: None,
            task_loop_auto_commit: false,
            task_loop_commit_prefix: "feat".to_string(),
            task_loop_include_summary: false,
        }
    }
}

fn default_update_checks_enabled() -> bool {
    true
}

fn default_greeting_enabled() -> bool {
    true
}

fn default_notifications_enabled() -> bool {
    true
}

fn default_notification_volume() -> f32 {
    0.7
}

fn default_font_size() -> u32 {
    14
}

fn default_budget_action() -> BudgetAction {
    BudgetAction::Warn
}

fn default_budget_warning_threshold() -> f32 {
    0.8
}

fn default_discord_rpc_enabled() -> bool {
    true
}

fn default_background_image_opacity() -> f32 {
    0.3
}

fn default_task_loop_commit_prefix() -> String {
    "feat".to_string()
}

#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum BudgetAction {
    #[default]
    Warn,
    Block,
}

#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum Theme {
    #[default]
    Dark,
    Light,
    #[serde(rename = "high-contrast")]
    HighContrast,
    Custom,
    Dracula,
    Catppuccin,
    Nord,
    Solarized,
    #[serde(rename = "solarized-light")]
    SolarizedLight,
    #[serde(rename = "catppuccin-latte")]
    CatppuccinLatte,
    #[serde(rename = "gruvbox-light")]
    GruvboxLight,
    #[serde(rename = "rose-pine-dawn")]
    RosePineDawn,
}

#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
pub struct CustomThemeColors {
    #[serde(default)]
    pub bg_primary: Option<String>,
    #[serde(default)]
    pub bg_secondary: Option<String>,
    #[serde(default)]
    pub bg_terminal: Option<String>,
    #[serde(default)]
    pub accent_primary: Option<String>,
    #[serde(default)]
    pub accent_secondary: Option<String>,
    #[serde(default)]
    pub text_primary: Option<String>,
    #[serde(default)]
    pub text_secondary: Option<String>,
    #[serde(default)]
    pub border_color: Option<String>,
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_default_config() {
        let config = HikariConfig::default();
        assert!(config.model.is_none());
        assert!(config.api_key.is_none());
        assert!(config.custom_instructions.is_none());
        assert!(config.mcp_servers_json.is_none());
        assert!(config.auto_granted_tools.is_empty());
        assert_eq!(config.theme, Theme::Dark);
        assert!(config.greeting_enabled);
        assert!(config.greeting_custom_prompt.is_none());
        assert!(!config.always_on_top);
        assert!(config.update_checks_enabled);
        assert!(config.character_panel_width.is_none());
        assert_eq!(config.font_size, 14);
        assert!(!config.streamer_mode);
        assert!(!config.streamer_hide_paths);
        assert!(!config.compact_mode);
        assert!(config.profile_name.is_none());
        assert!(config.profile_avatar_path.is_none());
        assert!(config.profile_bio.is_none());
        assert_eq!(config.custom_theme_colors, CustomThemeColors::default());
        assert!(!config.budget_enabled);
        assert!(config.session_token_budget.is_none());
        assert!(config.session_cost_budget.is_none());
        assert_eq!(config.budget_action, BudgetAction::Warn);
        assert!((config.budget_warning_threshold - 0.8).abs() < f32::EPSILON);
        assert!(config.discord_rpc_enabled);
        assert!(!config.use_worktree);
        assert!(!config.disable_1m_context);
        assert!(config.trusted_workspaces.is_empty());
        assert!(!config.show_thinking_blocks);
        assert!(config.custom_font_path.is_none());
        assert!(config.custom_font_family.is_none());
        assert!(config.custom_ui_font_path.is_none());
        assert!(config.custom_ui_font_family.is_none());
        assert!(!config.task_loop_auto_commit);
        assert_eq!(config.task_loop_commit_prefix, "feat");
        assert!(!config.task_loop_include_summary);
    }

    #[test]
    fn test_config_serialization() {
        let config = HikariConfig {
            model: Some("claude-sonnet-4-20250514".to_string()),
            api_key: None,
            custom_instructions: Some("Be helpful".to_string()),
            mcp_servers_json: None,
            auto_granted_tools: vec!["Read".to_string(), "Glob".to_string()],
            theme: Theme::Light,
            greeting_enabled: true,
            greeting_custom_prompt: Some("Hello!".to_string()),
            notifications_enabled: true,
            notification_volume: 0.7,
            always_on_top: true,
            update_checks_enabled: true,
            character_panel_width: Some(400),
            font_size: 16,
            streamer_mode: false,
            streamer_hide_paths: false,
            compact_mode: false,
            profile_name: Some("Test User".to_string()),
            profile_avatar_path: None,
            profile_bio: Some("A test bio".to_string()),
            custom_theme_colors: CustomThemeColors::default(),
            budget_enabled: true,
            session_token_budget: Some(100000),
            session_cost_budget: Some(1.50),
            budget_action: BudgetAction::Block,
            budget_warning_threshold: 0.75,
            discord_rpc_enabled: true,
            use_worktree: true,
            disable_1m_context: false,
            max_output_tokens: Some(32000),
            trusted_workspaces: vec!["/home/naomi/projects/trusted".to_string()],
            background_image_path: Some("/home/naomi/bg.png".to_string()),
            background_image_opacity: 0.25,
            show_thinking_blocks: true,
            custom_font_path: Some("/home/naomi/.fonts/MyFont.ttf".to_string()),
            custom_font_family: Some("MyFont".to_string()),
            custom_ui_font_path: None,
            custom_ui_font_family: None,
            task_loop_auto_commit: true,
            task_loop_commit_prefix: "fix".to_string(),
            task_loop_include_summary: true,
        };

        let json = serde_json::to_string(&config).unwrap();
        let deserialized: HikariConfig = serde_json::from_str(&json).unwrap();

        assert_eq!(deserialized.model, config.model);
        assert_eq!(deserialized.custom_instructions, config.custom_instructions);
        assert_eq!(deserialized.auto_granted_tools, config.auto_granted_tools);
        assert_eq!(deserialized.theme, Theme::Light);
        assert!(deserialized.greeting_enabled);
        assert_eq!(
            deserialized.greeting_custom_prompt,
            Some("Hello!".to_string())
        );
        assert!(deserialized.task_loop_auto_commit);
        assert_eq!(deserialized.task_loop_commit_prefix, "fix");
        assert!(deserialized.task_loop_include_summary);
    }

    #[test]
    fn test_theme_serialization() {
        assert_eq!(serde_json::to_string(&Theme::Dark).unwrap(), "\"dark\"");
        assert_eq!(serde_json::to_string(&Theme::Light).unwrap(), "\"light\"");
        assert_eq!(
            serde_json::to_string(&Theme::HighContrast).unwrap(),
            "\"high-contrast\""
        );
        assert_eq!(serde_json::to_string(&Theme::Custom).unwrap(), "\"custom\"");
        assert_eq!(
            serde_json::to_string(&Theme::Dracula).unwrap(),
            "\"dracula\""
        );
        assert_eq!(
            serde_json::to_string(&Theme::Catppuccin).unwrap(),
            "\"catppuccin\""
        );
        assert_eq!(serde_json::to_string(&Theme::Nord).unwrap(), "\"nord\"");
        assert_eq!(
            serde_json::to_string(&Theme::Solarized).unwrap(),
            "\"solarized\""
        );
        assert_eq!(
            serde_json::to_string(&Theme::SolarizedLight).unwrap(),
            "\"solarized-light\""
        );
        assert_eq!(
            serde_json::to_string(&Theme::CatppuccinLatte).unwrap(),
            "\"catppuccin-latte\""
        );
        assert_eq!(
            serde_json::to_string(&Theme::GruvboxLight).unwrap(),
            "\"gruvbox-light\""
        );
        assert_eq!(
            serde_json::to_string(&Theme::RosePineDawn).unwrap(),
            "\"rose-pine-dawn\""
        );
    }

    #[test]
    fn test_theme_deserialization() {
        assert_eq!(
            serde_json::from_str::<Theme>("\"dracula\"").unwrap(),
            Theme::Dracula
        );
        assert_eq!(
            serde_json::from_str::<Theme>("\"catppuccin\"").unwrap(),
            Theme::Catppuccin
        );
        assert_eq!(
            serde_json::from_str::<Theme>("\"nord\"").unwrap(),
            Theme::Nord
        );
        assert_eq!(
            serde_json::from_str::<Theme>("\"solarized\"").unwrap(),
            Theme::Solarized
        );
        assert_eq!(
            serde_json::from_str::<Theme>("\"solarized-light\"").unwrap(),
            Theme::SolarizedLight
        );
        assert_eq!(
            serde_json::from_str::<Theme>("\"catppuccin-latte\"").unwrap(),
            Theme::CatppuccinLatte
        );
        assert_eq!(
            serde_json::from_str::<Theme>("\"gruvbox-light\"").unwrap(),
            Theme::GruvboxLight
        );
        assert_eq!(
            serde_json::from_str::<Theme>("\"rose-pine-dawn\"").unwrap(),
            Theme::RosePineDawn
        );
    }
}
