use clap::{Parser, Subcommand};
use thiserror::Error;
use crate::database::Database;
use crate::database::DatabaseError;
use crate::models::{Task, Note, JournalEntry};
use crate::utils::{parse_date, get_current_date_string};
#[derive(Parser)]
#[command(name = "tnj")]
#[command(about = "Tasks, Notes, Journal - A lightweight terminal application")]
#[command(version)]
pub struct Cli {
#[arg(short, long)]
pub config: Option<String>,
#[arg(long)]
pub dev: bool,
#[command(subcommand)]
pub command: Option<Commands>,
}
#[derive(Subcommand)]
pub enum Commands {
Tui,
AddTask {
title: String,
#[arg(long)]
due: Option<String>,
#[arg(long)]
tags: Option<String>,
},
AddNote {
title: String,
#[arg(long)]
content: Option<String>,
#[arg(long)]
tags: Option<String>,
},
AddJournal {
content: String,
#[arg(long)]
title: Option<String>,
#[arg(long)]
tags: Option<String>,
},
}
#[derive(Debug, Error)]
pub enum CliError {
#[error("Database error: {0}")]
DatabaseError(#[from] DatabaseError),
#[error("Failed to parse date: {0}")]
DateParseError(String),
}
pub fn handle_add_task(
title: String,
due: Option<String>,
tags: Option<String>,
db: &Database,
) -> Result<(), CliError> {
let due_date = if let Some(due_str) = due {
parse_date(&due_str)
.map_err(|e| CliError::DateParseError(format!("Invalid date format '{}': {}", due_str, e)))?;
Some(due_str)
} else {
None
};
let mut task = Task::new(title);
task.due_date = due_date;
task.tags = tags;
let max_order = db.get_max_task_order().unwrap_or(-1);
task.order = max_order + 1;
let id = db.insert_task(&task)?;
println!("Task created successfully (ID: {})", id);
Ok(())
}
pub fn handle_add_note(
title: String,
content: Option<String>,
tags: Option<String>,
db: &Database,
) -> Result<(), CliError> {
let mut note = Note::new(title);
note.content = content;
note.tags = tags;
let id = db.insert_note(¬e)?;
println!("Note created successfully (ID: {})", id);
Ok(())
}
pub fn handle_add_journal(
content: String,
title: Option<String>,
tags: Option<String>,
db: &Database,
) -> Result<(), CliError> {
let date = get_current_date_string();
let mut journal = JournalEntry::new(date);
journal.content = Some(content);
journal.title = title;
journal.tags = tags;
let id = db.insert_journal(&journal)?;
println!("Journal entry created successfully (ID: {})", id);
Ok(())
}