/// logger mod
/// 
/// # Examples
/// 
/// ## Basic usage
/// ```ignore
/// use doe::logger::*;
/// doe::logger::init();
/// debug!("hello world");
/// info!("hello world");
/// warn!("hello world");
/// ```
/// 
/// ## Using builder pattern (fluent interface)
/// ```ignore
/// use doe::logger::*;
/// 
/// // Custom configuration with fluent interface
/// LoggerBuilder::init()
///     .with("debug")
///     .log_dir("logs")
///     .filename_prefix("myapp")
///     .filename_suffix("log")
///     .file_appender_rotation(doe::logger::tracing_appender::rolling::Rotation::DAILY)
///     .with_console(true)
///     .with_file(true)
///     .retention_days(30)
///     .build();
/// 
/// info!("Logger initialized with custom configuration");
/// ```
/// 
/// ## Console only
/// ```ignore
/// use doe::logger::*;
/// 
/// LoggerBuilder::init()
///     .with("info")
///     .with_console(true)
///     .with_file(false)
///     .build();
/// 
/// info!("Only console logging enabled");
/// ```
/// 
/// ## File only
/// ```ignore
/// use doe::logger::*;
/// 
/// LoggerBuilder::init()
///     .with("debug")
///     .log_dir("logs")
///     .with_console(false)
///     .with_file(true)
///     .build();
/// 
/// info!("Only file logging enabled");
/// ```
#[allow(warnings)]
#[cfg(feature = "logger")]
pub mod logger {
    use chrono::{Local, NaiveDate, TimeDelta, TimeZone};
    use std::fs;
    use std::path::{Path, PathBuf};
    use time::{format_description::parse, UtcOffset};
    use tracing_appender::{non_blocking, rolling};
    use tracing_error::ErrorLayer;
    use tracing_subscriber::{
        filter::EnvFilter,
        fmt,
        fmt::time::OffsetTime,
        layer::SubscriberExt,
        registry::Registry,
        util::SubscriberInitExt,
    };

    // 重新导出tracing的宏，保持原有使用方式
    pub use tracing::*;
    pub use tracing_appender::*;
    pub use tracing_appender;
    pub use tracing_subscriber::*;
    pub use tracing_subscriber;
    pub use tracing_error::*;
    pub use tracing_error;

    /// 默认日志保留天数
    const DEFAULT_LOG_RETENTION_DAYS: u64 = 14;

    /// 初始化debug级别的日志系统
    /// 自动清理超过14天的旧日志文件
    pub fn init_debug() {
        // 清理旧日志文件
        if let Err(e) = clean_old_logs("log", "app", "log", rolling::Rotation::DAILY, DEFAULT_LOG_RETENTION_DAYS) {
            eprintln!("Warning: Failed to clean old logs: {}", e);
        }

        // 初始化日志配置
        let env_filter = EnvFilter::try_from_default_env()
            .unwrap_or_else(|_| EnvFilter::new("debug"));
        
        let timer = create_local_timer();
        
        // 控制台日志层
        let formatting_layer = fmt::layer()
            .with_timer(timer.clone())
            .pretty()
            .with_writer(std::io::stdout);

        // 文件日志层
        let file_appender = rolling::RollingFileAppender::builder()
            .rotation(rolling::Rotation::DAILY)
            .filename_prefix("app")
            .filename_suffix("log")
            .build("log")
            .expect("Failed to create rolling file appender");
            
        let file_layer = fmt::layer()
            .with_ansi(false)
            .with_timer(timer)
            .with_writer(file_appender);

        // 组合并初始化日志系统
        if let Err(e) = Registry::default()
            .with(env_filter)
            .with(formatting_layer)
            .with(file_layer)
            .try_init()
        {
            eprintln!("Failed to initialize debug logger: {}", e);
        }
    }

