use crate::file::{resolve_hash, CitrineFile};
use crate::task::Status;
use anyhow::Result;
use chrono::Local;
use std::path::Path;

pub fn run(dir: &Path, partial_hash: &str, status_name: &str) -> Result<()> {
    let citrine_path = dir.join(".citrine");
    if !citrine_path.exists() {
        anyhow::bail!("Not initialized. Run 'citrine init' first");
    }

    let new_status = Status::from_name(status_name).ok_or_else(|| {
        anyhow::anyhow!("Invalid status '{}'. Valid statuses: todo, progress, blocked, done", status_name)
    })?;

    let mut main_file = CitrineFile::read_or_empty(&citrine_path);
    let mut local_file = CitrineFile::read_or_empty(&dir.join(".citrine.local"));

    let (hash, is_local) = resolve_hash(&main_file, &local_file, partial_hash)?;

    let file = if is_local { &mut local_file } else { &mut main_file };
    let task = file.find_task_mut(&hash).unwrap();

    let old_status = task.status.clone();
    task.status = new_status.clone();

    if new_status == Status::Done && !task.metadata.contains("@completed:") {
        let date = Local::now().format("%Y-%m-%d").to_string();
        let completed_tag = format!("@completed:{}", date);
        if task.metadata.is_empty() {
            task.metadata = completed_tag;
        } else {
            task.metadata = format!("{} {}", task.metadata, completed_tag);
        }
        println!("Added @completed:{}", date);
    }

    println!("Updated [{}]: {} → {}", hash, old_status, new_status);

    let path = if is_local {
        dir.join(".citrine.local")
    } else {
        citrine_path
    };
    file.write(&path)?;

    Ok(())
}
