using MktXService.Domain.Exceptions;
using MktXService.Domain.SeedWork;

namespace MktXService.Domain.AggregatesModel.SegmentAggregate;

/// <summary>
/// EN: Segment aggregate root for dynamic customer segmentation with condition-based filtering.
/// VI: Aggregate root phân khúc cho phân khúc khách hàng động với lọc dựa trên điều kiện.
/// </summary>
public class Segment : Entity, IAggregateRoot
{
    private Guid _merchantId;
    private string _name = null!;
    private List<SegmentCondition> _conditions = new();
    private int _contactCount;
    private DateTime _createdAt;
    private DateTime? _updatedAt;

    public Guid MerchantId => _merchantId;
    public string Name => _name;
    public IReadOnlyList<SegmentCondition> Conditions => _conditions.AsReadOnly();
    public int ContactCount => _contactCount;
    public DateTime CreatedAt => _createdAt;
    public DateTime? UpdatedAt => _updatedAt;

    protected Segment() { }

    public Segment(Guid merchantId, string name) : this()
    {
        if (merchantId == Guid.Empty)
            throw new SegmentDomainException("Merchant ID cannot be empty");
        if (string.IsNullOrWhiteSpace(name))
            throw new SegmentDomainException("Segment name cannot be empty");

        Id = Guid.NewGuid();
        _merchantId = merchantId;
        _name = name;
        _createdAt = DateTime.UtcNow;
    }

    public void UpdateName(string name)
    {
        if (string.IsNullOrWhiteSpace(name))
            throw new SegmentDomainException("Segment name cannot be empty");

        _name = name;
        _updatedAt = DateTime.UtcNow;
    }

    public void AddCondition(SegmentCondition condition)
    {
        _conditions.Add(condition);
        _updatedAt = DateTime.UtcNow;
    }

    public void RemoveCondition(Guid conditionId)
    {
        var condition = _conditions.FirstOrDefault(c => c.Id == conditionId);
        if (condition != null)
        {
            _conditions.Remove(condition);
            _updatedAt = DateTime.UtcNow;
        }
    }

    public void ClearConditions()
    {
        _conditions.Clear();
        _updatedAt = DateTime.UtcNow;
    }

    public void UpdateContactCount(int count)
    {
        _contactCount = count;
        _updatedAt = DateTime.UtcNow;
    }

    public void SetConditions(List<SegmentCondition> conditions)
    {
        _conditions = conditions ?? new List<SegmentCondition>();
        _updatedAt = DateTime.UtcNow;
    }
}

/// <summary>
/// EN: Segment condition entity for filtering contacts.
/// VI: Entity điều kiện phân khúc để lọc liên hệ.
/// </summary>
public class SegmentCondition : Entity
{
    private string _field = null!;
    private string _operator = null!;
    private string _value = null!;

    public Guid SegmentId { get; private set; }
    public string Field => _field;
    public string Operator => _operator;
    public string Value => _value;

    protected SegmentCondition() { }

    public SegmentCondition(Guid segmentId, string field, string @operator, string value) : this()
    {
        if (string.IsNullOrWhiteSpace(field))
            throw new SegmentDomainException("Condition field cannot be empty");
        if (string.IsNullOrWhiteSpace(@operator))
            throw new SegmentDomainException("Condition operator cannot be empty");

        Id = Guid.NewGuid();
        SegmentId = segmentId;
        _field = field;
        _operator = @operator;
        _value = value ?? "";
    }
}