    /// 初始化info级别的日志系统
    /// 自动清理超过14天的旧日志文件
    pub fn init_info() {
        // 清理旧日志文件
        if let Err(e) = clean_old_logs("log", "app", "log", rolling::Rotation::DAILY, DEFAULT_LOG_RETENTION_DAYS) {
            eprintln!("Warning: Failed to clean old logs: {}", e);
        }

        // 初始化日志配置
        let env_filter = EnvFilter::try_from_default_env()
            .unwrap_or_else(|_| EnvFilter::new("info"));
        
        let timer = create_local_timer();
        
        // 文件日志层
        let file_appender = rolling::RollingFileAppender::builder()
            .rotation(rolling::Rotation::DAILY)
            .filename_prefix("app")
            .filename_suffix("log")
            .build("log")
            .expect("Failed to create rolling file appender");
            
        let file_layer = fmt::layer()
            .with_ansi(false)
            .with_timer(timer.clone())
            .with_writer(file_appender);

        // 控制台日志层
        let formatting_layer = fmt::layer()
            .with_timer(timer)
            .pretty()
            .with_writer(std::io::stdout);

        // 组合并初始化日志系统
        if let Err(e) = Registry::default()
            .with(env_filter)
            .with(formatting_layer)
            .with(file_layer)
            .try_init()
        {
            eprintln!("Failed to initialize info logger: {}", e);
        }
    }

    /// Logger 构建器，提供 fluent interface
    pub struct LoggerBuilder {
        log_level: String,
        log_dir: String,
        filename_prefix: String,
        filename_suffix: String,
        rotation: Option<rolling::Rotation>,
        console_enabled: bool,
        file_enabled: bool,
        retention_days: u64,
    }

    impl Default for LoggerBuilder {
        fn default() -> Self {
            Self {
                log_level: "info".to_string(),
                log_dir: "log".to_string(),
                filename_prefix: "app".to_string(),
                filename_suffix: "log".to_string(),
                rotation: Some(rolling::Rotation::DAILY),
                console_enabled: true,
                file_enabled: true,
                retention_days: DEFAULT_LOG_RETENTION_DAYS,
            }
        }
    }

    impl LoggerBuilder {
        /// 创建一个新的 Logger 构建器
        pub fn init() -> Self {
            Self::default()
        }

        /// 设置日志级别
        pub fn with(mut self, level: &str) -> Self {
            self.log_level = level.to_string();
            self
        }

        /// 设置日志目录
        pub fn log_dir(mut self, dir: &str) -> Self {
            self.log_dir = dir.to_string();
            self
        }

        /// 设置文件名前缀
        pub fn filename_prefix(mut self, prefix: &str) -> Self {
            self.filename_prefix = prefix.to_string();
            self
        }

        /// 设置文件名后缀
        pub fn filename_suffix(mut self, suffix: &str) -> Self {
            self.filename_suffix = suffix.to_string();
            self
        }

        /// 设置日志轮转策略
        pub fn file_appender_rotation(mut self, rotation: rolling::Rotation) -> Self {
            self.rotation = Some(rotation);
            self
        }

        /// 启用或禁用控制台输出
        pub fn with_console(mut self, enabled: bool) -> Self {
            self.console_enabled = enabled;
            self
        }

        /// 启用或禁用文件输出
        pub fn with_file(mut self, enabled: bool) -> Self {
            self.file_enabled = enabled;
            self
        }

        /// 设置日志保留天数
        pub fn retention_days(mut self, days: u64) -> Self {
            self.retention_days = days;
            self
        }

