//! ProjectStore trait definition.

use crate::error::Result;
use crate::params::*;
use dirigent_protocol::project::{Project, ProjectBinding, ProjectRepository, Worktree};
use std::path::PathBuf;
use uuid::Uuid;

/// Trait for project storage backends.
///
/// Async-first, trait-object safe. Implementations must be Send + Sync.
/// Phase 1 implements project CRUD. Later phases add repository management,
/// bindings, and resolution.
#[async_trait::async_trait]
pub trait ProjectStore: Send + Sync {
    // --- Project CRUD (Phase 1) ---

    /// Create a new project.
    async fn create_project(&self, params: CreateProjectParams) -> Result<Project>;

    /// Get a project by ID.
    async fn get_project(&self, id: &Uuid) -> Result<Project>;

    /// List projects matching a filter.
    async fn list_projects(&self, filter: ProjectFilter) -> Result<Vec<Project>>;

    /// Update a project's fields.
    async fn update_project(&self, id: &Uuid, update: ProjectUpdate) -> Result<Project>;

    /// Delete a project and all associated data.
    async fn delete_project(&self, id: &Uuid) -> Result<()>;

    // --- Repository management (Phase 2) ---

    /// Add a repository to a project.
    async fn add_repository(&self, params: AddRepositoryParams) -> Result<ProjectRepository>;

    /// Remove a repository.
    async fn remove_repository(&self, id: &Uuid) -> Result<()>;

    /// Set a repository as the primary for its project.
    async fn set_primary_repository(&self, project_id: &Uuid, repo_id: &Uuid) -> Result<()>;

    /// List repositories for a project.
    async fn list_repositories(&self, project_id: &Uuid) -> Result<Vec<ProjectRepository>>;

    // --- Worktrees (Phase 4) ---

    /// Add a worktree record to a repository.
    async fn add_worktree(&self, params: AddWorktreeParams) -> Result<Worktree>;

    /// Remove a worktree record.
    async fn remove_worktree(&self, worktree_id: &Uuid) -> Result<()>;

    /// List worktree records for a repository.
    async fn list_worktrees(&self, repository_id: &Uuid) -> Result<Vec<Worktree>>;

    /// Update a worktree record.
    async fn update_worktree(&self, worktree_id: &Uuid, update: WorktreeUpdate)
        -> Result<Worktree>;

    // --- Bindings (Phase 5) ---

    /// Bind a project to a connector/session.
    async fn bind(&self, params: BindParams) -> Result<ProjectBinding>;

    /// Remove a binding.
    async fn unbind(&self, binding_id: &Uuid) -> Result<()>;

    /// List bindings for a project.
    async fn list_bindings(&self, project_id: &Uuid) -> Result<Vec<ProjectBinding>>;

    // --- Resolution (Phase 2) ---

    /// Resolve the working directory for a project.
    async fn resolve_working_dir(
        &self,
        project_id: &Uuid,
        repo_id: Option<&Uuid>,
    ) -> Result<PathBuf>;
}
