// EN: Therapist aggregate root for Spa/Beauty therapist management.
// VI: Aggregate root Therapist cho quản lý chuyên viên Spa/Beauty.

using BookingService.Domain.Events;
using BookingService.Domain.Exceptions;
using BookingService.Domain.SeedWork;

namespace BookingService.Domain.AggregatesModel.TherapistAggregate;

/// <summary>
/// EN: Therapist aggregate root - represents a spa/beauty therapist with specialties and working hours.
/// VI: Aggregate root Therapist - đại diện cho chuyên viên spa/beauty với chuyên môn và giờ làm việc.
/// </summary>
public class Therapist : Entity, IAggregateRoot
{
    private Guid _shopId;
    private string _name = null!;
    private string[] _specialties = [];
    private string _workingHours = null!; // EN: JSON string for weekly schedule / VI: Chuỗi JSON cho lịch tuần
    private bool _isActive;
    private DateTime _createdAt;
    private DateTime? _updatedAt;

    /// <summary>
    /// EN: The shop this therapist belongs to.
    /// VI: Shop mà chuyên viên này thuộc về.
    /// </summary>
    public Guid ShopId => _shopId;

    /// <summary>
    /// EN: Full name of the therapist.
    /// VI: Tên đầy đủ của chuyên viên.
    /// </summary>
    public string Name => _name;

    /// <summary>
    /// EN: List of specialties (e.g., massage, facial, nails).
    /// VI: Danh sách chuyên môn (ví dụ: massage, facial, nails).
    /// </summary>
    public string[] Specialties => _specialties;

    /// <summary>
    /// EN: JSON working hours schedule for the week.
    /// VI: Lịch làm việc dạng JSON cho tuần.
    /// </summary>
    public string WorkingHours => _workingHours;

    /// <summary>
    /// EN: Whether the therapist is currently active.
    /// VI: Chuyên viên có đang hoạt động hay không.
    /// </summary>
    public bool IsActive => _isActive;

    /// <summary>
    /// EN: When the therapist record was created.
    /// VI: Thời điểm tạo bản ghi chuyên viên.
    /// </summary>
    public DateTime CreatedAt => _createdAt;

    /// <summary>
    /// EN: When the therapist record was last updated.
    /// VI: Thời điểm cập nhật bản ghi chuyên viên lần cuối.
    /// </summary>
    public DateTime? UpdatedAt => _updatedAt;

    /// <summary>
    /// EN: EF Core parameterless constructor.
    /// VI: Constructor không tham số cho EF Core.
    /// </summary>
    protected Therapist()
    {
    }

    /// <summary>
    /// EN: Create a new therapist.
    /// VI: Tạo chuyên viên mới.
    /// </summary>
    /// <param name="shopId">EN: The shop ID / VI: ID shop</param>
    /// <param name="name">EN: Therapist name / VI: Tên chuyên viên</param>
    /// <param name="specialties">EN: List of specialties / VI: Danh sách chuyên môn</param>
    /// <param name="workingHours">EN: JSON working hours / VI: Giờ làm việc dạng JSON</param>
    public Therapist(
        Guid shopId,
        string name,
        string[] specialties,
        string workingHours)
    {
        if (shopId == Guid.Empty)
            throw new DomainException("Shop ID cannot be empty / Shop ID không được trống");
        if (string.IsNullOrWhiteSpace(name))
            throw new DomainException("Therapist name cannot be empty / Tên chuyên viên không được trống");
        if (string.IsNullOrWhiteSpace(workingHours))
            throw new DomainException("Working hours cannot be empty / Giờ làm việc không được trống");

        Id = Guid.NewGuid();
        _shopId = shopId;
        _name = name.Trim();
        _specialties = specialties ?? [];
        _workingHours = workingHours;
        _isActive = true;
        _createdAt = DateTime.UtcNow;

        AddDomainEvent(new TherapistCreatedDomainEvent(this));
    }

    /// <summary>
    /// EN: Activate the therapist.
    /// VI: Kích hoạt chuyên viên.
    /// </summary>
    public void Activate()
    {
        if (_isActive)
            throw new DomainException("Therapist is already active / Chuyên viên đã đang hoạt động");

        _isActive = true;
        _updatedAt = DateTime.UtcNow;
    }

    /// <summary>
    /// EN: Deactivate the therapist.
    /// VI: Vô hiệu hóa chuyên viên.
    /// </summary>
    public void Deactivate()
    {
        if (!_isActive)
            throw new DomainException("Therapist is already inactive / Chuyên viên đã đang bị vô hiệu");

        _isActive = false;
        _updatedAt = DateTime.UtcNow;
    }

    /// <summary>
    /// EN: Update therapist specialties.
    /// VI: Cập nhật chuyên môn chuyên viên.
    /// </summary>
    /// <param name="specialties">EN: New specialties list / VI: Danh sách chuyên môn mới</param>
    public void UpdateSpecialties(string[] specialties)
    {
        _specialties = specialties ?? [];
        _updatedAt = DateTime.UtcNow;
        AddDomainEvent(new TherapistUpdatedDomainEvent(this));
    }

    /// <summary>
    /// EN: Update therapist working hours.
    /// VI: Cập nhật giờ làm việc chuyên viên.
    /// </summary>
    /// <param name="workingHours">EN: New JSON working hours / VI: Giờ làm việc mới dạng JSON</param>
    public void UpdateWorkingHours(string workingHours)
    {
        if (string.IsNullOrWhiteSpace(workingHours))
            throw new DomainException("Working hours cannot be empty / Giờ làm việc không được trống");

        _workingHours = workingHours;
        _updatedAt = DateTime.UtcNow;
        AddDomainEvent(new TherapistUpdatedDomainEvent(this));
    }

    /// <summary>
    /// EN: Update therapist name.
    /// VI: Cập nhật tên chuyên viên.
    /// </summary>
    /// <param name="name">EN: New name / VI: Tên mới</param>
    public void UpdateName(string name)
    {
        if (string.IsNullOrWhiteSpace(name))
            throw new DomainException("Therapist name cannot be empty / Tên chuyên viên không được trống");

        _name = name.Trim();
        _updatedAt = DateTime.UtcNow;
        AddDomainEvent(new TherapistUpdatedDomainEvent(this));
    }

    /// <summary>
    /// EN: Update therapist details (name, specialties, working hours).
    /// VI: Cập nhật thông tin chuyên viên (tên, chuyên môn, giờ làm việc).
    /// </summary>
    public void Update(string name, string[] specialties, string workingHours)
    {
        if (string.IsNullOrWhiteSpace(name))
            throw new DomainException("Therapist name cannot be empty / Tên chuyên viên không được trống");
        if (string.IsNullOrWhiteSpace(workingHours))
            throw new DomainException("Working hours cannot be empty / Giờ làm việc không được trống");

        _name = name.Trim();
        _specialties = specialties ?? [];
        _workingHours = workingHours;
        _updatedAt = DateTime.UtcNow;
        AddDomainEvent(new TherapistUpdatedDomainEvent(this));
    }
}