        /// 构建并初始化日志系统
        pub fn build(self) {
            // 清理旧日志文件
            if self.file_enabled {
                let rotation = self.rotation.as_ref().unwrap_or(&rolling::Rotation::NEVER);
                if let Err(e) = clean_old_logs(
                    &self.log_dir,
                    &self.filename_prefix,
                    &self.filename_suffix,
                    rotation.clone(),
                    self.retention_days
                ) {
                    eprintln!("Warning: Failed to clean old logs: {}", e);
                }
            }

            // 创建环境过滤器
            let env_filter = EnvFilter::try_from_default_env()
                .unwrap_or_else(|_| EnvFilter::new(&self.log_level));

            let timer = create_local_timer();

            // 根据配置构建不同的 subscriber
            match (self.console_enabled, self.file_enabled) {
                (true, true) => {
                    // 控制台和文件都启用
                    let file_appender = if let Some(rotation) = self.rotation {
                        rolling::RollingFileAppender::builder()
                            .rotation(rotation)
                            .filename_prefix(&self.filename_prefix)
                            .filename_suffix(&self.filename_suffix)
                            .build(&self.log_dir)
                            .expect("Failed to create rolling file appender")
                    } else {
                        let file_path = format!("{}/{}.{}", self.log_dir, self.filename_prefix, self.filename_suffix);
                        rolling::never(&self.log_dir, &file_path)
                    };

                    let console_layer = fmt::layer()
                        .with_timer(timer.clone())
                        .pretty()
                        .with_writer(std::io::stdout);

                    let file_layer = fmt::layer()
                        .with_ansi(false)
                        .with_timer(timer)
                        .with_writer(file_appender);

                    if let Err(e) = Registry::default()
                        .with(env_filter)
                        .with(console_layer)
                        .with(file_layer)
                        .try_init()
                    {
                        eprintln!("Failed to initialize logger: {}", e);
                    }
                }
                (true, false) => {
                    // 只启用控制台
                    let console_layer = fmt::layer()
                        .with_timer(timer)
                        .pretty()
                        .with_writer(std::io::stdout);

                    if let Err(e) = Registry::default()
                        .with(env_filter)
                        .with(console_layer)
                        .try_init()
                    {
                        eprintln!("Failed to initialize logger: {}", e);
                    }
                }
                (false, true) => {
                    // 只启用文件
                    let file_appender = if let Some(rotation) = self.rotation {
                        rolling::RollingFileAppender::builder()
                            .rotation(rotation)
                            .filename_prefix(&self.filename_prefix)
                            .filename_suffix(&self.filename_suffix)
                            .build(&self.log_dir)
                            .expect("Failed to create rolling file appender")
                    } else {
                        let file_path = format!("{}/{}.{}", self.log_dir, self.filename_prefix, self.filename_suffix);
                        rolling::never(&self.log_dir, &file_path)
                    };

                    let file_layer = fmt::layer()
                        .with_ansi(false)
                        .with_timer(timer)
                        .with_writer(file_appender);

                    if let Err(e) = Registry::default()
                        .with(env_filter)
                        .with(file_layer)
                        .try_init()
                    {
                        eprintln!("Failed to initialize logger: {}", e);
                    }
                }
                (false, false) => {
                    eprintln!("Warning: Both console and file logging are disabled");
                }
            }
        }
    }

    /// 创建本地时间格式化器（完全兼容版）
    fn create_local_timer() -> OffsetTime<time::format_description::OwnedFormatItem> {
        let offset = UtcOffset::current_local_offset()
            .expect("Failed to get local time offset");
        
        // 使用 parse 函数替代宏，兼容所有 time 库版本
        let time_format = parse("[year]-[month]-[day] [hour]:[minute]:[second]")
            .expect("Invalid time format string");
        
        // 将 Vec<FormatItem> 转换为 OwnedFormatItem 以满足静态生命周期要求
        let time_format = time::format_description::OwnedFormatItem::from(time_format);
        
        OffsetTime::new(offset, time_format)
    }

