use colored::*;
use indicatif::{ProgressBar, ProgressStyle};
use std::io::{self, Write};
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;

/// 日志级别枚举
#[derive(Debug, Clone)]
pub enum LogLevel {
    Success,
    Error,
    Warning,
    Info,
    Debug,
}

/// 美化的日志输出函数
pub fn log(level: LogLevel, message: &str) {
    let (icon, colored_message) = match level {
        LogLevel::Success => ("✅", message.green()),
        LogLevel::Error => ("❌", message.red()),
        LogLevel::Warning => ("⚠️", message.yellow()),
        LogLevel::Info => ("ℹ️", message.blue()),
        LogLevel::Debug => ("🔍", message.dimmed()),
    };
    
    println!("{} {}", icon, colored_message);
}

/// 成功日志
pub fn success(message: &str) {
    log(LogLevel::Success, message);
}

/// 错误日志
pub fn error(message: &str) {
    log(LogLevel::Error, message);
}

/// 警告日志
pub fn warning(message: &str) {
    log(LogLevel::Warning, message);
}

/// 信息日志
pub fn info(message: &str) {
    log(LogLevel::Info, message);
}

/// 调试日志
pub fn debug(message: &str) {
    log(LogLevel::Debug, message);
}

/// 动态加载动画结构体
pub struct LoadingSpinner {
    pb: ProgressBar,
    message: String,
}

impl LoadingSpinner {
    /// 创建新的加载动画
    pub fn new(message: &str) -> Self {
        let pb = ProgressBar::new_spinner();
        pb.set_style(
            ProgressStyle::default_spinner()
                .tick_strings(&["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"])
                .template("{spinner:.blue} {msg}")
                .unwrap(),
        );
        pb.set_message(message.to_string());
        pb.enable_steady_tick(Duration::from_millis(100));
        
        Self {
            pb,
            message: message.to_string(),
        }
    }

    /// 更新加载消息
    pub fn set_message(&mut self, message: &str) {
        self.message = message.to_string();
        self.pb.set_message(message.to_string());
    }

    /// 完成加载并显示成功消息
    pub fn finish_with_success(self, message: &str) {
        self.pb.finish_and_clear();
        success(message);
    }

    /// 完成加载并显示错误消息
    pub fn finish_with_error(self, message: &str) {
        self.pb.finish_and_clear();
        error(message);
    }

    /// 完成加载并显示信息消息
    pub fn finish_with_info(self, message: &str) {
        self.pb.finish_and_clear();
        info(message);
    }

    /// 手动停止加载动画
    pub fn stop(self) {
        self.pb.finish_and_clear();
    }
}

/// 简单的点状加载动画（使用 Arc 和 Mutex 来处理并发）

pub struct DotSpinner {
    message: String,
    running: Arc<Mutex<bool>>,
}

impl DotSpinner {
    /// 创建新的点状加载动画
    pub fn new(message: &str) -> Self {
        Self {
            message: message.to_string(),
            running: Arc::new(Mutex::new(false)),
        }
    }

    /// 开始动画
    pub fn start(&mut self) {
        *self.running.lock().unwrap() = true;
        let message = self.message.clone();
        let running = Arc::clone(&self.running);
        
        thread::spawn(move || {
            let dots = [".", "..", "...", ""];
            let mut i = 0;
            
            while *running.lock().unwrap() {
                print!("\r🔄 {}{}", message, dots[i % dots.len()]);
                io::stdout().flush().unwrap();
                thread::sleep(Duration::from_millis(500));
                i += 1;
            }
            print!("\r");
            io::stdout().flush().unwrap();
        });
    }

    /// 停止动画
    pub fn stop(&mut self) {
        *self.running.lock().unwrap() = false;
        print!("\r");
        io::stdout().flush().unwrap();
    }
}

/// 带进度的操作
pub fn with_progress<F, R>(message: &str, operation: F) -> R
where
    F: FnOnce() -> R,
{
    let spinner = LoadingSpinner::new(message);
    let result = operation();
    spinner.stop();
    result
}

/// 带进度和结果反馈的操作
pub fn with_progress_result<F, R, E>(message: &str, operation: F) -> Result<R, E>
where
    F: FnOnce() -> Result<R, E>,
{
    let spinner = LoadingSpinner::new(message);
    match operation() {
        Ok(result) => {
            spinner.finish_with_success("完成");
            Ok(result)
        }
        Err(err) => {
            spinner.finish_with_error("失败");
            Err(err)
        }
    }
}

/// 打印分隔线
pub fn separator() {
    println!("{}", "─".repeat(50).dimmed());
}

/// 打印标题
pub fn title(text: &str) {
    separator();
    println!("{}", text.bold().cyan());
    separator();
}

/// 打印子标题
pub fn subtitle(text: &str) {
    println!("{}", text.bold().white());
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::thread;
    use std::time::Duration;

    #[test]
    fn test_log_levels() {
        // 测试不同级别的日志输出
        success("测试成功日志");
        error("测试错误日志");
        warning("测试警告日志");
        info("测试信息日志");
        debug("测试调试日志");
    }

    #[test]
    fn test_log_function() {
        // 测试通用日志函数
        log(LogLevel::Success, "通用成功日志");
        log(LogLevel::Error, "通用错误日志");
        log(LogLevel::Warning, "通用警告日志");
        log(LogLevel::Info, "通用信息日志");
        log(LogLevel::Debug, "通用调试日志");
    }

    #[test]
    fn test_loading_spinner() {
        let spinner = LoadingSpinner::new("测试加载中...");
        thread::sleep(Duration::from_millis(100));
        spinner.finish_with_success("加载完成");

        let spinner2 = LoadingSpinner::new("测试连接中...");
        thread::sleep(Duration::from_millis(50));
        spinner2.finish_with_error("连接失败");

        let spinner3 = LoadingSpinner::new("测试处理中...");
        thread::sleep(Duration::from_millis(50));
        spinner3.finish_with_info("处理信息");
    }

    #[test]
    fn test_with_progress() {
        let result = with_progress("测试进度操作", || {
            thread::sleep(Duration::from_millis(50));
            42
        });
        assert_eq!(result, 42);
    }

    #[test]
    fn test_with_progress_result_success() {
        let result = with_progress_result("测试成功操作", || {
            thread::sleep(Duration::from_millis(50));
            Ok::<i32, &str>(100)
        });
        assert!(result.is_ok());
        assert_eq!(result.unwrap(), 100);
    }

    #[test]
    fn test_with_progress_result_error() {
        let result = with_progress_result("测试失败操作", || {
            thread::sleep(Duration::from_millis(50));
            Err::<i32, &str>("测试错误")
        });
        assert!(result.is_err());
        assert_eq!(result.unwrap_err(), "测试错误");
    }

    #[test]
    fn test_formatting_functions() {
        // 测试格式化函数
        title("测试标题");
        subtitle("测试子标题");
        separator();
    }

    #[test]
    fn test_dot_spinner() {
        let mut spinner = DotSpinner::new("测试点状动画");
        spinner.start();
        thread::sleep(Duration::from_millis(100));
        spinner.stop();
    }
}