using DramaLing.Api.Models.DTOs;
using DramaLing.Api.Models.Entities;
using DramaLing.Api.Models.Configuration;
using Microsoft.Extensions.Options;
using System.Text.Json;
using System.Text;

namespace DramaLing.Api.Services;

public interface IGeminiService
{
    Task<SentenceAnalysisData> AnalyzeSentenceAsync(string inputText, AnalysisOptions options);
    Task<string> GenerateImageDescriptionAsync(Flashcard flashcard, GenerationOptionsDto options);
}

public class GeminiService : IGeminiService
{
    private readonly HttpClient _httpClient;
    private readonly ILogger<GeminiService> _logger;
    private readonly GeminiOptions _options;

    public GeminiService(HttpClient httpClient, IOptions<GeminiOptions> options, ILogger<GeminiService> logger)
    {
        _httpClient = httpClient;
        _logger = logger;
        _options = options.Value;

        _logger.LogInformation("GeminiService initialized with model: {Model}, timeout: {Timeout}s",
            _options.Model, _options.TimeoutSeconds);

        _httpClient.Timeout = TimeSpan.FromSeconds(_options.TimeoutSeconds);
        _httpClient.DefaultRequestHeaders.Add("User-Agent", "DramaLing/1.0");
    }

    public async Task<SentenceAnalysisData> AnalyzeSentenceAsync(string inputText, AnalysisOptions options)
    {
        var startTime = DateTime.UtcNow;

        try
        {
            _logger.LogInformation("Starting sentence analysis for text: {Text}",
                inputText.Substring(0, Math.Min(50, inputText.Length)));

            // 符合產品需求規格的結構化 prompt
            var prompt = $@"You are an English learning assistant. Analyze this sentence and return ONLY a valid JSON response.

**Input Sentence**: ""{inputText}""

**Required JSON Structure:**
{{
  ""sentenceTranslation"": ""Traditional Chinese translation of the entire sentence"",
  ""hasGrammarErrors"": true/false,
  ""grammarCorrections"": [
    {{
      ""original"": ""incorrect text"",
      ""corrected"": ""correct text"",
      ""type"": ""error type (tense/subject-verb/preposition/word-order)"",
      ""explanation"": ""brief explanation in Traditional Chinese""
    }}
  ],
  ""vocabularyAnalysis"": {{
    ""word1"": {{
      ""word"": ""the word"",
      ""translation"": ""Traditional Chinese translation"",
      ""definition"": ""English definition"",
      ""partOfSpeech"": ""noun/verb/adjective/etc"",
      ""pronunciation"": ""/phonetic/"",
      ""difficultyLevel"": ""A1/A2/B1/B2/C1/C2"",
      ""frequency"": ""high/medium/low"",
      ""synonyms"": [""synonym1"", ""synonym2""],
      ""example"": ""example sentence"",
      ""exampleTranslation"": ""Traditional Chinese example translation""
    }}
  }},
  ""idioms"": [
    {{
      ""idiom"": ""idiomatic expression"",
      ""translation"": ""Traditional Chinese meaning"",
      ""definition"": ""English explanation"",
      ""pronunciation"": ""/phonetic notation/"",
      ""difficultyLevel"": ""A1/A2/B1/B2/C1/C2"",
      ""frequency"": ""high/medium/low"",
      ""synonyms"": [""synonym1"", ""synonym2""],
      ""example"": ""usage example"",
      ""exampleTranslation"": ""Traditional Chinese example""
    }}
  ]
}}

**Analysis Guidelines:**
1. **Grammar Check**: Detect tense errors, subject-verb agreement, preposition usage, word order
2. **Vocabulary Analysis**: Include ALL significant words (exclude articles: a, an, the)
3. **CEFR Levels**: Assign accurate A1-C2 levels for each word
4. **Idioms**: Identify any idiomatic expressions or phrasal verbs
5. **Translations**: Use Traditional Chinese (Taiwan standard)

**IMPORTANT**: Return ONLY the JSON object, no additional text or explanation.";

            var aiResponse = await CallGeminiAPI(prompt);

            _logger.LogInformation("Gemini AI response received: {ResponseLength} characters", aiResponse?.Length ?? 0);

            if (string.IsNullOrWhiteSpace(aiResponse))
            {
                throw new InvalidOperationException("Gemini API returned empty response");
            }

            // 檢查是否是安全過濾的回退訊息
            if (aiResponse.Contains("temporarily unavailable due to safety filtering"))
            {
                // 這是安全過濾的情況，但我們仍然要處理它而不是拋出異常
                _logger.LogWarning("Using safety filtering fallback response");
            }

            // 直接使用 AI 的回應創建分析數據
            var analysisData = CreateAnalysisFromAIResponse(inputText, aiResponse);

            var processingTime = (DateTime.UtcNow - startTime).TotalSeconds;
            _logger.LogInformation("Sentence analysis completed in {ProcessingTime}s", processingTime);

            return analysisData;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error analyzing sentence: {Text}", inputText);
            throw;
        }
    }

