use crate::file::CitrineFile;
use crate::task::{Line, Status};
use anyhow::Result;
use colored::Colorize;
use std::path::Path;

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

    let filter = match status_filter {
        Some(s) => Some(Status::from_name(s).ok_or_else(|| {
            anyhow::anyhow!("Invalid status '{}'. Valid statuses: todo, progress, blocked, done", s)
        })?),
        None => None,
    };

    let files: Vec<CitrineFile> = if local_only {
        vec![CitrineFile::read_or_empty(&dir.join(".citrine.local"))]
    } else {
        vec![
            CitrineFile::read_or_empty(&citrine_path),
            CitrineFile::read_or_empty(&dir.join(".citrine.local")),
        ]
    };

    let mut has_output = false;
    for file in &files {
        for line in &file.lines {
            match line {
                Line::Task(t) => {
                    if filter.as_ref().map_or(true, |f| t.status == *f) {
                        let status_str = match t.status {
                            Status::Todo => format!("[{}]", t.status.symbol()),
                            Status::InProgress => format!("[{}]", t.status.symbol()).yellow().to_string(),
                            Status::Blocked => format!("[{}]", t.status.symbol()).red().to_string(),
                            Status::Done => format!("[{}]", t.status.symbol()).green().to_string(),
                        };
                        let meta = if t.metadata.is_empty() {
                            String::new()
                        } else {
                            format!(" {}", t.metadata.dimmed())
                        };
                        println!("[{}] {} {}{}", t.hash, status_str, t.description, meta);
                        has_output = true;
                    }
                }
                Line::Section(s) => {
                    if filter.is_none() {
                        println!("{}", format!("## {}", s).bold());
                        has_output = true;
                    }
                }
                Line::Other(s) if !s.trim().is_empty() && filter.is_none() => {
                    println!("{}", s);
                    has_output = true;
                }
                Line::Other(_) if filter.is_none() => {
                    println!();
                    has_output = true;
                }
                _ => {}
            }
        }
    }

    if !has_output && filter.is_some() {
        println!("No tasks matching filter.");
    }

    Ok(())
}