    /// 清理指定目录下超过指定天数的日志文件
    /// 
    /// # 参数
    /// - `log_dir`: 日志文件所在目录
    /// - `filename_prefix`: 日志文件名前缀
    /// - `filename_suffix`: 日志文件名后缀
    /// - `file_appender_rotation`: 日志轮转策略
    /// - `retention_days`: 保留的最大天数，超过该天数的文件将被删除
    /// 
    /// # 返回值
    /// - Result<(), std::io::Error>: 成功返回Ok(())，失败返回错误信息
    pub fn clean_old_logs(
        log_dir: &str,
        filename_prefix: &str,
        filename_suffix: &str,
        file_appender_rotation: rolling::Rotation,
        retention_days: u64,
    ) -> Result<(), std::io::Error> {
        // 检查日志目录是否存在
        let log_dir_path = Path::new(log_dir);
        if !log_dir_path.exists() {
            return Ok(());
        }

        // 计算过期时间点
        let cutoff_datetime = Local::now() - TimeDelta::days(retention_days as i64);
        
        // 遍历日志目录下的所有文件
        for entry in fs::read_dir(log_dir_path)? {
            let entry = entry?;
            let path = entry.path();
            
            // 只处理文件（跳过目录）
            if path.is_file() {
                // 获取文件名
                if let Some(file_name) = path.file_name().and_then(|n| n.to_str()) {
                    // 检查是否匹配前缀和后缀
                    let has_correct_prefix = file_name.starts_with(&format!("{}.", filename_prefix));
                    let has_correct_suffix = file_name.ends_with(&format!(".{}", filename_suffix));
                    
                    if !has_correct_prefix || !has_correct_suffix {
                        continue;
                    }
                    
                    // 根据轮转策略判断文件是否过期
                    let is_expired = match file_appender_rotation {
                        rolling::Rotation::NEVER => {
                            // 不轮转，直接比较文件修改时间
                            if let Ok(metadata) = fs::metadata(&path) {
                                if let Ok(modified) = metadata.modified() {
                                    let modified_datetime = chrono::DateTime::<chrono::Local>::from(modified);
                                    modified_datetime < cutoff_datetime
                                } else {
                                    false
                                }
                            } else {
                                false
                            }
                        }
                        rolling::Rotation::HOURLY => {
                            // 每小时轮转，文件名格式: prefix.YYYY-MM-DD-HH.suffix
                            match extract_datetime_from_filename(file_name, &format!("{}.", filename_prefix), &format!(".{}", filename_suffix), "%Y-%m-%d-%H") {
                                Some(file_datetime) => file_datetime < cutoff_datetime,
                                None => false,
                            }
                        }
                        rolling::Rotation::DAILY => {
                            // 每天轮转，文件名格式: prefix.YYYY-MM-DD.suffix
                            match extract_datetime_from_filename(file_name, &format!("{}.", filename_prefix), &format!(".{}", filename_suffix), "%Y-%m-%d") {
                                Some(file_datetime) => file_datetime < cutoff_datetime,
                                None => false,
                            }
                        }
                        rolling::Rotation::MINUTELY => {
                            // 每分钟轮转，文件名格式: prefix.YYYY-MM-DD-HH-MM.suffix
                            match extract_datetime_from_filename(file_name, &format!("{}.", filename_prefix), &format!(".{}", filename_suffix), "%Y-%m-%d-%H-%M") {
                                Some(file_datetime) => file_datetime < cutoff_datetime,
                                None => false,
                            }
                        }
                        rolling::Rotation::WEEKLY => {
                            // 每周轮转，使用文件修改时间
                            if let Ok(metadata) = fs::metadata(&path) {
                                if let Ok(modified) = metadata.modified() {
                                    let modified_datetime = chrono::DateTime::<chrono::Local>::from(modified);
                                    modified_datetime < cutoff_datetime
                                } else {
                                    false
                                }
                            } else {
                                false
                            }
                        }
                    };
                    
                    if is_expired {
                        println!("Deleting old log file: {}", path.display());
                        fs::remove_file(&path)?;
                    }
                }
            }
        }
        
        Ok(())
    }
    
    /// 从文件名中提取日期时间
    fn extract_datetime_from_filename(
        file_name: &str,
        prefix: &str,
        suffix: &str,
        format_str: &str,
    ) -> Option<chrono::DateTime<Local>> {
        // 移除前缀和后缀
        let datetime_str = file_name.strip_prefix(prefix)?.strip_suffix(suffix)?;
        
        // 尝试解析日期时间
        match NaiveDate::parse_from_str(datetime_str, format_str) {
            Ok(date) => Some(date.and_hms_opt(0, 0, 0)?.and_local_timezone(Local).unwrap()),
            Err(_) => None,
        }
    }

    /// 简化的初始化函数（兼容原有接口）
    pub fn init() {
        init_info();
    }
}


#[cfg(feature = "logger")]
pub use logger::*;
