use async_trait::async_trait;
use serde_json::{json, Value};

use crate::filetree::mode::{DisplayMode, FilterOption, SortOption};
use crate::filetree::FileTree;

pub struct TreeMode;

#[async_trait]
impl DisplayMode for TreeMode {
    fn name(&self) -> &'static str {
        "tree"
    }

    fn render(&self, tree: &FileTree) -> Value {
        let nodes: Vec<Value> = tree
            .nodes
            .iter()
            .map(|n| {
                json!({
                    "node_id": n.node_id,
                    "label": n.label,
                    "aliases": n.aliases,
                    "file_uuid": n.file_uuid,
                    "sha256": n.sha256,
                    "parent_id": n.parent_id,
                    "node_type": n.node_type.as_str(),
                    "icon": n.icon,
                    "color": n.color,
                    "bg_color": n.bg_color,
                    "file_size": n.file_size,
                    "registered_at": n.registered_at,
                    "children": n.children,
                })
            })
            .collect();

        json!({
            "mode": "tree",
            "user_id": tree.user_id,
            "nodes": nodes,
        })
    }

    fn sort_options(&self) -> Vec<SortOption> {
        vec![
            SortOption {
                key: "name_asc".into(),
                label: "Name A-Z".into(),
            },
            SortOption {
                key: "name_desc".into(),
                label: "Name Z-A".into(),
            },
            SortOption {
                key: "date_desc".into(),
                label: "Newest First".into(),
            },
            SortOption {
                key: "date_asc".into(),
                label: "Oldest First".into(),
            },
        ]
    }

    fn filter_options(&self) -> Vec<FilterOption> {
        vec![
            FilterOption {
                key: "all".into(),
                label: "All".into(),
            },
            FilterOption {
                key: "folder".into(),
                label: "Folders".into(),
            },
            FilterOption {
                key: "file".into(),
                label: "Files".into(),
            },
        ]
    }
}
