use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::str::FromStr;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FileNode {
    pub node_id: String,
    pub label: String,
    pub aliases: Aliases,
    pub file_uuid: Option<String>,
    pub sha256: Option<String>,
    pub parent_id: Option<String>,
    pub children: Vec<String>,
    pub node_type: NodeType,
    pub icon: Option<String>,
    pub color: Option<String>,
    pub bg_color: Option<String>,
    pub file_size: Option<i64>,
    pub registered_at: Option<String>,
    pub created_at: String,
    pub updated_at: String,
    pub sort_order: i32,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Aliases {
    #[serde(flatten)]
    pub map: HashMap<String, String>,
}

impl Aliases {
    pub fn empty() -> Self {
        Aliases {
            map: HashMap::new(),
        }
    }

    pub fn to_json(&self) -> String {
        serde_json::to_string(&self.map).unwrap_or_else(|_| "{}".to_string())
    }

    pub fn from_json(s: &str) -> Self {
        let map: HashMap<String, String> = serde_json::from_str(s).unwrap_or_default();
        Aliases { map }
    }

    pub fn set(&mut self, lang: &str, value: &str) {
        self.map.insert(lang.to_string(), value.to_string());
    }

    pub fn get(&self, lang: &str) -> Option<&String> {
        self.map.get(lang)
    }

    pub fn first_value(&self) -> Option<&String> {
        self.map.values().next()
    }
}

#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum NodeType {
    Folder,
    File,
    DynamicLayer,
}

impl NodeType {
    pub fn as_str(&self) -> &'static str {
        match self {
            NodeType::Folder => "folder",
            NodeType::File => "file",
            NodeType::DynamicLayer => "dynamic_layer",
        }
    }
}

impl FromStr for NodeType {
    type Err = String;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "folder" => Ok(NodeType::Folder),
            "file" => Ok(NodeType::File),
            "dynamic_layer" => Ok(NodeType::DynamicLayer),
            _ => Ok(NodeType::Folder), // Default to Folder for unknown types
        }
    }
}
