using StorageService.Domain.SeedWork;

namespace StorageService.Domain.AggregatesModel.FolderAggregate;

/// <summary>
/// EN: Folder aggregate root - represents a logical folder for organizing files.
/// VI: Folder aggregate root - đại diện cho folder logic để tổ chức files.
/// </summary>
/// <remarks>
/// EN: CRITICAL: Folders are LOGICAL only (database). Storage uses flat UUID keys.
///     Folder rename/move is O(1) - only updates database, not storage.
/// VI: QUAN TRỌNG: Folders chỉ là LOGIC (database). Storage dùng flat UUID keys.
///     Đổi tên/di chuyển folder là O(1) - chỉ update database, không động storage.
/// </remarks>
public class Folder : Entity, IAggregateRoot
{
    /// <summary>EN: Owner user ID / VI: ID user sở hữu</summary>
    public string UserId { get; private set; } = default!;

    /// <summary>EN: Parent folder ID (null = root) / VI: ID folder cha (null = root)</summary>
    public Guid? ParentId { get; private set; }

    /// <summary>EN: Folder name / VI: Tên folder</summary>
    public string Name { get; private set; } = default!;

    /// <summary>EN: Materialized path (e.g., /parent/child/) / VI: Đường dẫn (vd: /parent/child/)</summary>
    public string Path { get; private set; } = default!;

    /// <summary>EN: Nesting level (0 = root level) / VI: Cấp độ lồng (0 = cấp root)</summary>
    public int Level { get; private set; }

    /// <summary>EN: Created timestamp / VI: Thời gian tạo</summary>
    public DateTime CreatedAt { get; private set; }

    /// <summary>EN: Updated timestamp / VI: Thời gian cập nhật</summary>
    public DateTime UpdatedAt { get; private set; }

    /// <summary>EN: Soft delete flag / VI: Cờ xóa mềm</summary>
    public bool IsDeleted { get; private set; }

    /// <summary>EN: Deleted timestamp / VI: Thời gian xóa</summary>
    public DateTime? DeletedAt { get; private set; }

    // EN: For EF Core / VI: Cho EF Core
    protected Folder() { }

    /// <summary>
    /// EN: Create a new root folder.
    /// VI: Tạo folder root mới.
    /// </summary>
    public static Folder CreateRoot(string userId, string name)
    {
        return new Folder
        {
            Id = Guid.NewGuid(),
            UserId = userId,
            ParentId = null,
            Name = name,
            Path = $"/{name}/",
            Level = 0,
            CreatedAt = DateTime.UtcNow,
            UpdatedAt = DateTime.UtcNow,
            IsDeleted = false
        };
    }

    /// <summary>
    /// EN: Create a child folder.
    /// VI: Tạo folder con.
    /// </summary>
    public Folder CreateChild(string name)
    {
        return new Folder
        {
            Id = Guid.NewGuid(),
            UserId = UserId,
            ParentId = Id,
            Name = name,
            Path = $"{Path}{name}/",
            Level = Level + 1,
            CreatedAt = DateTime.UtcNow,
            UpdatedAt = DateTime.UtcNow,
            IsDeleted = false
        };
    }

    /// <summary>
    /// EN: Rename folder. O(1) operation - only database update.
    /// VI: Đổi tên folder. O(1) - chỉ update database.
    /// </summary>
    public void Rename(string newName)
    {
        if (IsDeleted)
            throw new InvalidOperationException("Cannot rename deleted folder");

        var oldPath = Path;
        Name = newName;
        
        // EN: Update path - need to update children paths too (via repository)
        // VI: Update path - cần update paths của children (qua repository)
        Path = ParentId == null 
            ? $"/{newName}/" 
            : oldPath.Substring(0, oldPath.LastIndexOf('/', oldPath.Length - 2) + 1) + $"{newName}/";
        
        UpdatedAt = DateTime.UtcNow;
    }

    /// <summary>
    /// EN: Move folder to new parent.
    /// VI: Di chuyển folder sang parent mới.
    /// </summary>
    public void MoveTo(Folder? newParent)
    {
        if (IsDeleted)
            throw new InvalidOperationException("Cannot move deleted folder");

        if (newParent != null && newParent.UserId != UserId)
            throw new InvalidOperationException("Cannot move folder to different user");

        ParentId = newParent?.Id;
        Level = newParent == null ? 0 : newParent.Level + 1;
        Path = newParent == null ? $"/{Name}/" : $"{newParent.Path}{Name}/";
        UpdatedAt = DateTime.UtcNow;
    }

    /// <summary>
    /// EN: Soft delete folder.
    /// VI: Xóa mềm folder.
    /// </summary>
    public void Delete()
    {
        if (IsDeleted)
            return;

        IsDeleted = true;
        DeletedAt = DateTime.UtcNow;
    }
}
