use crate::config::Config;
use anyhow::Result;
use colored::Colorize;
use std::io::{self, BufRead, Write};
use std::path::{Path, PathBuf};
pub fn run(config_path: &Path, force: bool) -> Result<()> {
if config_path.exists() && !force {
println!("{}", "Config file already exists:".yellow());
println!(" {}", config_path.display());
println!();
print!("Overwrite it? [y/N] ");
io::stdout().flush()?;
let mut line = String::new();
io::stdin().lock().read_line(&mut line)?;
let answer = line.trim().to_lowercase();
if answer != "y" && answer != "yes" {
println!("Aborted.");
println!(
" {} use {} to materialise all config keys into the existing file",
"tip:".cyan(),
"mps config init".bold()
);
return Ok(());
}
}
println!("{}", "mps init — interactive setup".white().bold());
println!(" Press Enter to accept the default shown in [brackets].");
println!();
let home = dirs::home_dir().unwrap_or_else(|| PathBuf::from("."));
let default_mps_dir = home.join(".mps");
let mps_dir_str = prompt(
"Journal directory (mps_dir)",
&default_mps_dir.display().to_string(),
)?;
let mps_dir = PathBuf::from(&mps_dir_str);
let default_storage_dir = mps_dir.join("mps");
let storage_dir_str = prompt(
"Storage directory (storage_dir)",
&default_storage_dir.display().to_string(),
)?;
let storage_dir = PathBuf::from(&storage_dir_str);
let log_file = mps_dir.join("mps.log");
let git_remote = prompt("Git remote", "origin")?;
let git_branch = prompt("Git branch", "master")?;
println!();
println!(" Default command when 'mps' is run with no arguments:");
println!(" open — open today's file in $EDITOR");
println!(" list — list today's elements");
let cmd_input = prompt("Default command (open/list)", "open")?;
let default_command = if cmd_input.trim().to_lowercase().starts_with('l') {
"list"
} else {
"open"
};
println!();
println!(
"{}",
"── LLM chat settings ─────────────────────────────────".white()
);
println!(" Leave URL blank to auto-detect Ollama (:11434) or llama.cpp (:8080).");
let chat_url_input = prompt("Chat LLM URL (blank = auto-detect)", "")?;
let chat_url = if chat_url_input.trim().is_empty() {
None
} else {
Some(chat_url_input.trim().to_string())
};
let chat_model = prompt("Chat model name", "llama3.2")?;
println!();
let mut cfg = Config::default_config()?;
cfg.mps_dir = mps_dir;
cfg.storage_dir = storage_dir;
cfg.log_file = log_file;
cfg.git_remote = git_remote;
cfg.git_branch = git_branch;
cfg.default_command = default_command.to_string();
cfg.chat.url = chat_url;
cfg.chat.model = chat_model;
if let Some(parent) = config_path.parent() {
if !parent.as_os_str().is_empty() {
std::fs::create_dir_all(parent)?;
}
}
cfg.save(config_path)?;
cfg.ensure_dirs()?;
println!("{} {}", "created:".green(), config_path.display());
println!("{} {}", "created:".green(), cfg.mps_dir.display());
println!("{} {}", "created:".green(), cfg.storage_dir.display());
println!();
println!(
" {} run {} to see all settings",
"tip:".cyan(),
"mps config show".bold()
);
println!(
" {} run {} to validate config health",
"tip:".cyan(),
"mps config check".bold()
);
println!(
" {} run {} to push config to git",
"tip:".cyan(),
"mps autogit".bold()
);
Ok(())
}
fn prompt(label: &str, default: &str) -> Result<String> {
if default.is_empty() {
print!(" {}: ", label);
} else {
print!(" {} [{}]: ", label, default);
}
io::stdout().flush()?;
let mut line = String::new();
io::stdin().lock().read_line(&mut line)?;
let trimmed = line.trim().to_string();
if trimmed.is_empty() && !default.is_empty() {
Ok(default.to_string())
} else {
Ok(trimmed)
}
}