using System.Text.Json;
using System.Text;
using DramaLing.Api.Models.Entities;

namespace DramaLing.Api.Services;

public interface IGeminiService
{
    Task<List<GeneratedCard>> GenerateCardsAsync(string inputText, string extractionType, int cardCount);
    Task<ValidationResult> ValidateCardAsync(Flashcard card);
    Task<SentenceAnalysisResponse> AnalyzeSentenceAsync(string inputText, string userLevel = "A2");
    Task<WordAnalysisResult> AnalyzeWordAsync(string word, string sentence);
}

public class GeminiService : IGeminiService
{
    private readonly HttpClient _httpClient;
    private readonly IConfiguration _configuration;
    private readonly ILogger<GeminiService> _logger;
    private readonly string _apiKey;

    public GeminiService(HttpClient httpClient, IConfiguration configuration, ILogger<GeminiService> logger)
    {
        _httpClient = httpClient;
        _configuration = configuration;
        _logger = logger;
        _apiKey = Environment.GetEnvironmentVariable("DRAMALING_GEMINI_API_KEY")
            ?? _configuration["AI:GeminiApiKey"] ?? "";
    }

    public async Task<List<GeneratedCard>> GenerateCardsAsync(string inputText, string extractionType, int cardCount)
    {
        try
        {
            if (string.IsNullOrEmpty(_apiKey) || _apiKey == "your-gemini-api-key-here")
            {
                throw new InvalidOperationException("Gemini API key not configured");
            }

            var prompt = BuildPrompt(inputText, extractionType, cardCount);
            var response = await CallGeminiApiAsync(prompt);

            return ParseGeneratedCards(response);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error generating cards with Gemini API");
            throw;
        }
    }

    /// <summary>
    /// 真正的句子分析和翻譯 - 調用 Gemini AI
    /// </summary>
    public async Task<SentenceAnalysisResponse> AnalyzeSentenceAsync(string inputText, string userLevel = "A2")
    {
        try
        {
            if (string.IsNullOrEmpty(_apiKey) || _apiKey == "your-gemini-api-key-here")
            {
                throw new InvalidOperationException("Gemini API key not configured");
            }

            var targetRange = CEFRLevelService.GetTargetLevelRange(userLevel);

            var prompt = $@"
請分析以下英文句子，提供翻譯和個人化詞彙分析：

句子：{inputText}
學習者程度：{userLevel}

請按照以下JSON格式回應，不要包含任何其他文字：

{{
  ""translation"": ""自然流暢的繁體中文翻譯"",
  ""grammarCorrection"": {{
    ""hasErrors"": false,
    ""originalText"": ""{inputText}"",
    ""correctedText"": null,
    ""corrections"": []
  }},
  ""highValueWords"": [""重要詞彙1"", ""重要詞彙2""],
  ""wordAnalysis"": {{
    ""單字"": {{
      ""translation"": ""中文翻譯"",
      ""definition"": ""英文定義"",
      ""partOfSpeech"": ""詞性"",
      ""pronunciation"": ""音標"",
      ""isHighValue"": true,
      ""difficultyLevel"": ""CEFR等級""
    }}
  }}
}}

要求：
1. 翻譯要自然流暢，符合中文語法
2. **基於學習者程度({userLevel})，標記 {targetRange} 等級的詞彙為重點學習**
3. 如有語法錯誤請指出並修正
4. 確保JSON格式正確

重點學習判定邏輯：
- 學習者程度: {userLevel}
- 重點學習範圍: {targetRange}
- 太簡單的詞彙(≤{userLevel})不要標記為重點學習
- 太難的詞彙謹慎標記
- 重點關注適合學習者程度的詞彙
";

            var response = await CallGeminiApiAsync(prompt);
            return ParseSentenceAnalysisResponse(response);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error analyzing sentence with Gemini API");
            throw;
        }
    }

