use fern::{Dispatch, colors::{Color, ColoredLevelConfig}};
use log::{debug};
use std::fs;
use std::path::PathBuf;
use std::time::SystemTime;

fn resolve_log_dir() -> PathBuf {
    if let Some(override_dir) = std::env::var_os("JE_SKIN_LOG_DIR") {
        return PathBuf::from(override_dir);
    }

    if cfg!(target_os = "windows") {
        if let Some(local_app_data) = std::env::var_os("LOCALAPPDATA") {
            return PathBuf::from(local_app_data).join("JE-Skin").join("logs");
        }
    }

    std::env::temp_dir().join("JE-Skin").join("logs")
}

fn ensure_log_dir() -> PathBuf {
    let preferred = resolve_log_dir();
    if fs::create_dir_all(&preferred).is_ok() {
        return preferred;
    }

    let fallback = std::env::temp_dir().join("JE-Skin").join("logs");
    let _ = fs::create_dir_all(&fallback);
    fallback
}

pub fn setup_logger() {
    let colors_line = ColoredLevelConfig::new()
        .error(Color::Red)
        .warn(Color::Yellow)
        .info(Color::Green)
        .debug(Color::BrightBlue)
        .trace(Color::BrightBlack);

    let colors_level = colors_line.info(Color::Green);
    let level = if cfg!(debug_assertions) {
        log::LevelFilter::Debug
    } else {
        log::LevelFilter::Info
    };

    let console_config = fern::Dispatch::new()
        .format(move |out, message, record| {
            out.finish(
                format_args!(
                    "{colors_line}[{data} {level} {target} {colors_line}] {message}\x1B[0m",
                    colors_line = format_args!(
                        "\x1B[{}m",
                        colors_line.get_color(&record.level()).to_fg_str()
                    ),
                    data = humantime::format_rfc3339_seconds(SystemTime::now()),
                    target = record.target(),
                    level = colors_level.color(record.level()),
                    message = message,
                )
            );
        })
        .level(level)
        .chain(std::io::stdout());
        // .chain(fern::DateBased::new("program.log", "%Y-%m-%d"))
        // .apply()
        // .unwrap();

    let log_dir = ensure_log_dir();
    let log_file_base = log_dir.join("program.log");

    let file_config = fern::Dispatch::new()
        .format(move |out, message, record| {
            out.finish(
                format_args!(
                    "[{data} {level} {target}] {message}",
                    data = humantime::format_rfc3339_seconds(SystemTime::now()),
                    target = record.target(),
                    level = colors_level.color(record.level()),
                    message = message,
                )
            );
        })
        .level(level)
        .chain(fern::DateBased::new(log_file_base, "%Y-%m-%d"));

    Dispatch::new()
        .level(log::LevelFilter::Debug)
        .chain(console_config)
        .chain(file_config)
        .apply()
        .unwrap();

    debug!("logging initialized");
}
