using ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate;
using ColaFlow.Modules.ProjectManagement.Domain.ValueObjects;

namespace ColaFlow.Modules.ProjectManagement.Domain.Repositories;

/// <summary>
/// Repository interface for Project aggregate
/// </summary>
public interface IProjectRepository
{
    // ========== Basic CRUD Operations ==========

    /// <summary>
    /// Gets a project by its ID
    /// </summary>
    Task<Project?> GetByIdAsync(ProjectId id, CancellationToken cancellationToken = default);

    /// <summary>
    /// Gets a project by its unique key
    /// </summary>
    Task<Project?> GetByKeyAsync(string key, CancellationToken cancellationToken = default);

    /// <summary>
    /// Gets all projects with pagination
    /// </summary>
    Task<List<Project>> GetAllAsync(CancellationToken cancellationToken = default);

    /// <summary>
    /// Adds a new project
    /// </summary>
    Task AddAsync(Project project, CancellationToken cancellationToken = default);

    /// <summary>
    /// Updates an existing project
    /// </summary>
    void Update(Project project);

    /// <summary>
    /// Deletes a project
    /// </summary>
    void Delete(Project project);

    // ========== Aggregate Root Loading (for Command Handlers - with tracking) ==========

    /// <summary>
    /// Gets project containing specific epic (with tracking, for modification)
    /// </summary>
    Task<Project?> GetProjectWithEpicAsync(EpicId epicId, CancellationToken cancellationToken = default);

    /// <summary>
    /// Gets project containing specific story (with tracking, for modification)
    /// </summary>
    Task<Project?> GetProjectWithStoryAsync(StoryId storyId, CancellationToken cancellationToken = default);

    /// <summary>
    /// Gets project containing specific task (with tracking, for modification)
    /// </summary>
    Task<Project?> GetProjectWithTaskAsync(TaskId taskId, CancellationToken cancellationToken = default);

    /// <summary>
    /// Gets project with all epics (without stories and tasks)
    /// </summary>
    Task<Project?> GetProjectWithEpicsAsync(ProjectId projectId, CancellationToken cancellationToken = default);

    // ========== Read-Only Queries (for Query Handlers - AsNoTracking) ==========

    /// <summary>
    /// Gets epic by ID (read-only, AsNoTracking)
    /// </summary>
    Task<Epic?> GetEpicByIdReadOnlyAsync(EpicId epicId, CancellationToken cancellationToken = default);

    /// <summary>
    /// Gets all epics for a project (read-only, AsNoTracking)
    /// </summary>
    Task<List<Epic>> GetEpicsByProjectIdAsync(ProjectId projectId, CancellationToken cancellationToken = default);

    /// <summary>
    /// Gets story by ID (read-only, AsNoTracking)
    /// </summary>
    Task<Story?> GetStoryByIdReadOnlyAsync(StoryId storyId, CancellationToken cancellationToken = default);

    /// <summary>
    /// Gets all stories for an epic (read-only, AsNoTracking)
    /// </summary>
    Task<List<Story>> GetStoriesByEpicIdAsync(EpicId epicId, CancellationToken cancellationToken = default);

    /// <summary>
    /// Gets task by ID (read-only, AsNoTracking)
    /// </summary>
    Task<WorkTask?> GetTaskByIdReadOnlyAsync(TaskId taskId, CancellationToken cancellationToken = default);

    /// <summary>
    /// Gets all tasks for a story (read-only, AsNoTracking)
    /// </summary>
    Task<List<WorkTask>> GetTasksByStoryIdAsync(StoryId storyId, CancellationToken cancellationToken = default);

    /// <summary>
    /// Gets project by ID with all epics/stories/tasks (read-only, AsNoTracking)
    /// </summary>
    Task<Project?> GetProjectByIdReadOnlyAsync(ProjectId projectId, CancellationToken cancellationToken = default);

    /// <summary>
    /// Gets all projects (read-only, AsNoTracking)
    /// </summary>
    Task<List<Project>> GetAllProjectsReadOnlyAsync(CancellationToken cancellationToken = default);

    /// <summary>
    /// Gets project with all epics/stories/tasks hierarchy (read-only, AsNoTracking)
    /// </summary>
    Task<Project?> GetProjectWithFullHierarchyReadOnlyAsync(ProjectId projectId, CancellationToken cancellationToken = default);
}