    public async Task<WordAnalysisResult> AnalyzeWordAsync(string word, string sentence)
    {
        try
        {
            if (string.IsNullOrEmpty(_apiKey) || _apiKey == "your-gemini-api-key-here")
            {
                throw new InvalidOperationException("Gemini API key not configured");
            }

            var prompt = $@"
請分析單字 ""{word}"" 在句子 ""{sentence}"" 中的詳細資訊：

單字: {word}
語境: {sentence}

請以JSON格式回應，不要包含任何其他文字：
{{
  ""word"": ""{word}"",
  ""translation"": ""繁體中文翻譯"",
  ""definition"": ""英文定義"",
  ""partOfSpeech"": ""詞性(n./v./adj./adv.等)"",
  ""pronunciation"": ""IPA音標"",
  ""difficultyLevel"": ""CEFR等級(A1/A2/B1/B2/C1/C2)"",
  ""isHighValue"": false,
  ""contextMeaning"": ""在此句子中的具體含義""
}}

要求：
1. 翻譯要準確自然
2. 定義要簡潔易懂
3. 音標使用標準IPA格式
4. 根據語境判斷詞性和含義
";

            var response = await CallGeminiApiAsync(prompt);
            return ParseWordAnalysisResponse(response, word);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error analyzing word with Gemini API");

            // 回退到基本資料
            return new WordAnalysisResult
            {
                Word = word,
                Translation = $"{word} (AI 暫時不可用)",
                Definition = $"Definition of {word} (service temporarily unavailable)",
                PartOfSpeech = "unknown",
                Pronunciation = $"/{word}/",
                DifficultyLevel = "unknown",
                IsHighValue = false
            };
        }
    }

    public async Task<ValidationResult> ValidateCardAsync(Flashcard card)
    {
        try
        {
            if (string.IsNullOrEmpty(_apiKey) || _apiKey == "your-gemini-api-key-here")
            {
                throw new InvalidOperationException("Gemini API key not configured");
            }

            var prompt = BuildValidationPrompt(card);
            var response = await CallGeminiApiAsync(prompt);

            return ParseValidationResult(response);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error validating card with Gemini API");
            throw;
        }
    }

    private string BuildPrompt(string inputText, string extractionType, int cardCount)
    {
        var template = extractionType == "vocabulary" ? VocabularyExtractionPrompt : SmartExtractionPrompt;

        return template
            .Replace("{cardCount}", cardCount.ToString())
            .Replace("{inputText}", inputText);
    }

    private string BuildValidationPrompt(Flashcard card)
    {
        return CardValidationPrompt
            .Replace("{word}", card.Word)
            .Replace("{translation}", card.Translation)
            .Replace("{definition}", card.Definition)
            .Replace("{partOfSpeech}", card.PartOfSpeech ?? "")
            .Replace("{pronunciation}", card.Pronunciation ?? "")
            .Replace("{example}", card.Example ?? "");
    }

    private async Task<string> CallGeminiApiAsync(string prompt)
    {
        var requestBody = new
        {
            contents = new[]
            {
                new
                {
                    parts = new[]
                    {
                        new { text = prompt }
                    }
                }
            }
        };

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

        var response = await _httpClient.PostAsync(
            $"https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash-latest:generateContent?key={_apiKey}",
            content);

        if (!response.IsSuccessStatusCode)
        {
            var errorContent = await response.Content.ReadAsStringAsync();
            _logger.LogError("Gemini API error: {StatusCode} - {Content}", response.StatusCode, errorContent);
            throw new HttpRequestException($"Gemini API request failed: {response.StatusCode}");
        }

        var responseContent = await response.Content.ReadAsStringAsync();
        var geminiResponse = JsonSerializer.Deserialize<JsonElement>(responseContent);

        if (geminiResponse.TryGetProperty("candidates", out var candidates) &&
            candidates.GetArrayLength() > 0 &&
            candidates[0].TryGetProperty("content", out var contentElement) &&
            contentElement.TryGetProperty("parts", out var parts) &&
            parts.GetArrayLength() > 0 &&
            parts[0].TryGetProperty("text", out var textElement))
        {
            return textElement.GetString() ?? "";
        }

        throw new InvalidOperationException("Invalid response format from Gemini API");
    }

