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

/// 게임 세계 - 엔티티와 시스템을 관리하는 최상위 컨테이너
pub struct World {
    /// 모든 엔티티
    entities: Vec<Entity>,
    /// 엔티티 ID를 인덱스로 매핑하는 해시맵
    entity_indices: HashMap<EntityId, usize>,
    /// 다음 엔티티 ID
    next_entity_id: u64,
    /// 시스템 스케줄러
    scheduler: SystemScheduler,
    /// 삭제 대기 중인 엔티티 ID들
    entities_to_remove: Vec<EntityId>,
    /// 카메라
    pub camera: Camera,
}

impl World {
    pub fn new() -> Self {
        Self {
            entities: Vec::new(),
            entity_indices: HashMap::new(),
            next_entity_id: 1,
            scheduler: SystemScheduler::new(),
            entities_to_remove: Vec::new(),
            camera: Camera::new(),
        }
    }
    
    /// 새 엔티티 생성
    pub fn create_entity(&mut self) -> EntityId {
        let id = EntityId::new(self.next_entity_id);
        self.next_entity_id += 1;
        
        let entity = Entity::new(id);
        let index = self.entities.len();
        
        self.entities.push(entity);
        self.entity_indices.insert(id, index);
        
        id
    }
    
    /// 엔티티 가져오기 (불변 참조)
    pub fn get_entity(&self, entity_id: EntityId) -> Option<&Entity> {
        self.entity_indices.get(&entity_id)
            .and_then(|&index| self.entities.get(index))
    }
    
    /// 엔티티 가져오기 (가변 참조)
    pub fn get_entity_mut(&mut self, entity_id: EntityId) -> Option<&mut Entity> {
        self.entity_indices.get(&entity_id)
            .and_then(|&index| self.entities.get_mut(index))
    }
    
    /// 엔티티 삭제 예약 (다음 프레임에 실제 삭제됨)
    pub fn destroy_entity(&mut self, entity_id: EntityId) {
        if self.entity_indices.contains_key(&entity_id) {
            self.entities_to_remove.push(entity_id);
        }
    }
    
    /// 모든 엔티티 가져오기 (불변 참조) - 읽기 전용
    pub fn entities(&self) -> &[Entity] {
        &self.entities
    }
    
    /// 모든 엔티티 가져오기 (가변 참조) - 시스템에서만 사용
    pub fn entities_mut(&mut self) -> &mut Vec<Entity> {
        &mut self.entities
    }
    
    /// 시스템 등록
    pub fn register_system<T: System + 'static>(&mut self, system: T) -> Result<SystemId, SystemError> {
        self.scheduler.register_system(system)
    }
    
    /// 월드 초기화 (모든 시스템 초기화)
    pub fn initialize(&mut self) -> Result<(), SystemError> {
        self.scheduler.initialize()
    }
    
    /// 한 프레임 업데이트
    pub fn update(&mut self, delta_time: f32, input: &InputState) -> Result<(), SystemError> {
        // 1. 카메라 업데이트 (먼저!)
        self.camera.update(delta_time, input);
        
        // 2. 시스템 업데이트
        self.scheduler.update(delta_time, &mut self.entities, input, &self.camera)?;
        
        // 3. 삭제 예약된 엔티티들 처리
        self.process_entity_removals();
        
        Ok(())
    }
    
    /// 월드 종료 (모든 시스템 종료)
    pub fn shutdown(&mut self) -> Result<(), SystemError> {
        self.scheduler.shutdown()
    }
    
    /// 카메라 참조 가져오기
    pub fn camera(&self) -> &Camera {
        &self.camera
    }
    
    /// 카메라 가변 참조 가져오기
    pub fn camera_mut(&mut self) -> &mut Camera {
        &mut self.camera
    }
    
    // 내부 헬퍼 메서드들
    
    /// 삭제 예약된 엔티티들 처리
    fn process_entity_removals(&mut self) {
        for entity_id in self.entities_to_remove.drain(..) {
            if let Some(&index) = self.entity_indices.get(&entity_id) {
                self.entities.remove(index);
                self.entity_indices.remove(&entity_id);
                
                // 인덱스 재조정
                for (_, stored_index) in self.entity_indices.iter_mut() {
                    if *stored_index > index {
                        *stored_index -= 1;
                    }
                }
            }
        }
    }
}

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