// EN: Shop member entity - staff assignment to shop.
// VI: Entity shop member - gán nhân viên vào shop.

using MerchantService.Domain.Exceptions;
using MerchantService.Domain.SeedWork;

namespace MerchantService.Domain.AggregatesModel.MerchantStaffAggregate;

/// <summary>
/// EN: Represents a staff member's assignment to a shop.
/// VI: Đại diện cho việc gán nhân viên vào shop.
/// </summary>
public class ShopMember : Entity
{
    private Guid _staffId;
    private Guid _shopId;
    private Guid? _branchId;
    private ShopRole _role = null!;
    private StaffPermissions? _customPermissions;
    private bool _isPrimary;
    private DateTime _assignedAt;

    /// <summary>
    /// EN: Staff ID.
    /// VI: ID nhân viên.
    /// </summary>
    public Guid StaffId => _staffId;

    /// <summary>
    /// EN: Shop ID.
    /// VI: ID shop.
    /// </summary>
    public Guid ShopId => _shopId;

    /// <summary>
    /// EN: Specific branch ID (null = all branches).
    /// VI: ID chi nhánh cụ thể (null = tất cả chi nhánh).
    /// </summary>
    public Guid? BranchId => _branchId;

    /// <summary>
    /// EN: Role at this shop.
    /// VI: Vai trò tại shop này.
    /// </summary>
    public ShopRole Role => _role;

    /// <summary>
    /// EN: Role ID for EF Core mapping.
    /// VI: Role ID cho EF Core mapping.
    /// </summary>
    public int RoleId { get; private set; }

    /// <summary>
    /// EN: Custom permissions override for this shop.
    /// VI: Quyền tùy chỉnh ghi đè cho shop này.
    /// </summary>
    public StaffPermissions? CustomPermissions => _customPermissions;

    /// <summary>
    /// EN: Whether this is the staff's primary shop.
    /// VI: Đây có phải shop chính của nhân viên không.
    /// </summary>
    public bool IsPrimary => _isPrimary;

    /// <summary>
    /// EN: When the staff was assigned to this shop.
    /// VI: Thời điểm nhân viên được gán vào shop này.
    /// </summary>
    public DateTime AssignedAt => _assignedAt;

    /// <summary>
    /// EN: Private constructor for EF Core.
    /// VI: Constructor private cho EF Core.
    /// </summary>
    protected ShopMember()
    {
    }

    /// <summary>
    /// EN: Create a new shop member assignment.
    /// VI: Tạo việc gán shop member mới.
    /// </summary>
    public ShopMember(Guid staffId, Guid shopId, ShopRole role, Guid? branchId = null, bool isPrimary = false)
    {
        if (staffId == Guid.Empty)
            throw new DomainException("Staff ID cannot be empty");
        if (shopId == Guid.Empty)
            throw new DomainException("Shop ID cannot be empty");
        ArgumentNullException.ThrowIfNull(role, nameof(role));

        Id = Guid.NewGuid();
        _staffId = staffId;
        _shopId = shopId;
        _branchId = branchId;
        _role = role;
        RoleId = role.Id;
        _isPrimary = isPrimary;
        _assignedAt = DateTime.UtcNow;
    }

    /// <summary>
    /// EN: Update role at this shop.
    /// VI: Cập nhật vai trò tại shop này.
    /// </summary>
    public void UpdateRole(ShopRole role)
    {
        ArgumentNullException.ThrowIfNull(role, nameof(role));
        _role = role;
        RoleId = role.Id;
    }

    /// <summary>
    /// EN: Set custom permissions for this shop.
    /// VI: Đặt quyền tùy chỉnh cho shop này.
    /// </summary>
    public void SetCustomPermissions(StaffPermissions? permissions)
    {
        _customPermissions = permissions;
    }

    /// <summary>
    /// EN: Set as primary shop.
    /// VI: Đặt làm shop chính.
    /// </summary>
    public void SetAsPrimary()
    {
        _isPrimary = true;
    }

    /// <summary>
    /// EN: Unset as primary shop.
    /// VI: Bỏ đặt làm shop chính.
    /// </summary>
    public void UnsetAsPrimary()
    {
        _isPrimary = false;
    }

    /// <summary>
    /// EN: Assign to specific branch.
    /// VI: Gán vào chi nhánh cụ thể.
    /// </summary>
    public void AssignToBranch(Guid branchId)
    {
        _branchId = branchId;
    }

    /// <summary>
    /// EN: Remove branch assignment (assign to all branches).
    /// VI: Xóa gán chi nhánh (gán cho tất cả chi nhánh).
    /// </summary>
    public void AssignToAllBranches()
    {
        _branchId = null;
    }
}
