using FacebookService.Domain.Exceptions;
using FacebookService.Domain.SeedWork;

namespace FacebookService.Domain.AggregatesModel.ChatbotAggregate;

/// <summary>
/// EN: AIChatbotConfig aggregate root configuring AI-powered chatbot behavior.
/// VI: AIChatbotConfig aggregate root cấu hình hành vi chatbot AI.
/// </summary>
public class AIChatbotConfig : Entity, IAggregateRoot
{
    // EN: Validation constraints
    // VI: Ràng buộc validation
    private const float MinTemperature = 0.0f;
    private const float MaxTemperature = 2.0f;
    private const int MinMaxTokens = 1;
    private const int MaxMaxTokens = 4096;

    // EN: Private fields for encapsulation
    // VI: Fields private để đóng gói
    private Guid _shopId;
    private AIProvider _provider = null!;
    private string _model = null!;
    private string _systemPrompt = null!;
    private float _temperature;
    private int _maxTokens;
    private bool _isEnabled;
    private DateTime _createdAt;
    private DateTime _updatedAt;

    /// <summary>
    /// EN: Shop ID that owns this config.
    /// VI: ID shop sở hữu config này.
    /// </summary>
    public Guid ShopId => _shopId;

    /// <summary>
    /// EN: AI provider. / VI: Nhà cung cấp AI.
    /// </summary>
    public AIProvider Provider => _provider;

    /// <summary>
    /// EN: Provider ID for EF Core. / VI: ID nhà cung cấp cho EF Core.
    /// </summary>
    public int ProviderId { get; private set; }

    /// <summary>
    /// EN: AI model name (e.g., gpt-4-turbo).
    /// VI: Tên model AI (ví dụ: gpt-4-turbo).
    /// </summary>
    public string Model => _model;

    /// <summary>
    /// EN: System prompt for AI context.
    /// VI: System prompt cho ngữ cảnh AI.
    /// </summary>
    public string SystemPrompt => _systemPrompt;

    /// <summary>
    /// EN: Temperature setting (0.0 - 2.0).
    /// VI: Cài đặt temperature (0.0 - 2.0).
    /// </summary>
    public float Temperature => _temperature;

    /// <summary>
    /// EN: Maximum tokens for response.
    /// VI: Số tokens tối đa cho response.
    /// </summary>
    public int MaxTokens => _maxTokens;

    /// <summary>
    /// EN: Whether AI chatbot is enabled.
    /// VI: AI chatbot có được bật không.
    /// </summary>
    public bool IsEnabled => _isEnabled;

    /// <summary>
    /// EN: Creation timestamp. / VI: Thời gian tạo.
    /// </summary>
    public DateTime CreatedAt => _createdAt;

    /// <summary>
    /// EN: Last update timestamp. / VI: Thời gian cập nhật cuối.
    /// </summary>
    public DateTime UpdatedAt => _updatedAt;

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

    /// <summary>
    /// EN: Create a new AI chatbot configuration.
    /// VI: Tạo cấu hình AI chatbot mới.
    /// </summary>
    public AIChatbotConfig(
        Guid shopId,
        AIProvider provider,
        string model,
        string systemPrompt,
        float temperature = 0.7f,
        int maxTokens = 500) : this()
    {
        if (shopId == Guid.Empty)
            throw new FacebookDomainException("Shop ID cannot be empty");
        
        if (string.IsNullOrWhiteSpace(model))
            throw new FacebookDomainException("Model name cannot be empty");
        
        if (string.IsNullOrWhiteSpace(systemPrompt))
            throw new FacebookDomainException("System prompt cannot be empty");

        ValidateTemperature(temperature);
        ValidateMaxTokens(maxTokens);

        Id = Guid.NewGuid();
        _shopId = shopId;
        _provider = provider;
        ProviderId = provider.Id;
        _model = model;
        _systemPrompt = systemPrompt;
        _temperature = temperature;
        _maxTokens = maxTokens;
        _isEnabled = false;
        _createdAt = DateTime.UtcNow;
        _updatedAt = DateTime.UtcNow;
    }

    /// <summary>
    /// EN: Update configuration settings.
    /// VI: Cập nhật cài đặt cấu hình.
    /// </summary>
    public void UpdateConfig(
        AIProvider provider,
        string model,
        string systemPrompt,
        float temperature,
        int maxTokens)
    {
        if (string.IsNullOrWhiteSpace(model))
            throw new FacebookDomainException("Model name cannot be empty");
        
        if (string.IsNullOrWhiteSpace(systemPrompt))
            throw new FacebookDomainException("System prompt cannot be empty");

        ValidateTemperature(temperature);
        ValidateMaxTokens(maxTokens);

        _provider = provider;
        ProviderId = provider.Id;
        _model = model;
        _systemPrompt = systemPrompt;
        _temperature = temperature;
        _maxTokens = maxTokens;
        _updatedAt = DateTime.UtcNow;
    }

    /// <summary>
    /// EN: Update system prompt only.
    /// VI: Chỉ cập nhật system prompt.
    /// </summary>
    public void UpdateSystemPrompt(string systemPrompt)
    {
        if (string.IsNullOrWhiteSpace(systemPrompt))
            throw new FacebookDomainException("System prompt cannot be empty");

        _systemPrompt = systemPrompt;
        _updatedAt = DateTime.UtcNow;
    }

    /// <summary>
    /// EN: Enable the AI chatbot.
    /// VI: Bật AI chatbot.
    /// </summary>
    public void Enable()
    {
        _isEnabled = true;
        _updatedAt = DateTime.UtcNow;
    }

    /// <summary>
    /// EN: Disable the AI chatbot.
    /// VI: Tắt AI chatbot.
    /// </summary>
    public void Disable()
    {
        _isEnabled = false;
        _updatedAt = DateTime.UtcNow;
    }

    /// <summary>
    /// EN: Validate temperature value.
    /// VI: Validate giá trị temperature.
    /// </summary>
    private static void ValidateTemperature(float temperature)
    {
        if (temperature < MinTemperature || temperature > MaxTemperature)
            throw new FacebookDomainException($"Temperature must be between {MinTemperature} and {MaxTemperature}");
    }

    /// <summary>
    /// EN: Validate max tokens value.
    /// VI: Validate giá trị max tokens.
    /// </summary>
    private static void ValidateMaxTokens(int maxTokens)
    {
        if (maxTokens < MinMaxTokens || maxTokens > MaxMaxTokens)
            throw new FacebookDomainException($"Max tokens must be between {MinMaxTokens} and {MaxMaxTokens}");
    }
}