    private List<GeneratedCard> ParseGeneratedCards(string response)
    {
        try
        {
            // 清理回應文本
            var cleanText = response.Trim();
            cleanText = cleanText.Replace("```json", "").Replace("```", "").Trim();

            // 如果不是以 { 開始，嘗試找到 JSON 部分
            if (!cleanText.StartsWith("{"))
            {
                var jsonStart = cleanText.IndexOf("{");
                if (jsonStart >= 0)
                {
                    cleanText = cleanText[jsonStart..];
                }
            }

            var jsonResponse = JsonSerializer.Deserialize<JsonElement>(cleanText);

            if (!jsonResponse.TryGetProperty("cards", out var cardsElement) || cardsElement.ValueKind != JsonValueKind.Array)
            {
                throw new InvalidOperationException("Response does not contain cards array");
            }

            var cards = new List<GeneratedCard>();
            foreach (var cardElement in cardsElement.EnumerateArray())
            {
                var card = new GeneratedCard
                {
                    Word = GetStringProperty(cardElement, "word"),
                    PartOfSpeech = GetStringProperty(cardElement, "part_of_speech"),
                    Pronunciation = GetStringProperty(cardElement, "pronunciation"),
                    Translation = GetStringProperty(cardElement, "translation"),
                    Definition = GetStringProperty(cardElement, "definition"),
                    Synonyms = GetArrayProperty(cardElement, "synonyms"),
                    Example = GetStringProperty(cardElement, "example"),
                    ExampleTranslation = GetStringProperty(cardElement, "example_translation"),
                    DifficultyLevel = GetStringProperty(cardElement, "difficulty_level")
                };

                if (!string.IsNullOrEmpty(card.Word) && !string.IsNullOrEmpty(card.Translation))
                {
                    cards.Add(card);
                }
            }

            return cards;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error parsing generated cards response: {Response}", response);
            throw new InvalidOperationException($"Failed to parse AI response: {ex.Message}");
        }
    }

