use std::any::{Any, TypeId};
use std::fmt::Debug;
use super::entity::Entity;
use super::input::InputState;
use crate::runtime::Camera;

/// 시스템 고유 식별자
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct SystemId(u64);

impl SystemId {
    pub fn new(id: u64) -> Self {
        SystemId(id)
    }
    
    pub fn from_type<T: 'static>() -> Self {
        // TypeId를 해시해서 고유 ID 생성
        use std::collections::hash_map::DefaultHasher;
        use std::hash::{Hash, Hasher};
        
        let type_id = TypeId::of::<T>();
        let mut hasher = DefaultHasher::new();
        type_id.hash(&mut hasher);
        SystemId(hasher.finish())
    }
    
    pub fn as_u64(&self) -> u64 {
        self.0
    }
}

/// 시스템 실행 컨텍스트
pub struct SystemContext<'a> {
    /// 현재 프레임의 델타 타임 (초 단위)
    pub delta_time: f32,
    /// 프레임 번호
    pub frame_number: u64,
    /// 총 실행 시간 (초 단위)
    pub total_time: f32,
    /// 엔티티 컨테이너에 대한 참조
    pub entities: &'a mut Vec<Entity>,
    /// 입력 상태 (읽기 전용)
    pub input: &'a InputState,
    /// 카메라 참조 (읽기 전용)
    pub camera: &'a Camera,
}

impl<'a> SystemContext<'a> {
    pub fn new(
        delta_time: f32, 
        frame_number: u64, 
        total_time: f32, 
        entities: &'a mut Vec<Entity>,
        input: &'a InputState,
        camera: &'a Camera
    ) -> Self {
        Self {
            delta_time,
            frame_number,
            total_time,
            entities,
            input,
            camera,
        }
    }
}

/// 모든 시스템이 구현해야 하는 기본 트레이트
pub trait System: Any + Send + Sync {
    /// 시스템 초기화 (한 번만 호출)
    fn initialize(&mut self) -> Result<(), SystemError> {
        Ok(())
    }
    
    /// 매 프레임 업데이트 (필수 구현)
    fn update(&mut self, context: &mut SystemContext) -> Result<(), SystemError>;
    
    /// 시스템 종료 처리 (한 번만 호출)
    fn shutdown(&mut self) -> Result<(), SystemError> {
        Ok(())
    }
    
    /// 시스템 이름 반환
    fn name(&self) -> &'static str {
        std::any::type_name::<Self>()
    }
    
    /// 시스템이 활성화되어 있는지 확인
    fn is_enabled(&self) -> bool {
        true
    }
    
    /// 시스템 활성화/비활성화
    fn set_enabled(&mut self, enabled: bool) {
        // 기본 구현은 아무것도 하지 않음
        // 필요한 시스템에서 오버라이드
        let _ = enabled;
    }
    
    /// Any 트레이트로 다운캐스팅을 위한 메서드
    fn as_any(&self) -> &dyn Any;
    
    /// Any 트레이트로 다운캐스팅을 위한 가변 메서드
    fn as_any_mut(&mut self) -> &mut dyn Any;
}

/// 시스템 실행 중 발생할 수 있는 에러
#[derive(Debug, Clone)]
pub enum SystemError {
    /// 초기화 실패
    InitializationFailed(String),
    /// 업데이트 실행 실패
    UpdateFailed(String),
    /// 종료 처리 실패
    ShutdownFailed(String),
    /// 일반적인 런타임 에러
    RuntimeError(String),
}

impl std::fmt::Display for SystemError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            SystemError::InitializationFailed(msg) => write!(f, "System initialization failed: {}", msg),
            SystemError::UpdateFailed(msg) => write!(f, "System update failed: {}", msg),
            SystemError::ShutdownFailed(msg) => write!(f, "System shutdown failed: {}", msg),
            SystemError::RuntimeError(msg) => write!(f, "System runtime error: {}", msg),
        }
    }
}

impl std::error::Error for SystemError {}
