use crate::client::KeepClient;
use crate::modes::common::{
    ColumnType, OutputFormat, format_size, render_list_table_with_format, settings_output_format,
};
use clap::Command;
use log::debug;
use std::str::FromStr;

pub fn mode(
    client: &KeepClient,
    _cmd: &mut Command,
    settings: &crate::config::Settings,
    tags: &[String],
) -> Result<(), anyhow::Error> {
    debug!("CLIENT_LIST: Listing items via remote server");

    let meta_filter: std::collections::HashMap<String, Option<String>> = settings
        .meta
        .iter()
        .map(|(k, v)| (k.clone(), v.clone()))
        .collect();
    let items = client.list_items(tags, "newest", 0, 100, &meta_filter)?;

    let output_format = settings_output_format(settings);

    match output_format {
        OutputFormat::Json | OutputFormat::Yaml => {
            crate::modes::common::print_serialized(&items, &output_format)?;
        }
        OutputFormat::Table => {
            let rows: Vec<Vec<String>> = items
                .iter()
                .map(|item| {
                    let mut row = Vec::new();
                    for column in &settings.list_format {
                        let col_type = ColumnType::from_str(&column.name).ok();
                        let cell = match col_type {
                            Some(ColumnType::Id) => item.id.to_string(),
                            Some(ColumnType::Time) => item.ts.clone(),
                            Some(ColumnType::Size) => item
                                .size
                                .map(|s| format_size(s as u64, settings.human_readable))
                                .unwrap_or_default(),
                            Some(ColumnType::Compression) => item.compression.clone(),
                            Some(ColumnType::Tags) => item.tags.join(" "),
                            Some(ColumnType::Meta) => {
                                let meta_key = column.name.strip_prefix("meta:");
                                match meta_key {
                                    Some(key) => {
                                        item.metadata.get(key).cloned().unwrap_or_default()
                                    }
                                    None => String::new(),
                                }
                            }
                            _ => String::new(),
                        };
                        row.push(cell);
                    }
                    row
                })
                .collect();

            render_list_table_with_format(&settings.list_format, &rows, &settings.table_config);
        }
    }

    Ok(())
}
