using System.ClientModel;
using System.Text.Json;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using OpenAI;
using OpenAI.Chat;

namespace WhatsAppService.Infrastructure.ExternalServices;

/// <summary>
/// EN: OpenAI LLM service implementation.
/// VI: Triển khai dịch vụ OpenAI LLM.
/// </summary>
public class OpenAILlmService : ILlmService
{
    private readonly ChatClient _chatClient;
    private readonly ILogger<OpenAILlmService> _logger;
    private readonly OpenAISettings _settings;

    public OpenAILlmService(
        IOptions<OpenAISettings> settings,
        ILogger<OpenAILlmService> logger)
    {
        _settings = settings.Value;
        _logger = logger;

        var apiKey = _settings.ApiKey ?? throw new InvalidOperationException("OpenAI API key is not configured");
        var client = new OpenAIClient(apiKey);
        _chatClient = client.GetChatClient(_settings.Model ?? "gpt-4o-mini");
    }

    public async Task<LlmResponse> GenerateResponseAsync(
        LlmRequest request,
        CancellationToken cancellationToken = default)
    {
        try
        {
            var messages = new List<ChatMessage>();

            // Add system prompt
            if (!string.IsNullOrEmpty(request.SystemPrompt))
            {
                messages.Add(ChatMessage.CreateSystemMessage(request.SystemPrompt));
            }

            // Add conversation history
            foreach (var msg in request.Messages)
            {
                messages.Add(msg.Role.ToLowerInvariant() switch
                {
                    "user" => ChatMessage.CreateUserMessage(msg.Content),
                    "assistant" => ChatMessage.CreateAssistantMessage(msg.Content),
                    "system" => ChatMessage.CreateSystemMessage(msg.Content),
                    _ => ChatMessage.CreateUserMessage(msg.Content)
                });
            }

            var options = new ChatCompletionOptions
            {
                MaxOutputTokenCount = request.MaxTokens ?? _settings.MaxTokens ?? 500,
                Temperature = (float?)(request.Temperature ?? _settings.Temperature ?? 0.7)
            };

            _logger.LogDebug("Sending request to OpenAI with {MessageCount} messages", messages.Count);

            var response = await _chatClient.CompleteChatAsync(messages, options, cancellationToken);
            var completion = response.Value;

            var content = completion.Content.FirstOrDefault()?.Text;
            var usage = completion.Usage;

            _logger.LogInformation(
                "OpenAI response received. Prompt tokens: {PromptTokens}, Completion tokens: {CompletionTokens}",
                usage.InputTokenCount, usage.OutputTokenCount);

            return new LlmResponse(
                Success: true,
                Content: content,
                PromptTokens: usage.InputTokenCount,
                CompletionTokens: usage.OutputTokenCount,
                Error: null);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to generate response from OpenAI");
            return new LlmResponse(
                Success: false,
                Content: null,
                PromptTokens: 0,
                CompletionTokens: 0,
                Error: ex.Message);
        }
    }

    public async Task<IntentResult> ExtractIntentAsync(
        string message,
        string[] possibleIntents,
        CancellationToken cancellationToken = default)
    {
        try
        {
            var intentsStr = string.Join(", ", possibleIntents);
            var systemPrompt = $"You are an intent classifier. Analyze the user message and classify it into one of these intents: {intentsStr}. Respond with JSON only in this format: {{\"intent\": \"intent_name\", \"confidence\": 0.0-1.0}}";

            var messages = new List<ChatMessage>
            {
                ChatMessage.CreateSystemMessage(systemPrompt),
                ChatMessage.CreateUserMessage(message)
            };

            var options = new ChatCompletionOptions
            {
                MaxOutputTokenCount = 100,
                Temperature = 0.1f
            };

            var response = await _chatClient.CompleteChatAsync(messages, options, cancellationToken);
            var content = response.Value.Content.FirstOrDefault()?.Text ?? "{}";

            var result = JsonSerializer.Deserialize<IntentExtraction>(content);
            
            return new IntentResult(
                Success: true,
                Intent: result?.Intent,
                Confidence: result?.Confidence ?? 0,
                Error: null);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to extract intent");
            return new IntentResult(
                Success: false,
                Intent: null,
                Confidence: 0,
                Error: ex.Message);
        }
    }

    private record IntentExtraction(string? Intent, double Confidence);
}

/// <summary>
/// EN: OpenAI configuration settings.
/// VI: Cấu hình OpenAI.
/// </summary>
public class OpenAISettings
{
    public string? ApiKey { get; set; }
    public string? Model { get; set; } = "gpt-4o-mini";
    public int? MaxTokens { get; set; } = 500;
    public double? Temperature { get; set; } = 0.7;
}
