use crate::data::models::project::{Project, CreateProjectRequest, UpdateProjectRequest};
use crate::data::repositories::project_repository::ProjectRepository;
use crate::infrastructure::file_system::FileSystemService;
use anyhow::{Result, anyhow};

/// 项目业务服务
/// 遵循 Tauri 开发规范的业务逻辑层设计
pub struct ProjectService;

impl ProjectService {
    /// 创建新项目
    /// 遵循安全第一原则，验证输入数据和文件系统权限
    pub fn create_project(
        repository: &ProjectRepository,
        request: CreateProjectRequest,
    ) -> Result<Project> {
        // 验证请求数据
        request.validate().map_err(|e| anyhow!(e))?;

        // 验证路径
        if !FileSystemService::is_valid_project_directory(&request.path)? {
            return Err(anyhow!("无效的项目路径或没有访问权限"));
        }

        // 获取绝对路径
        let absolute_path = FileSystemService::get_absolute_path(&request.path)?;

        // 检查路径是否已被使用
        if repository.path_exists(&absolute_path, None)? {
            return Err(anyhow!("该路径已被其他项目使用"));
        }

        // 创建项目实例
        let project = Project::new(
            request.name,
            absolute_path.clone(),
            request.description,
        );

        // 验证项目数据
        project.validate().map_err(|e| anyhow!(e))?;

        // 创建项目目录结构
        FileSystemService::create_project_structure(&absolute_path)?;

        // 保存到数据库
        repository.create(&project)?;

        Ok(project)
    }

    /// 获取所有活跃项目
    pub fn get_all_projects(repository: &ProjectRepository) -> Result<Vec<Project>> {
        let projects = repository.find_all_active()?;
        
        // 验证项目路径是否仍然有效
        let mut valid_projects = Vec::new();
        for project in projects {
            if FileSystemService::validate_path(&project.path).unwrap_or(false) {
                valid_projects.push(project);
            }
        }
        
        Ok(valid_projects)
    }

    /// 根据ID获取项目
    pub fn get_project_by_id(
        repository: &ProjectRepository,
        id: &str,
    ) -> Result<Option<Project>> {
        if id.trim().is_empty() {
            return Err(anyhow!("项目ID不能为空"));
        }

        let project = repository.find_by_id(id)?;
        
        // 验证项目路径是否仍然有效
        if let Some(ref proj) = project {
            if !FileSystemService::validate_path(&proj.path).unwrap_or(false) {
                return Err(anyhow!("项目路径不存在或无法访问"));
            }
        }
        
        Ok(project)
    }

    /// 更新项目
    pub fn update_project(
        repository: &ProjectRepository,
        id: &str,
        request: UpdateProjectRequest,
    ) -> Result<Project> {
        // 验证请求数据
        request.validate().map_err(|e| anyhow!(e))?;

        // 获取现有项目
        let mut project = repository.find_by_id(id)?
            .ok_or_else(|| anyhow!("项目不存在"))?;

        // 更新项目信息
        project.update(request.name, request.description);

        // 验证更新后的项目数据
        project.validate().map_err(|e| anyhow!(e))?;

        // 保存更新
        repository.update(&project)?;

        Ok(project)
    }

    /// 删除项目
    pub fn delete_project(repository: &ProjectRepository, id: &str) -> Result<()> {
        if id.trim().is_empty() {
            return Err(anyhow!("项目ID不能为空"));
        }

        // 检查项目是否存在
        let project = repository.find_by_id(id)?
            .ok_or_else(|| anyhow!("项目不存在"))?;

        // 执行软删除
        repository.delete(&project.id)?;

        Ok(())
    }

    /// 验证项目路径
    pub fn validate_project_path(path: &str) -> Result<bool> {
        if path.trim().is_empty() {
            return Ok(false);
        }

        FileSystemService::is_valid_project_directory(path)
    }

    /// 获取目录名称作为默认项目名
    pub fn get_default_project_name(path: &str) -> Result<String> {
        FileSystemService::get_directory_name(path)
    }
}