    private ValidationResult ParseValidationResult(string response)
    {
        try
        {
            var cleanText = response.Trim().Replace("```json", "").Replace("```", "").Trim();
            var jsonResponse = JsonSerializer.Deserialize<JsonElement>(cleanText);

            var issues = new List<ValidationIssue>();
            if (jsonResponse.TryGetProperty("issues", out var issuesElement))
            {
                foreach (var issueElement in issuesElement.EnumerateArray())
                {
                    issues.Add(new ValidationIssue
                    {
                        Field = GetStringProperty(issueElement, "field"),
                        Original = GetStringProperty(issueElement, "original"),
                        Corrected = GetStringProperty(issueElement, "corrected"),
                        Reason = GetStringProperty(issueElement, "reason"),
                        Severity = GetStringProperty(issueElement, "severity")
                    });
                }
            }

            var suggestions = new List<string>();
            if (jsonResponse.TryGetProperty("suggestions", out var suggestionsElement))
            {
                foreach (var suggestion in suggestionsElement.EnumerateArray())
                {
                    suggestions.Add(suggestion.GetString() ?? "");
                }
            }

            return new ValidationResult
            {
                Issues = issues,
                Suggestions = suggestions,
                OverallScore = jsonResponse.TryGetProperty("overall_score", out var scoreElement)
                    ? scoreElement.GetInt32() : 85,
                Confidence = jsonResponse.TryGetProperty("confidence", out var confidenceElement)
                    ? confidenceElement.GetDouble() : 0.9
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error parsing validation result: {Response}", response);
            throw new InvalidOperationException($"Failed to parse validation response: {ex.Message}");
        }
    }

    /// <summary>
    /// 解析 Gemini AI 詞彙分析響應
    /// </summary>
    private WordAnalysisResult ParseWordAnalysisResponse(string response, string word)
    {
        try
        {
            var cleanText = response.Trim().Replace("```json", "").Replace("```", "").Trim();
            var jsonResponse = JsonSerializer.Deserialize<JsonElement>(cleanText);

            return new WordAnalysisResult
            {
                Word = GetStringProperty(jsonResponse, "word") ?? word,
                Translation = GetStringProperty(jsonResponse, "translation") ?? $"{word} 的翻譯",
                Definition = GetStringProperty(jsonResponse, "definition") ?? $"Definition of {word}",
                PartOfSpeech = GetStringProperty(jsonResponse, "partOfSpeech") ?? "unknown",
                Pronunciation = GetStringProperty(jsonResponse, "pronunciation") ?? $"/{word}/",
                DifficultyLevel = GetStringProperty(jsonResponse, "difficultyLevel") ?? "A1",
                IsHighValue = jsonResponse.TryGetProperty("isHighValue", out var isHighValueElement) && isHighValueElement.GetBoolean()
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to parse word analysis response");

            return new WordAnalysisResult
            {
                Word = word,
                Translation = $"{word} (解析失敗)",
                Definition = $"Definition of {word} (parsing failed)",
                PartOfSpeech = "unknown",
                Pronunciation = $"/{word}/",
                DifficultyLevel = "unknown",
                IsHighValue = false
            };
        }
    }

    /// <summary>
    /// 解析 Gemini AI 句子分析響應
    /// </summary>
    private SentenceAnalysisResponse ParseSentenceAnalysisResponse(string response)
    {
        try
        {
            var cleanText = response.Trim().Replace("```json", "").Replace("```", "").Trim();

            if (!cleanText.StartsWith("{"))
            {
                var jsonStart = cleanText.IndexOf("{");
                if (jsonStart >= 0)
                {
                    cleanText = cleanText[jsonStart..];
                }
            }

            var jsonResponse = JsonSerializer.Deserialize<JsonElement>(cleanText);

            return new SentenceAnalysisResponse
            {
                Translation = GetStringProperty(jsonResponse, "translation"),
                Explanation = GetStringProperty(jsonResponse, "explanation"),
                HighValueWords = GetArrayProperty(jsonResponse, "highValueWords"),
                WordAnalysis = ParseWordAnalysisFromJson(jsonResponse),
                GrammarCorrection = ParseGrammarCorrectionFromJson(jsonResponse)
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error parsing sentence analysis response: {Response}", response);
            throw new InvalidOperationException($"Failed to parse AI sentence analysis: {ex.Message}");
        }
    }

    private Dictionary<string, WordAnalysisResult> ParseWordAnalysisFromJson(JsonElement jsonResponse)
    {
        var result = new Dictionary<string, WordAnalysisResult>();

        if (jsonResponse.TryGetProperty("wordAnalysis", out var wordAnalysisElement))
        {
            foreach (var property in wordAnalysisElement.EnumerateObject())
            {
                var word = property.Name;
                var analysis = property.Value;

                result[word] = new WordAnalysisResult
                {
                    Word = word,
                    Translation = GetStringProperty(analysis, "translation"),
                    Definition = GetStringProperty(analysis, "definition"),
                    PartOfSpeech = GetStringProperty(analysis, "partOfSpeech"),
                    Pronunciation = GetStringProperty(analysis, "pronunciation"),
                    IsHighValue = analysis.TryGetProperty("isHighValue", out var isHighValueElement) && isHighValueElement.GetBoolean(),
                    DifficultyLevel = GetStringProperty(analysis, "difficultyLevel")
                };
            }
        }

        return result;
    }

    private GrammarCorrectionResult ParseGrammarCorrectionFromJson(JsonElement jsonResponse)
    {
        if (jsonResponse.TryGetProperty("grammarCorrection", out var grammarElement))
        {
            return new GrammarCorrectionResult
            {
                HasErrors = grammarElement.TryGetProperty("hasErrors", out var hasErrorsElement) && hasErrorsElement.GetBoolean(),
                OriginalText = GetStringProperty(grammarElement, "originalText"),
                CorrectedText = GetStringProperty(grammarElement, "correctedText"),
                Corrections = new List<GrammarCorrection>() // 簡化
            };
        }

        return new GrammarCorrectionResult
        {
            HasErrors = false,
            OriginalText = "",
            CorrectedText = null,
            Corrections = new List<GrammarCorrection>()
        };
    }

    private static string GetStringProperty(JsonElement element, string propertyName)
    {
        return element.TryGetProperty(propertyName, out var prop) ? prop.GetString() ?? "" : "";
    }

    private static List<string> GetArrayProperty(JsonElement element, string propertyName)
    {
        var result = new List<string>();
        if (element.TryGetProperty(propertyName, out var arrayElement) && arrayElement.ValueKind == JsonValueKind.Array)
        {
            foreach (var item in arrayElement.EnumerateArray())
            {
                result.Add(item.GetString() ?? "");
            }
        }
        return result;
    }

    // Prompt 模板
    private const string VocabularyExtractionPrompt = @"
從以下英文文本中萃取 {cardCount} 個最重要的詞彙，為每個詞彙生成詞卡資料。

輸入文本：
{inputText}

請按照以下 JSON 格式回應，不要包含任何其他文字或代碼塊標記：

{
  ""cards"": [
    {
      ""word"": ""單字原型"",
      ""part_of_speech"": ""詞性(n./v./adj./adv.等)"",
      ""pronunciation"": ""IPA音標"",
      ""translation"": ""繁體中文翻譯"",
      ""definition"": ""英文定義(保持A1-A2程度)"",
      ""synonyms"": [""同義詞1"", ""同義詞2""],
      ""example"": ""例句(使用原文中的句子或生成新句子)"",
      ""example_translation"": ""例句中文翻譯"",
      ""difficulty_level"": ""CEFR等級(A1/A2/B1/B2/C1/C2)""
    }
  ]
}

要求：
1. 選擇最有學習價值的詞彙
2. 定義要簡單易懂，適合英語學習者
3. 例句要實用且符合語境
4. 確保 JSON 格式正確
5. 同義詞最多2個，選擇常用的";

    private const string SmartExtractionPrompt = @"
分析以下英文文本，識別片語、俚語和常用表達，生成 {cardCount} 個學習卡片：

輸入文本：
{inputText}

重點關注：
1. 片語和俚語
2. 文化相關表達
3. 語境特定用法
4. 慣用語和搭配

請按照相同的 JSON 格式回應...";

    private const string CardValidationPrompt = @"
請檢查以下詞卡內容的準確性：

單字: {word}
翻譯: {translation}
定義: {definition}
詞性: {partOfSpeech}
發音: {pronunciation}
例句: {example}

請按照以下 JSON 格式回應：
{
  ""issues"": [],
  ""suggestions"": [],
  ""overall_score"": 85,
  ""confidence"": 0.9
}";
}

// 支援類型
public class GeneratedCard
{
    public string Word { get; set; } = string.Empty;
    public string PartOfSpeech { get; set; } = string.Empty;
    public string Pronunciation { get; set; } = string.Empty;
    public string Translation { get; set; } = string.Empty;
    public string Definition { get; set; } = string.Empty;
    public List<string> Synonyms { get; set; } = new();
    public string Example { get; set; } = string.Empty;
    public string ExampleTranslation { get; set; } = string.Empty;
    public string DifficultyLevel { get; set; } = string.Empty;
}

public class ValidationResult
{
    public List<ValidationIssue> Issues { get; set; } = new();
    public List<string> Suggestions { get; set; } = new();
    public int OverallScore { get; set; }
    public double Confidence { get; set; }
}

public class ValidationIssue
{
    public string Field { get; set; } = string.Empty;
    public string Original { get; set; } = string.Empty;
    public string Corrected { get; set; } = string.Empty;
    public string Reason { get; set; } = string.Empty;
    public string Severity { get; set; } = string.Empty;
}

// 新增句子分析相關類型
public class SentenceAnalysisResponse
{
    public string Translation { get; set; } = string.Empty;
    public string Explanation { get; set; } = string.Empty;
    public List<string> HighValueWords { get; set; } = new();
    public Dictionary<string, WordAnalysisResult> WordAnalysis { get; set; } = new();
    public GrammarCorrectionResult GrammarCorrection { get; set; } = new();
}

public class WordAnalysisResult
{
    public string Word { get; set; } = string.Empty;
    public string Translation { get; set; } = string.Empty;
    public string Definition { get; set; } = string.Empty;
    public string PartOfSpeech { get; set; } = string.Empty;
    public string Pronunciation { get; set; } = string.Empty;
    public bool IsHighValue { get; set; }
    public string DifficultyLevel { get; set; } = string.Empty;
}

public class GrammarCorrectionResult
{
    public bool HasErrors { get; set; }
    public string OriginalText { get; set; } = string.Empty;
    public string? CorrectedText { get; set; }
    public List<GrammarCorrection> Corrections { get; set; } = new();
}

public class GrammarCorrection
{
    public string ErrorType { get; set; } = string.Empty;
    public string Original { get; set; } = string.Empty;
    public string Corrected { get; set; } = string.Empty;
    public string Reason { get; set; } = string.Empty;
}