// src/util/logger.rs
use chrono::Local;
use once_cell::sync::Lazy;
use tokio::sync::Mutex;
use std::fs::{self, OpenOptions};
use std::io::Write;
use std::path::PathBuf;

static LOGGER: Lazy<Mutex<Option<DebugLogger>>> = Lazy::new(|| Mutex::new(None));

pub struct DebugLogger {
    file: std::fs::File,
    log_path: PathBuf,
}

impl DebugLogger {
    fn new(log_dir: &std::path::Path) -> std::io::Result<Self> {

        fs::create_dir_all(log_dir)?;
        let filename = format!("backtest_{}.log", Local::now().format("%Y%m%d_%H%M%S"));
        let log_path = log_dir.join(&filename);
        let file = OpenOptions::new()
            .create(true)
            .append(true)
            .open(&log_path)?;
        Ok(Self { file, log_path })
    }

    async fn log(&mut self, msg: &str) {
        let line = format!("[{}] {}\n", Local::now().format("%H:%M:%S"), msg);
        let _ = self.file.write_all(line.as_bytes());
        let _ = self.file.flush();
        println!("{}", line.trim_end());
    }
}

pub async fn init_debug_logger(log_dir: &std::path::Path) -> Result<(), String> {
    let mut logger = LOGGER.lock().await;
    match DebugLogger::new(log_dir) {
        Ok(l) => {
            let log_path = l.log_path.clone();
            *logger = Some(l);
            println!("✓ Logger initialized at: {:?}", log_path);
            Ok(())
        }
        Err(e) => {
            let err_msg = format!("Failed to initialize logger: {}", e);
            eprintln!("{}", err_msg);
            Err(err_msg)
        }
    }
}

pub async fn log_message(msg: &str) {
    let mut logger = LOGGER.lock().await;
    if let Some(l) = logger.as_mut() {
        l.log(msg).await;
    } else {
        println!("[LOG] {}", msg);
    }
}

pub async fn log_detailed(level: &str, msg: &str) {
    let formatted = format!("[{}] {}", level, msg);
    log_message(&formatted).await;
}

pub async fn log_info(msg: &str) {
    log_detailed("INFO", msg).await;
}

pub async fn log_warn(msg: &str) {
    log_detailed("WARN", msg).await;
}

pub async fn log_error(msg: &str) {
    log_detailed("ERROR", msg).await;
}