use std::collections::HashMap;
use std::path::PathBuf;
use serde_yaml::Value;

use super::manifest::{EntityManifest, SceneManifest, load_entity_manifest, ManifestLoaderError};

#[derive(Debug, thiserror::Error)]
pub enum SolverError {
    #[error("Manifest loader error: {0}")]
    ManifestLoader(#[from] ManifestLoaderError),
    #[error("Template not found: {0}")]
    TemplateNotFound(String),
    #[error("Component merge error: {0}")]
    ComponentMerge(String),
}

pub struct ResolvedScene {
    pub entities: HashMap<String, HashMap<String, Value>>,
}

pub struct ManifestSolver {
    entity_cache: HashMap<String, EntityManifest>,
    base_path: PathBuf,
}

impl ManifestSolver {
    pub fn new<P: Into<PathBuf>>(base_path: P) -> Self {
        Self {
            entity_cache: HashMap::new(),
            base_path: base_path.into(),
        }
    }
    
    pub fn resolve_scene(&mut self, scene: &SceneManifest) -> Result<ResolvedScene, SolverError> {
        let mut resolved = HashMap::new();
        
        for (name, entity_instance) in &scene.entities {
            let components = if let Some(template) = &entity_instance.template {
                // 템플릿 로드
                let template_manifest = self.load_template(template)?;
                
                // 템플릿 + 오버라이드 병합
                Self::merge_components(&template_manifest.components, &entity_instance.components)?
            } else {
                entity_instance.components.clone()
            };
            
            resolved.insert(name.clone(), components);
        }
        
        Ok(ResolvedScene { entities: resolved })
    }
    
    fn load_template(&mut self, template_path: &str) -> Result<&EntityManifest, SolverError> {
        if !self.entity_cache.contains_key(template_path) {
            let full_path = self.base_path.join("world").join("entities").join(format!("{}.yaml", template_path));
            let manifest = load_entity_manifest(full_path)?;
            self.entity_cache.insert(template_path.to_string(), manifest);
        }
        Ok(&self.entity_cache[template_path])
    }
    
    fn merge_components(
        template_components: &HashMap<String, Value>, 
        overrides: &HashMap<String, Value>
    ) -> Result<HashMap<String, Value>, SolverError> {
        let mut merged = template_components.clone();
        
        // 단순 오버라이드 병합
        for (key, value) in overrides {
            merged.insert(key.clone(), value.clone());
        }
        
        Ok(merged)
    }
}