use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::collections::HashMap;

// =============================================================================
// Serde Helpers for HashMap with [u8; 32] keys
// =============================================================================

/// Serialize HashMap<[u8; 32], V> with hex string keys for JSON compatibility
pub mod hex_key_map {
    use super::*;

    pub fn serialize<S, V>(map: &HashMap<[u8; 32], V>, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
        V: Serialize,
    {
        use serde::ser::SerializeMap;
        let mut ser_map = serializer.serialize_map(Some(map.len()))?;
        for (key, value) in map {
            ser_map.serialize_entry(&hex::encode(key), value)?;
        }
        ser_map.end()
    }

    pub fn deserialize<'de, D, V>(deserializer: D) -> Result<HashMap<[u8; 32], V>, D::Error>
    where
        D: Deserializer<'de>,
        V: Deserialize<'de>,
    {
        use serde::de::Error;
        let string_map: HashMap<String, V> = HashMap::deserialize(deserializer)?;
        let mut result = HashMap::with_capacity(string_map.len());
        for (key_str, value) in string_map {
            let key_bytes = hex::decode(&key_str)
                .map_err(|e| D::Error::custom(format!("invalid hex key '{}': {}", key_str, e)))?;
            if key_bytes.len() != 32 {
                return Err(D::Error::custom(format!(
                    "hex key '{}' has wrong length: expected 32 bytes, got {}",
                    key_str,
                    key_bytes.len()
                )));
            }
            let mut key = [0u8; 32];
            key.copy_from_slice(&key_bytes);
            result.insert(key, value);
        }
        Ok(result)
    }
}

/// Serialize HashMap<[u8; 32], PathBuf> with hex string keys
pub mod hex_key_pathbuf_map {
    use std::path::PathBuf;

    use super::*;

    pub fn serialize<S>(map: &HashMap<[u8; 32], PathBuf>, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        use serde::ser::SerializeMap;
        let mut ser_map = serializer.serialize_map(Some(map.len()))?;
        for (key, value) in map {
            ser_map.serialize_entry(&hex::encode(key), value)?;
        }
        ser_map.end()
    }

    pub fn deserialize<'de, D>(deserializer: D) -> Result<HashMap<[u8; 32], PathBuf>, D::Error>
    where
        D: Deserializer<'de>,
    {
        use serde::de::Error;
        let string_map: HashMap<String, PathBuf> = HashMap::deserialize(deserializer)?;
        let mut result = HashMap::with_capacity(string_map.len());
        for (key_str, value) in string_map {
            let key_bytes = hex::decode(&key_str)
                .map_err(|e| D::Error::custom(format!("invalid hex key '{}': {}", key_str, e)))?;
            if key_bytes.len() != 32 {
                return Err(D::Error::custom(format!(
                    "hex key '{}' has wrong length: expected 32 bytes, got {}",
                    key_str,
                    key_bytes.len()
                )));
            }
            let mut key = [0u8; 32];
            key.copy_from_slice(&key_bytes);
            result.insert(key, value);
        }
        Ok(result)
    }
}