    private SentenceAnalysisData CreateAnalysisFromAIResponse(string inputText, string aiResponse)
    {
        _logger.LogInformation("Creating analysis from AI response: {ResponsePreview}...",
            aiResponse.Substring(0, Math.Min(100, aiResponse.Length)));

        try
        {
            // 清理 AI 回應以確保是純 JSON
            var cleanJson = aiResponse.Trim();
            if (cleanJson.StartsWith("```json"))
            {
                cleanJson = cleanJson.Substring(7);
            }
            if (cleanJson.EndsWith("```"))
            {
                cleanJson = cleanJson.Substring(0, cleanJson.Length - 3);
            }

            // 解析 AI 回應的 JSON
            var aiAnalysis = JsonSerializer.Deserialize<AiAnalysisResponse>(cleanJson, new JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true
            });

            if (aiAnalysis == null)
            {
                throw new InvalidOperationException("Failed to parse AI response JSON");
            }

            // 轉換為 DTO 結構
            var analysisData = new SentenceAnalysisData
            {
                OriginalText = inputText,
                SentenceMeaning = aiAnalysis.SentenceTranslation ?? "",
                VocabularyAnalysis = ConvertVocabularyAnalysis(aiAnalysis.VocabularyAnalysis ?? new()),
                Idioms = ConvertIdioms(aiAnalysis.Idioms ?? new()),
                GrammarCorrection = ConvertGrammarCorrection(aiAnalysis),
                Metadata = new AnalysisMetadata
                {
                    ProcessingDate = DateTime.UtcNow,
                    AnalysisModel = "gemini-1.5-flash",
                    AnalysisVersion = "2.0"
                }
            };


            return analysisData;
        }
        catch (JsonException ex)
        {
            _logger.LogError(ex, "Failed to parse AI response as JSON: {Response}", aiResponse);
            // 回退到舊的處理方式
            return CreateFallbackAnalysis(inputText, aiResponse);
        }
    }

    private Dictionary<string, VocabularyAnalysisDto> ConvertVocabularyAnalysis(Dictionary<string, AiVocabularyAnalysis> aiVocab)
    {
        var result = new Dictionary<string, VocabularyAnalysisDto>();

        foreach (var kvp in aiVocab)
        {
            var aiWord = kvp.Value;
            result[kvp.Key] = new VocabularyAnalysisDto
            {
                Word = aiWord.Word ?? kvp.Key,
                Translation = aiWord.Translation ?? "",
                Definition = aiWord.Definition ?? "",
                PartOfSpeech = aiWord.PartOfSpeech ?? "unknown",
                Pronunciation = aiWord.Pronunciation ?? $"/{kvp.Key}/",
                DifficultyLevel = aiWord.DifficultyLevel ?? "A2",
                Frequency = aiWord.Frequency ?? "medium",
                Synonyms = aiWord.Synonyms ?? new List<string>(),
                Example = aiWord.Example,
                ExampleTranslation = aiWord.ExampleTranslation,
            };
        }

        return result;
    }

    private List<IdiomDto> ConvertIdioms(List<AiIdiom> aiIdioms)
    {
        var result = new List<IdiomDto>();

        foreach (var aiIdiom in aiIdioms)
        {
            result.Add(new IdiomDto
            {
                Idiom = aiIdiom.Idiom ?? "",
                Translation = aiIdiom.Translation ?? "",
                Definition = aiIdiom.Definition ?? "",
                Pronunciation = aiIdiom.Pronunciation ?? "",
                DifficultyLevel = aiIdiom.DifficultyLevel ?? "B2",
                Frequency = aiIdiom.Frequency ?? "medium",
                Synonyms = aiIdiom.Synonyms ?? new List<string>(),
                Example = aiIdiom.Example,
                ExampleTranslation = aiIdiom.ExampleTranslation
            });
        }

        return result;
    }

    private GrammarCorrectionDto? ConvertGrammarCorrection(AiAnalysisResponse aiAnalysis)
    {
        if (!aiAnalysis.HasGrammarErrors || aiAnalysis.GrammarCorrections == null || !aiAnalysis.GrammarCorrections.Any())
        {
            return null;
        }

        var corrections = aiAnalysis.GrammarCorrections.Select(gc => new GrammarErrorDto
        {
            Error = gc.Original ?? "",
            Correction = gc.Corrected ?? "",
            Type = gc.Type ?? "grammar",
            Explanation = gc.Explanation ?? "",
            Severity = "medium",
            Position = new ErrorPosition { Start = 0, End = 0 } // 簡化處理
        }).ToList();

        return new GrammarCorrectionDto
        {
            HasErrors = true,
            CorrectedText = string.Join(" ", corrections.Select(c => c.Correction)),
            Corrections = corrections
        };
    }

    private SentenceAnalysisData CreateFallbackAnalysis(string inputText, string aiResponse)
    {
        _logger.LogWarning("Using fallback analysis due to JSON parsing failure");

        return new SentenceAnalysisData
        {
            OriginalText = inputText,
            SentenceMeaning = aiResponse,
            VocabularyAnalysis = CreateBasicVocabularyFromText(inputText, aiResponse),
            Metadata = new AnalysisMetadata
            {
                ProcessingDate = DateTime.UtcNow,
                AnalysisModel = "gemini-1.5-flash-fallback",
                AnalysisVersion = "2.0"
            },
        };
    }

    private Dictionary<string, VocabularyAnalysisDto> CreateBasicVocabularyFromText(string inputText, string aiResponse)
    {
        // 從 AI 回應中提取真實的詞彙翻譯
        var words = inputText.Split(' ', StringSplitOptions.RemoveEmptyEntries);
        var result = new Dictionary<string, VocabularyAnalysisDto>();

        foreach (var word in words.Take(15))
        {
            var cleanWord = word.ToLower().Trim('.', ',', '!', '?', ';', ':', '"', '\'');
            if (string.IsNullOrEmpty(cleanWord) || cleanWord.Length < 2) continue;

            result[cleanWord] = new VocabularyAnalysisDto
            {
                Word = cleanWord,
                Translation = ExtractTranslationFromAI(cleanWord, aiResponse),
                Definition = $"Please refer to the AI analysis above for detailed definition.",
                PartOfSpeech = "unknown",
                Pronunciation = $"/{cleanWord}/",
                DifficultyLevel = EstimateBasicDifficulty(cleanWord),
                Frequency = "medium",
                Synonyms = new List<string>(),
                Example = null,
                ExampleTranslation = null,
            };
        }

        return result;
    }

    private string ExtractTranslationFromAI(string word, string aiResponse)
    {
        // 嘗試從 AI 回應中提取該詞的翻譯
        // 這是簡化版本，真正的版本應該解析完整的 JSON
        if (aiResponse.Contains(word, StringComparison.OrdinalIgnoreCase))
        {
            return $"{word} translation from AI";
        }
        return $"{word} - 請查看完整分析";
    }

    private string EstimateBasicDifficulty(string word)
    {
        // 基本詞彙列表（這是最小的 fallback 邏輯）
        var a1Words = new[] { "i", "you", "he", "she", "it", "we", "they", "the", "a", "an", "is", "are", "was", "were", "have", "do", "go", "get", "see", "know" };
        var a2Words = new[] { "make", "think", "come", "take", "use", "work", "call", "try", "ask", "need", "feel", "become", "leave", "put", "say", "tell", "turn", "move" };

        var lowerWord = word.ToLower();
        if (a1Words.Contains(lowerWord)) return "A1";
        if (a2Words.Contains(lowerWord)) return "A2";
        if (word.Length <= 4) return "A2";
        if (word.Length <= 6) return "B1";
        return "B2";
    }


    private async Task<string> CallGeminiAPI(string prompt)
    {
        try
        {
            var requestBody = new
            {
                contents = new[]
                {
                    new
                    {
                        parts = new[]
                        {
                            new { text = prompt }
                        }
                    }
                },
                generationConfig = new
                {
                    temperature = _options.Temperature,
                    topK = 40,
                    topP = 0.95,
                    maxOutputTokens = _options.MaxOutputTokens
                }
            };

            var json = JsonSerializer.Serialize(requestBody);
            var content = new StringContent(json, Encoding.UTF8, "application/json");

            var response = await _httpClient.PostAsync($"{_options.BaseUrl}/v1beta/models/{_options.Model}:generateContent?key={_options.ApiKey}", content);
            response.EnsureSuccessStatusCode();

            var responseJson = await response.Content.ReadAsStringAsync();
            _logger.LogInformation("Raw Gemini API response: {Response}", responseJson.Substring(0, Math.Min(500, responseJson.Length)));

            // 先嘗試使用動態解析來避免反序列化問題
            using var document = JsonDocument.Parse(responseJson);
            var root = document.RootElement;

            string aiText = string.Empty;

            // 檢查是否有 candidates 陣列
            if (root.TryGetProperty("candidates", out var candidatesElement) && candidatesElement.ValueKind == JsonValueKind.Array)
            {
                _logger.LogInformation("Found candidates array with {Count} items", candidatesElement.GetArrayLength());

                var firstCandidate = candidatesElement.EnumerateArray().FirstOrDefault();
                if (firstCandidate.ValueKind != JsonValueKind.Undefined)
                {
                    if (firstCandidate.TryGetProperty("content", out var contentElement))
                    {
                        if (contentElement.TryGetProperty("parts", out var partsElement) && partsElement.ValueKind == JsonValueKind.Array)
                        {
                            var firstPart = partsElement.EnumerateArray().FirstOrDefault();
                            if (firstPart.TryGetProperty("text", out var textElement))
                            {
                                aiText = textElement.GetString() ?? string.Empty;
                                _logger.LogInformation("Successfully extracted text: {Length} characters", aiText.Length);
                            }
                        }
                    }
                }
            }

            // 檢查是否有安全過濾
            if (root.TryGetProperty("promptFeedback", out var feedbackElement))
            {
                _logger.LogWarning("Gemini prompt feedback received: {Feedback}", feedbackElement.ToString());
            }

            _logger.LogInformation("Gemini API returned: {ResponseLength} characters", aiText.Length);
            if (!string.IsNullOrEmpty(aiText))
            {
                _logger.LogInformation("AI text preview: {Preview}", aiText.Substring(0, Math.Min(200, aiText.Length)));
            }

            // 如果沒有獲取到文本且有安全過濾回饋，返回友好訊息
            if (string.IsNullOrWhiteSpace(aiText) && root.TryGetProperty("promptFeedback", out _))
            {
                return "The content analysis is temporarily unavailable due to safety filtering. Please try with different content.";
            }

            return aiText;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Gemini API call failed");
            throw;
        }
    }

    public async Task<string> GenerateImageDescriptionAsync(Flashcard flashcard, GenerationOptionsDto options)
    {
        try
        {
            _logger.LogInformation("Starting image description generation for flashcard {FlashcardId}", flashcard.Id);

            var prompt = BuildImageDescriptionPrompt(flashcard, options);
            var response = await CallGeminiAPI(prompt);

            if (string.IsNullOrWhiteSpace(response))
            {
                throw new InvalidOperationException("Gemini API returned empty response");
            }

            var description = ExtractImageDescription(response);
            var optimizedPrompt = OptimizeForReplicate(description, options);

            _logger.LogInformation("Image description generated successfully for flashcard {FlashcardId}", flashcard.Id);

            return optimizedPrompt;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Image description generation failed for flashcard {FlashcardId}", flashcard.Id);
            throw;
        }
    }

    private string BuildImageDescriptionPrompt(Flashcard flashcard, GenerationOptionsDto options)
    {
        return $@"# 總覽
你是一位專業插畫設計師兼職英文老師，專門為英語學習教材製作插畫圖卡，用來幫助學生理解英文例句的意思。

# 例句資訊
例句：{flashcard.Example}

# SOP
1. 根據上述英文例句，請撰寫一段圖像描述提示詞，用於提供圖片生成AI作為生成圖片的提示詞
2. 請將下方「風格指南」的所有要求加入提示詞中
3. 並於圖片提示詞最後加上：「Absolutely no visible text, characters, letters, numbers, symbols, handwriting, labels, or any form of writing anywhere in the image — including on signs, books, clothing, screens, or backgrounds.」

# 圖片提示詞規範

## 情境清楚
1. 角色描述具體清楚
2. 動作明確具象
3. 場景明確具體
4. 物品明確具體
5. 語意需與原句一致
6. 避免過於抽象或象徵性符號

## 風格指南
- 風格類型：扁平插畫（Flat Illustration）
- 線條特徵：無描邊線條（outline-less）
- 色調：暖色調、柔和、低飽和
- 人物樣式：簡化卡通人物，表情自然，不誇張
- 背景構成：圖形簡化，使用色塊區分層次
- 整體氛圍：溫馨、平靜、適合教育情境
- 技術風格：無紋理、無漸層、無光影寫實感

請根據以上規範，為這個英文例句生成圖片描述提示詞，並確保完全符合風格指南要求。";
    }

    private string ExtractImageDescription(string geminiResponse)
    {
        // 從 Gemini 回應中提取圖片描述
        var description = geminiResponse.Trim();

        // 移除可能的 markdown 標記
        if (description.StartsWith("```"))
        {
            var lines = description.Split('\n');
            description = string.Join('\n', lines.Skip(1).SkipLast(1));
        }

        return description.Trim();
    }

    private string OptimizeForReplicate(string description, GenerationOptionsDto options)
    {
        var optimizedPrompt = description;

        // 確保包含扁平插畫風格要求
        if (!optimizedPrompt.Contains("flat illustration"))
        {
            optimizedPrompt += ". Style guide: flat illustration style, outline-less shapes, warm and soft color tones, low saturation, cartoon-style characters with natural expressions, simplified background with color blocks, cozy and educational atmosphere, no texture, no gradients, no photorealism, no fantasy elements.";
        }

        // 強制加入禁止文字的規則
        if (!optimizedPrompt.Contains("Absolutely no visible text"))
        {
            optimizedPrompt += " Absolutely no visible text, characters, letters, numbers, symbols, handwriting, labels, or any form of writing anywhere in the image — including on signs, books, clothing, screens, or backgrounds.";
        }

        return optimizedPrompt;
    }
}

