use std::collections::HashMap;
use crate::core::{Entity, System, SystemId, SystemContext, SystemError, InputState};
use super::camera::Camera;

/// 시스템 스케줄러 - 시스템들의 실행 순서와 의존성을 관리
pub struct SystemScheduler {
    /// 등록된 시스템들
    systems: HashMap<SystemId, Box<dyn System>>,
    /// 초기화 여부
    initialized: bool,
    /// 프레임 카운터
    frame_number: u64,
    /// 총 실행 시간
    total_time: f32,
}

impl SystemScheduler {
    pub fn new() -> Self {
        Self {
            systems: HashMap::new(),
            initialized: false,
            frame_number: 0,
            total_time: 0.0,
        }
    }
    
    /// 시스템 등록
    pub fn register_system<T: System + 'static>(&mut self, mut system: T) -> Result<SystemId, SystemError> {
        let id = SystemId::from_type::<T>();
        
        // 시스템 초기화
        if self.initialized {
            system.initialize().map_err(|e| 
                SystemError::InitializationFailed(format!("Failed to initialize {}: {}", system.name(), e))
            )?;
        }
        
        self.systems.insert(id, Box::new(system));
        Ok(id)
    }
    
    /// 모든 시스템 초기화
    pub fn initialize(&mut self) -> Result<(), SystemError> {
        if self.initialized {
            return Ok(());
        }
        
        for system in self.systems.values_mut() {
            system.initialize().map_err(|e| 
                SystemError::InitializationFailed(format!("Failed to initialize {}: {}", system.name(), e))
            )?;
        }
        
        self.initialized = true;
        Ok(())
    }
    
    /// 한 프레임 업데이트 실행
    pub fn update(&mut self, delta_time: f32, entities: &mut Vec<Entity>, input: &InputState, camera: &Camera) -> Result<(), SystemError> {
        if !self.initialized {
            return Err(SystemError::RuntimeError("Scheduler not initialized".to_string()));
        }
        
        self.frame_number += 1;
        self.total_time += delta_time;
        
        let mut context = SystemContext::new(
            delta_time,
            self.frame_number,
            self.total_time,
            entities,
            input,
            camera
        );
        
        // 모든 시스템 순차 실행
        for system in self.systems.values_mut() {
            if system.is_enabled() {
                system.update(&mut context).map_err(|e| {
                    SystemError::UpdateFailed(format!("System {} failed: {}", system.name(), e))
                })?;
            }
        }
        
        Ok(())
    }
    
    /// 모든 시스템 종료
    pub fn shutdown(&mut self) -> Result<(), SystemError> {
        for system in self.systems.values_mut() {
            system.shutdown().map_err(|e| {
                SystemError::ShutdownFailed(format!("Failed to shutdown {}: {}", system.name(), e))
            })?;
        }
        
        self.systems.clear();
        self.initialized = false;
        
        Ok(())
    }
}

impl Default for SystemScheduler {
    fn default() -> Self {
        Self::new()
    }
}
