// EN: Leave request aggregate — staff leave/time-off requests.
// VI: Aggregate nghi phep — yeu cau nghi phep cua nhan vien.

using MerchantService.Domain.SeedWork;

namespace MerchantService.Domain.AggregatesModel.LeaveRequestAggregate;

/// <summary>
/// EN: Leave request from a staff member.
/// VI: Yeu cau nghi phep tu nhan vien.
/// </summary>
public class LeaveRequest : Entity, IAggregateRoot
{
    private Guid _staffId;
    private Guid _shopId;
    private string _leaveType; // Annual, Sick, Personal, Maternity, Other
    private DateTime _startDate;
    private DateTime _endDate;
    private string? _reason;
    private string _status; // Pending, Approved, Rejected
    private Guid? _approvedBy;
    private DateTime? _approvedAt;
    private string? _rejectionReason;
    private DateTime _createdAt;

    public Guid StaffId => _staffId;
    public Guid ShopId => _shopId;
    public string LeaveType => _leaveType;
    public DateTime StartDate => _startDate;
    public DateTime EndDate => _endDate;
    public string? Reason => _reason;
    public string Status => _status;
    public Guid? ApprovedBy => _approvedBy;
    public DateTime? ApprovedAt => _approvedAt;
    public string? RejectionReason => _rejectionReason;
    public DateTime CreatedAt => _createdAt;

    /// <summary>
    /// EN: Number of days requested.
    /// VI: So ngay nghi phep yeu cau.
    /// </summary>
    public int Days => (_endDate - _startDate).Days + 1;

    protected LeaveRequest() { _leaveType = "Annual"; _status = "Pending"; }

    /// <summary>
    /// EN: Create a new leave request.
    /// VI: Tao yeu cau nghi phep moi.
    /// </summary>
    public static LeaveRequest Create(Guid staffId, Guid shopId, string leaveType, DateTime startDate, DateTime endDate, string? reason)
    {
        if (endDate < startDate)
            throw new InvalidOperationException("End date must be after start date / Ngay ket thuc phai sau ngay bat dau");

        return new LeaveRequest
        {
            Id = Guid.NewGuid(),
            _staffId = staffId,
            _shopId = shopId,
            _leaveType = leaveType,
            _startDate = DateTime.SpecifyKind(startDate.Date, DateTimeKind.Utc),
            _endDate = DateTime.SpecifyKind(endDate.Date, DateTimeKind.Utc),
            _reason = reason,
            _status = "Pending",
            _createdAt = DateTime.UtcNow
        };
    }

    /// <summary>
    /// EN: Approve the leave request.
    /// VI: Duyet yeu cau nghi phep.
    /// </summary>
    public void Approve(Guid approvedBy)
    {
        if (_status != "Pending")
            throw new InvalidOperationException("Only pending requests can be approved / Chi duyet duoc yeu cau dang cho");

        _status = "Approved";
        _approvedBy = approvedBy;
        _approvedAt = DateTime.UtcNow;
    }

    /// <summary>
    /// EN: Reject the leave request.
    /// VI: Tu choi yeu cau nghi phep.
    /// </summary>
    public void Reject(Guid rejectedBy, string? reason = null)
    {
        if (_status != "Pending")
            throw new InvalidOperationException("Only pending requests can be rejected / Chi tu choi duoc yeu cau dang cho");

        _status = "Rejected";
        _approvedBy = rejectedBy;
        _approvedAt = DateTime.UtcNow;
        _rejectionReason = reason;
    }
}