// Gemini API response models
internal class GeminiApiResponse
{
    public List<GeminiCandidate>? Candidates { get; set; }
    public object? PromptFeedback { get; set; }
}

internal class GeminiCandidate
{
    public GeminiContent? Content { get; set; }
}

internal class GeminiContent
{
    public List<GeminiPart>? Parts { get; set; }
}

internal class GeminiPart
{
    public string? Text { get; set; }
}

// AI Response JSON Models
internal class AiAnalysisResponse
{
    public string? SentenceTranslation { get; set; }
    public bool HasGrammarErrors { get; set; }
    public List<AiGrammarCorrection>? GrammarCorrections { get; set; }
    public Dictionary<string, AiVocabularyAnalysis>? VocabularyAnalysis { get; set; }
    public List<AiIdiom>? Idioms { get; set; }
}

internal class AiGrammarCorrection
{
    public string? Original { get; set; }
    public string? Corrected { get; set; }
    public string? Type { get; set; }
    public string? Explanation { get; set; }
}

internal class AiVocabularyAnalysis
{
    public string? Word { get; set; }
    public string? Translation { get; set; }
    public string? Definition { get; set; }
    public string? PartOfSpeech { get; set; }
    public string? Pronunciation { get; set; }
    public string? DifficultyLevel { get; set; }
    public string? Frequency { get; set; }
    public List<string>? Synonyms { get; set; }
    public string? Example { get; set; }
    public string? ExampleTranslation { get; set; }
}

internal class AiIdiom
{
    public string? Idiom { get; set; }
    public string? Translation { get; set; }
    public string? Definition { get; set; }
    public string? Pronunciation { get; set; }
    public string? DifficultyLevel { get; set; }
    public string? Frequency { get; set; }
    public List<string>? Synonyms { get; set; }
    public string? Example { get; set; }
    public string? ExampleTranslation { get; set; }
}