use std::path::Path;
use anyhow::{Result, anyhow};

/// 文件系统操作工具
/// 遵循 Tauri 开发规范的文件系统安全操作
pub struct FileSystemService;

impl FileSystemService {
    /// 验证路径是否存在且可访问
    pub fn validate_path(path: &str) -> Result<bool> {
        let path = Path::new(path);
        Ok(path.exists() && path.is_dir())
    }

    /// 获取路径的绝对路径
    pub fn get_absolute_path(path: &str) -> Result<String> {
        let path = Path::new(path);
        let absolute_path = path.canonicalize()?;
        Ok(absolute_path.to_string_lossy().to_string())
    }

    /// 检查路径是否为有效的项目目录
    pub fn is_valid_project_directory(path: &str) -> Result<bool> {
        let path = Path::new(path);
        
        // 检查路径是否存在且为目录
        if !path.exists() || !path.is_dir() {
            return Ok(false);
        }

        // 检查是否有读写权限
        let metadata = path.metadata()?;
        if metadata.permissions().readonly() {
            return Ok(false);
        }

        Ok(true)
    }

    /// 获取目录名称
    pub fn get_directory_name(path: &str) -> Result<String> {
        let path = Path::new(path);
        match path.file_name() {
            Some(name) => Ok(name.to_string_lossy().to_string()),
            None => Err(anyhow::anyhow!("Invalid directory path")),
        }
    }

    /// 创建项目目录结构
    pub fn create_project_structure(project_path: &str) -> Result<()> {
        let base_path = Path::new(project_path);
        
        // 创建基本目录结构
        let directories = [
            "assets",
            "output",
            "temp",
            "config",
        ];

        for dir in &directories {
            let dir_path = base_path.join(dir);
            if !dir_path.exists() {
                std::fs::create_dir_all(&dir_path)?;
            }
        }

        // 创建项目配置文件
        let config_file = base_path.join("mixvideo.project.json");
        if !config_file.exists() {
            let default_config = serde_json::json!({
                "version": "0.1.0",
                "created_at": chrono::Utc::now().to_rfc3339(),
                "settings": {
                    "auto_save": true,
                    "backup_enabled": true
                }
            });
            std::fs::write(config_file, serde_json::to_string_pretty(&default_config)?)?;
        }

        Ok(())
    }

    /// 检查是否为现有的 MixVideo 项目
    pub fn is_mixvideo_project(path: &str) -> bool {
        let project_file = Path::new(path).join("mixvideo.project.json");
        project_file.exists()
    }

    /// 创建目录（如果不存在）
    pub fn create_directory_if_not_exists(path: &str) -> Result<()> {
        let dir_path = Path::new(path);
        if !dir_path.exists() {
            std::fs::create_dir_all(dir_path)?;
        }
        Ok(())
    }

    /// 移动文件
    pub fn move_file(source: &str, destination: &str) -> Result<()> {
        let source_path = Path::new(source);
        let dest_path = Path::new(destination);

        // 确保源文件存在
        if !source_path.exists() {
            return Err(anyhow!("源文件不存在: {}", source));
        }

        // 确保目标目录存在
        if let Some(parent) = dest_path.parent() {
            std::fs::create_dir_all(parent)?;
        }

        // 移动文件
        std::fs::rename(source_path, dest_path)?;
        Ok(())
    }

    /// 复制文件
    pub fn copy_file(source: &str, destination: &str) -> Result<()> {
        let source_path = Path::new(source);
        let dest_path = Path::new(destination);

        // 确保源文件存在
        if !source_path.exists() {
            return Err(anyhow!("源文件不存在: {}", source));
        }

        // 确保目标目录存在
        if let Some(parent) = dest_path.parent() {
            std::fs::create_dir_all(parent)?;
        }

        // 复制文件
        std::fs::copy(source_path, dest_path)?;
        Ok(())
    }

    /// 获取文件大小
    pub fn get_file_size(path: &str) -> Result<u64> {
        let metadata = std::fs::metadata(path)?;
        Ok(metadata.len())
    }

    /// 检查文件是否存在
    pub fn file_exists(path: &str) -> bool {
        Path::new(path).exists()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use tempfile::TempDir;

    #[test]
    fn test_validate_path() {
        // 测试存在的目录
        let temp_dir = TempDir::new().unwrap();
        let path = temp_dir.path().to_str().unwrap();
        assert!(FileSystemService::validate_path(path).unwrap());

        // 测试不存在的路径
        assert!(!FileSystemService::validate_path("/non/existent/path").unwrap());
    }

    #[test]
    fn test_get_absolute_path() {
        let temp_dir = TempDir::new().unwrap();
        let path = temp_dir.path().to_str().unwrap();
        let absolute_path = FileSystemService::get_absolute_path(path).unwrap();
        assert!(absolute_path.len() > path.len() || absolute_path == path);
    }

    #[test]
    fn test_is_valid_project_directory() {
        let temp_dir = TempDir::new().unwrap();
        let path = temp_dir.path().to_str().unwrap();

        // 有效目录应该返回 true
        assert!(FileSystemService::is_valid_project_directory(path).unwrap());

        // 不存在的路径应该返回 false
        assert!(!FileSystemService::is_valid_project_directory("/non/existent/path").unwrap());
    }

    #[test]
    fn test_get_directory_name() {
        assert_eq!(
            FileSystemService::get_directory_name("/path/to/project").unwrap(),
            "project"
        );

        assert_eq!(
            FileSystemService::get_directory_name("C:\\Users\\test\\project").unwrap(),
            "project"
        );
    }

    #[test]
    fn test_create_project_structure() {
        let temp_dir = TempDir::new().unwrap();
        let project_path = temp_dir.path().to_str().unwrap();

        FileSystemService::create_project_structure(project_path).unwrap();

        // 检查目录是否创建
        assert!(temp_dir.path().join("assets").exists());
        assert!(temp_dir.path().join("output").exists());
        assert!(temp_dir.path().join("temp").exists());
        assert!(temp_dir.path().join("config").exists());

        // 检查配置文件是否创建
        assert!(temp_dir.path().join("mixvideo.project.json").exists());
    }

    #[test]
    fn test_is_mixvideo_project() {
        let temp_dir = TempDir::new().unwrap();
        let project_path = temp_dir.path().to_str().unwrap();

        // 初始状态不是 MixVideo 项目
        assert!(!FileSystemService::is_mixvideo_project(project_path));

        // 创建项目结构后应该是 MixVideo 项目
        FileSystemService::create_project_structure(project_path).unwrap();
        assert!(FileSystemService::is_mixvideo_project(project_path));
    }
}
