using MediatR;
using FacebookService.Domain.AggregatesModel.ChatbotAggregate;

namespace FacebookService.API.Application.Commands;

/// <summary>
/// EN: Handler for UpsertAIChatbotConfigCommand.
/// VI: Handler cho UpsertAIChatbotConfigCommand.
/// </summary>
public class UpsertAIChatbotConfigCommandHandler : IRequestHandler<UpsertAIChatbotConfigCommand, UpsertAIChatbotConfigResult>
{
    private readonly IAIChatbotConfigRepository _configRepository;
    private readonly ILogger<UpsertAIChatbotConfigCommandHandler> _logger;

    public UpsertAIChatbotConfigCommandHandler(
        IAIChatbotConfigRepository configRepository,
        ILogger<UpsertAIChatbotConfigCommandHandler> logger)
    {
        _configRepository = configRepository ?? throw new ArgumentNullException(nameof(configRepository));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    public async Task<UpsertAIChatbotConfigResult> Handle(
        UpsertAIChatbotConfigCommand request,
        CancellationToken cancellationToken)
    {
        _logger.LogInformation(
            "Upserting AI chatbot config for shop: {ShopId}",
            request.ShopId);

        // EN: Parse provider / VI: Parse provider
        var provider = ParseProvider(request.Provider);
        if (provider is null)
        {
            _logger.LogWarning("Invalid AI provider: {Provider}", request.Provider);
            return new UpsertAIChatbotConfigResult(Guid.Empty, IsNew: false, Success: false);
        }

        // EN: Check for existing config / VI: Kiểm tra config sẵn có
        var existingConfig = await _configRepository.GetByShopIdAsync(request.ShopId, cancellationToken);

        if (existingConfig is not null)
        {
            // EN: Update existing / VI: Cập nhật sẵn có
            try
            {
                existingConfig.UpdateConfig(
                    provider,
                    request.Model,
                    request.SystemPrompt,
                    request.Temperature,
                    request.MaxTokens);

                _configRepository.Update(existingConfig);
                await _configRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

                _logger.LogInformation("AI config updated for shop: {ShopId}", request.ShopId);
                return new UpsertAIChatbotConfigResult(existingConfig.Id, IsNew: false, Success: true);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Failed to update AI config for shop: {ShopId}", request.ShopId);
                return new UpsertAIChatbotConfigResult(existingConfig.Id, IsNew: false, Success: false);
            }
        }

        // EN: Create new config / VI: Tạo config mới
        try
        {
            var config = new AIChatbotConfig(
                request.ShopId,
                provider,
                request.Model,
                request.SystemPrompt,
                request.Temperature,
                request.MaxTokens);

            _configRepository.Add(config);
            await _configRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

            _logger.LogInformation("AI config created for shop: {ShopId} with ID: {ConfigId}", 
                request.ShopId, config.Id);
            return new UpsertAIChatbotConfigResult(config.Id, IsNew: true, Success: true);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to create AI config for shop: {ShopId}", request.ShopId);
            return new UpsertAIChatbotConfigResult(Guid.Empty, IsNew: true, Success: false);
        }
    }

    private static AIProvider? ParseProvider(string provider)
    {
        return provider?.ToLowerInvariant() switch
        {
            "openai" => AIProvider.OpenAI,
            "azureopenai" or "azure" => AIProvider.AzureOpenAI,
            _ => null
        };
    }
}
