//! `relicario settings {show, trash-retention, history-retention, attachment-cap, generator-defaults}`.

use anyhow::Result;

use crate::SettingsAction;

pub fn cmd_settings(action: SettingsAction) -> Result<()> {
    use relicario_core::{
        Capitalization, CharClasses, GeneratorRequest, HistoryRetention,
        SymbolCharset, TrashRetention,
    };

    let vault = crate::session::UnlockedVault::unlock_interactive()?;
    let mut settings = vault.load_settings()?;

    match action {
        SettingsAction::Show => {
            println!("{}", serde_json::to_string_pretty(&settings)?);
            return Ok(());
        }
        SettingsAction::TrashRetention { days, forever } => {
            settings.trash_retention = match (days, forever) {
                (Some(d), false) => TrashRetention::Days(d),
                (None, true) => TrashRetention::Forever,
                _ => anyhow::bail!("specify exactly one of --days or --forever"),
            };
        }
        SettingsAction::HistoryRetention { last_n, days, forever } => {
            settings.field_history_retention = match (last_n, days, forever) {
                (Some(n), None, false) => HistoryRetention::LastN(n),
                (None, Some(d), false) => HistoryRetention::Days(d),
                (None, None, true) => HistoryRetention::Forever,
                _ => anyhow::bail!("specify exactly one of --last-n / --days / --forever"),
            };
        }
        SettingsAction::AttachmentCap {
            per_attachment_max_bytes, per_item_max_count,
            per_vault_soft_cap_bytes, per_vault_hard_cap_bytes,
        } => {
            if let Some(v) = per_attachment_max_bytes { settings.attachment_caps.per_attachment_max_bytes = v; }
            if let Some(v) = per_item_max_count { settings.attachment_caps.per_item_max_count = v; }
            if let Some(v) = per_vault_soft_cap_bytes { settings.attachment_caps.per_vault_soft_cap_bytes = v; }
            if let Some(v) = per_vault_hard_cap_bytes { settings.attachment_caps.per_vault_hard_cap_bytes = v; }
        }
        SettingsAction::GeneratorDefaults {
            random, bip39, length, words, symbols, separator,
        } => {
            // Decide target mode: explicit flag wins, else preserve current.
            let target_bip39 = if random { false }
                else if bip39 { true }
                else { matches!(settings.generator_defaults, GeneratorRequest::Bip39 { .. }) };

            // Pull existing fields where compatible, else seed with sensible
            // defaults (kept in sync with `GeneratorRequest::default()`).
            let (cur_length, cur_classes, cur_charset) = match &settings.generator_defaults {
                GeneratorRequest::Random { length, classes, symbol_charset } => {
                    (*length, *classes, symbol_charset.clone())
                }
                _ => (
                    20,
                    CharClasses { lower: true, upper: true, digits: true, symbols: true },
                    SymbolCharset::SafeOnly,
                ),
            };
            let (cur_words, cur_sep, cur_cap) = match &settings.generator_defaults {
                GeneratorRequest::Bip39 { word_count, separator, capitalization } => {
                    (*word_count, separator.clone(), *capitalization)
                }
                _ => (5, " ".to_string(), Capitalization::Lower),
            };

            settings.generator_defaults = if target_bip39 {
                GeneratorRequest::Bip39 {
                    word_count: words.unwrap_or(cur_words),
                    separator: separator.unwrap_or(cur_sep),
                    capitalization: cur_cap,
                }
            } else {
                let charset = match symbols.as_deref() {
                    None => cur_charset,
                    Some("safe") => SymbolCharset::SafeOnly,
                    Some("extended") => SymbolCharset::Extended,
                    Some(other) => SymbolCharset::Custom(other.to_string()),
                };
                GeneratorRequest::Random {
                    length: length.unwrap_or(cur_length),
                    classes: cur_classes,
                    symbol_charset: charset,
                }
            };
        }
    }

    vault.save_settings(&settings)?;
    super::commit_paths(&vault, "settings: update", &["settings.enc"])?;
    eprintln!("Settings updated.");
    Ok(())
}
