// Services/Implementation/AiAnalysisService.cs
using Azure;
using Azure.AI.TextAnalytics;
using Azure.AI.OpenAI;
using OpenAI.Chat;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Services.AIViewModel;
using Services.Interaces;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
using Data;
using Microsoft.EntityFrameworkCore;
using System.ClientModel;

namespace Services.Implemnetation
{
    public class AiAnalysisService : IAiAnalysisService, IDisposable
    {
        private readonly TextAnalyticsClient _textAnalyticsClient;
        private readonly AzureOpenAIClient _azureOpenAIClient;
        private readonly ChatClient _chatClient;
        private readonly IConfiguration _configuration;
        private readonly ILogger<AiAnalysisService> _logger;
        private readonly SurveyContext _context;
        private readonly string _openAIDeploymentName;
        private bool _disposed = false;

        public AiAnalysisService(
            IConfiguration configuration,
            ILogger<AiAnalysisService> logger,
            SurveyContext context)
        {
            _configuration = configuration;
            _logger = logger;
            _context = context;

            // Initialize Azure Language Service
            var languageEndpoint = _configuration["AzureLanguageService:Endpoint"];
            var languageKey = _configuration["AzureLanguageService:Key"];
            _textAnalyticsClient = new TextAnalyticsClient(new Uri(languageEndpoint), new AzureKeyCredential(languageKey));

            // Initialize Azure OpenAI
            var openAIEndpoint = _configuration["AzureOpenAI:Endpoint"];
            var openAIKey = _configuration["AzureOpenAI:Key"];
            _openAIDeploymentName = _configuration["AzureOpenAI:DeploymentName"];

            _azureOpenAIClient = new AzureOpenAIClient(new Uri(openAIEndpoint), new AzureKeyCredential(openAIKey));
            _chatClient = _azureOpenAIClient.GetChatClient(_openAIDeploymentName);

            _logger.LogInformation("AiAnalysisService initialized successfully");
        }

        #region Azure Language Service Methods

        public async Task<SentimentAnalysisResult> AnalyzeSentimentAsync(string text)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(text))
                {
                    return new SentimentAnalysisResult { Sentiment = "Neutral", ConfidenceScore = 0.0 };
                }

                var response = await _textAnalyticsClient.AnalyzeSentimentAsync(text);
                var sentiment = response.Value;

                return new SentimentAnalysisResult
                {
                    Sentiment = sentiment.Sentiment.ToString(),
                    ConfidenceScore = sentiment.ConfidenceScores.Positive > sentiment.ConfidenceScores.Negative
                        ? sentiment.ConfidenceScores.Positive
                        : sentiment.ConfidenceScores.Negative,
                    PositiveScore = sentiment.ConfidenceScores.Positive,
                    NegativeScore = sentiment.ConfidenceScores.Negative,
                    NeutralScore = sentiment.ConfidenceScores.Neutral,
                    AnalyzedAt = DateTime.UtcNow
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error analyzing sentiment for text: {Text}", text);
                throw;
            }
        }

        public async Task<KeyPhrasesResult> ExtractKeyPhrasesAsync(string text)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(text))
                {
                    return new KeyPhrasesResult();
                }

                var response = await _textAnalyticsClient.ExtractKeyPhrasesAsync(text);
                var keyPhrases = response.Value.ToList();

                // Mental health specific categorization
                var workplaceFactors = keyPhrases.Where(phrase =>
                    phrase.Contains("work") || phrase.Contains("manager") || phrase.Contains("team") ||
                    phrase.Contains("deadline") || phrase.Contains("pressure") || phrase.Contains("colleague") ||
                    phrase.Contains("office") || phrase.Contains("meeting") || phrase.Contains("project")).ToList();

                var emotionalIndicators = keyPhrases.Where(phrase =>
                    phrase.Contains("stress") || phrase.Contains("anxious") || phrase.Contains("tired") ||
                    phrase.Contains("overwhelmed") || phrase.Contains("frustrated") || phrase.Contains("happy") ||
                    phrase.Contains("satisfied") || phrase.Contains("motivated") || phrase.Contains("burned")).ToList();

                return new KeyPhrasesResult
                {
                    KeyPhrases = keyPhrases,
                    WorkplaceFactors = workplaceFactors,
                    EmotionalIndicators = emotionalIndicators,
                    ExtractedAt = DateTime.UtcNow
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error extracting key phrases for text: {Text}", text);
                throw;
            }
        }

        public async Task<string> AnonymizeTextAsync(string text)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(text))
                {
                    return string.Empty;
                }

                var response = await _textAnalyticsClient.RecognizePiiEntitiesAsync(text);
                var piiEntities = response.Value;

                string anonymizedText = text;
                foreach (var entity in piiEntities.OrderByDescending(e => e.Offset))
                {
                    var replacement = entity.Category.ToString() switch
                    {
                        "Person" => "[NAME]",
                        "Email" => "[EMAIL]",
                        "PhoneNumber" => "[PHONE]",
                        "Address" => "[ADDRESS]",
                        _ => "[REDACTED]"
                    };

                    anonymizedText = anonymizedText.Remove(entity.Offset, entity.Length)
                        .Insert(entity.Offset, replacement);
                }

                return anonymizedText;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error anonymizing text: {Text}", text);
                return text; // Return original text if anonymization fails
            }
        }

        public async Task<List<string>> DetectEntitiesAsync(string text)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(text))
                {
                    return new List<string>();
                }

                var response = await _textAnalyticsClient.RecognizeEntitiesAsync(text);
                var entities = response.Value;

                return entities.Select(entity => $"{entity.Category}: {entity.Text}").ToList();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error detecting entities for text: {Text}", text);
                throw;
            }
        }

        #endregion

        #region Azure OpenAI Methods

        public async Task<MentalHealthRiskAssessment> AssessMentalHealthRiskAsync(string anonymizedText, string questionContext)
        {
            try
            {
                var prompt = $@"
As a mental health professional, analyze this workplace survey response and assess the mental health risk level.

Question Context: {questionContext}
Response: {anonymizedText}

Please provide:
1. Risk Level (Low, Moderate, High, Critical)
2. Risk Score (0.0 to 1.0)
3. Risk Indicators (specific concerns found)
4. Protective Factors (positive elements found)
5. Requires Immediate Attention (true/false)
6. Recommended Action

Respond in this JSON format:
{{
    ""riskLevel"": ""Low"",
    ""riskScore"": 0.0,
    ""riskIndicators"": [""indicator1"", ""indicator2""],
    ""protectiveFactors"": [""factor1"", ""factor2""],
    ""requiresImmediateAttention"": false,
    ""recommendedAction"": ""specific action recommendation""
}}";

                var messages = new List<ChatMessage>
                {
                    new SystemChatMessage("You are a mental health professional specialized in workplace wellness. Always respond with a single valid JSON object only. No markdown, no explanations."),
                    new UserChatMessage(prompt)
                };

                var chatOptions = new ChatCompletionOptions()
                {
                    Temperature = 0.3f
                };

                var response = await _chatClient.CompleteChatAsync(messages, chatOptions);
                var content = response.Value.Content[0].Text;

                _logger.LogInformation("OpenAI Response: {Content}", content);

                // Parse more defensively
                var jsonDoc = ParseLenient(content, out var parseErr);
                if (jsonDoc == null)
                {
                    _logger.LogWarning("Failed to parse JSON response from OpenAI: {Err}. Raw (first 800): {Raw}",
                        parseErr, content?.Length > 800 ? content[..800] : content);

                    return new MentalHealthRiskAssessment
                    {
                        RiskLevel = RiskLevel.Moderate,
                        RiskScore = 0.5,
                        RiskIndicators = new List<string> { "Unable to parse AI response" },
                        ProtectiveFactors = new List<string>(),
                        RequiresImmediateAttention = false,
                        RecommendedAction = "Manual review recommended due to analysis error",
                        AssessedAt = DateTime.UtcNow
                    };
                }

                var root = jsonDoc.RootElement;

                return new MentalHealthRiskAssessment
                {
                    RiskLevel = Enum.TryParse<RiskLevel>(root.TryGetProperty("riskLevel", out var rl) ? (rl.GetString() ?? "Low") : "Low", out var riskLevel)
                        ? riskLevel : RiskLevel.Low,
                    RiskScore = root.TryGetProperty("riskScore", out var scoreProperty)
                        ? TryGetDoubleFlexible(scoreProperty, out var d) ? d : 0.0
                        : 0.0,
                    RiskIndicators = root.TryGetProperty("riskIndicators", out var indicatorsProperty)
                        ? indicatorsProperty.EnumerateArray().Select(x => x.GetString() ?? "").Where(s => !string.IsNullOrEmpty(s)).ToList()
                        : new List<string>(),
                    ProtectiveFactors = root.TryGetProperty("protectiveFactors", out var factorsProperty)
                        ? factorsProperty.EnumerateArray().Select(x => x.GetString() ?? "").Where(s => !string.IsNullOrEmpty(s)).ToList()
                        : new List<string>(),
                    RequiresImmediateAttention = root.TryGetProperty("requiresImmediateAttention", out var attentionProperty) &&
                                                TryGetBoolFlexible(attentionProperty, out var b) && b,
                    RecommendedAction = root.TryGetProperty("recommendedAction", out var actionProperty) ? (actionProperty.GetString() ?? "") : "",
                    AssessedAt = DateTime.UtcNow
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error assessing mental health risk for text: {Text}", anonymizedText);

                // Return a safe default assessment instead of throwing
                return new MentalHealthRiskAssessment
                {
                    RiskLevel = RiskLevel.Moderate,
                    RiskScore = 0.5,
                    RiskIndicators = new List<string> { $"Analysis error: {ex.Message}" },
                    ProtectiveFactors = new List<string>(),
                    RequiresImmediateAttention = false,
                    RecommendedAction = "Manual review recommended due to system error",
                    AssessedAt = DateTime.UtcNow
                };
            }
        }

        public async Task<List<WorkplaceInsight>> GenerateWorkplaceInsightsAsync(string anonymizedText, string questionContext)
        {
            try
            {
                var prompt = $@"
Analyze this workplace survey response and identify specific workplace insights and intervention recommendations.

Question Context: {questionContext}
Response: {anonymizedText}

Identify workplace issues and provide specific, actionable intervention recommendations. Focus on:
- Work-life balance issues
- Management/leadership concerns
- Team dynamics problems
- Workload and stress factors
- Communication issues
- Organizational culture problems

Respond in this JSON format:
{{
  ""insights"": [
    {{
      ""category"": ""category name"",
      ""issue"": ""specific issue identified"",
      ""recommendedIntervention"": ""specific action to take"",
      ""priority"": 1,
      ""affectedAreas"": [""area1"", ""area2""]
    }}
  ]
}}";

                var messages = new List<ChatMessage>
                {
                    new SystemChatMessage("You are a workplace mental health consultant. Always respond with a SINGLE valid JSON object ONLY. No markdown, no code fences, no explanations."),
                    new UserChatMessage(prompt)
                };

                var chatOptions = new ChatCompletionOptions()
                {
                    Temperature = 0.4f
                };

                var response = await _chatClient.CompleteChatAsync(messages, chatOptions);
                var content = response.Value.Content[0].Text;

                var jsonDoc = ParseLenient(content, out var parseErr);
                if (jsonDoc == null)
                {
                    _logger.LogWarning("Insights JSON parse failed: {Err}. Raw (first 800): {Raw}",
                        parseErr, content?.Length > 800 ? content[..800] : content);

                    // Fail soft (avoid crashing controller)
                    return new List<WorkplaceInsight>();
                }

                var root = jsonDoc.RootElement;

                if (!root.TryGetProperty("insights", out var insightsElement) || insightsElement.ValueKind != JsonValueKind.Array)
                {
                    // No insights array — return empty rather than throw
                    return new List<WorkplaceInsight>();
                }

                var workplaceInsights = new List<WorkplaceInsight>();

                foreach (var insight in insightsElement.EnumerateArray())
                {
                    // Be defensive with each field
                    string category = insight.TryGetProperty("category", out var cat) ? (cat.GetString() ?? "") : "";
                    string issue = insight.TryGetProperty("issue", out var iss) ? (iss.GetString() ?? "") : "";
                    string recommended = insight.TryGetProperty("recommendedIntervention", out var rec) ? (rec.GetString() ?? "") : "";
                    int priority = 3;
                    if (insight.TryGetProperty("priority", out var pr))
                    {
                        if (pr.ValueKind == JsonValueKind.Number && pr.TryGetInt32(out var pInt)) priority = pInt;
                        else if (pr.ValueKind == JsonValueKind.String && int.TryParse(pr.GetString(), out var pStr)) priority = pStr;
                    }
                    var affectedAreas = new List<string>();
                    if (insight.TryGetProperty("affectedAreas", out var aa) && aa.ValueKind == JsonValueKind.Array)
                    {
                        affectedAreas = aa.EnumerateArray().Select(x => x.GetString() ?? "").Where(s => !string.IsNullOrWhiteSpace(s)).ToList();
                    }

                    workplaceInsights.Add(new WorkplaceInsight
                    {
                        Category = category,
                        Issue = issue,
                        RecommendedIntervention = recommended,
                        Priority = priority,
                        AffectedAreas = affectedAreas,
                        IdentifiedAt = DateTime.UtcNow
                    });
                }

                return workplaceInsights;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error generating workplace insights for text: {Text}", anonymizedText);
                // Fail soft to prevent controller crash
                return new List<WorkplaceInsight>();
            }
        }

        public async Task<string> GenerateExecutiveSummaryAsync(List<ResponseAnalysisResult> analysisResults)
        {
            try
            {
                var totalResponses = analysisResults.Count;
                var highRiskCount = analysisResults.Count(r => r.RiskAssessment?.RiskLevel >= RiskLevel.High);
                var positiveResponses = analysisResults.Count(r => r.SentimentAnalysis?.Sentiment == "Positive");

                var commonIssues = analysisResults
                    .SelectMany(r => r.Insights)
                    .GroupBy(i => i.Category)
                    .OrderByDescending(g => g.Count())
                    .Take(5)
                    .Select(g => $"{g.Key}: {g.Count()} instances")
                    .ToList();

                var prompt = $@"
Create an executive summary for a workplace mental health survey analysis.

Survey Statistics:
- Total Responses: {totalResponses}
- High Risk Responses: {highRiskCount}
- Positive Responses: {positiveResponses}
- Most Common Issues: {string.Join(", ", commonIssues)}

Create a comprehensive executive summary that includes:
1. Overall mental health status
2. Key findings and trends
3. Areas of concern
4. Positive indicators
5. Immediate action items
6. Long-term recommendations

Keep it professional, actionable, and suitable for senior management.";

                var messages = new List<ChatMessage>
                {
                    new SystemChatMessage("You are an executive consultant specializing in workplace mental health reporting."),
                    new UserChatMessage(prompt)
                };

                var chatOptions = new ChatCompletionOptions()
                {
                    Temperature = 0.3f
                };

                var response = await _chatClient.CompleteChatAsync(messages, chatOptions);
                return response.Value.Content[0].Text;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error generating executive summary");
                throw;
            }
        }

        public async Task<List<string>> CategorizeResponseAsync(string anonymizedText)
        {
            try
            {
                var prompt = $@"
Categorize this workplace mental health survey response into relevant themes.

Response: {anonymizedText}

Choose from these categories (select all that apply):
- Work-Life Balance
- Workload Management
- Team Dynamics
- Leadership/Management
- Communication Issues
- Job Satisfaction
- Stress Management
- Career Development
- Work Environment
- Organizational Culture
- Mental Health Support
- Burnout Prevention

Respond with a JSON array of applicable categories: [""category1"", ""category2""]";

                var messages = new List<ChatMessage>
                {
                    new SystemChatMessage("You are a mental health professional categorizing workplace responses. Always respond with a JSON array only."),
                    new UserChatMessage(prompt)
                };

                var chatOptions = new ChatCompletionOptions()
                {
                    Temperature = 0.2f
                };

                var response = await _chatClient.CompleteChatAsync(messages, chatOptions);
                var content = response.Value.Content[0].Text;

                // lenient array parse
                var categories = DeserializeLenient<List<string>>(content, out var err) ?? new List<string>();
                if (!string.IsNullOrEmpty(err))
                {
                    _logger.LogWarning("Category JSON parse failed: {Err}. Raw (first 800): {Raw}",
                        err, content?.Length > 800 ? content[..800] : content);
                }

                return categories;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error categorizing response: {Text}", anonymizedText);
                throw;
            }
        }

        #endregion

        #region Combined Analysis Methods

        public async Task<ResponseAnalysisResult> AnalyzeCompleteResponseAsync(AnalysisRequest request)
        {
            try
            {
                var result = new ResponseAnalysisResult
                {
                    ResponseId = request.ResponseId,
                    QuestionId = request.QuestionId,
                    QuestionText = request.QuestionText,
                    ResponseText = request.ResponseText,
                    AnalyzedAt = DateTime.UtcNow
                };

                // Step 1: Anonymize the text
                result.AnonymizedResponseText = await AnonymizeTextAsync(request.ResponseText);

                // Step 2: Azure Language Service Analysis
                if (request.IncludeSentimentAnalysis)
                {
                    result.SentimentAnalysis = await AnalyzeSentimentAsync(result.AnonymizedResponseText);
                }

                if (request.IncludeKeyPhraseExtraction)
                {
                    result.KeyPhrases = await ExtractKeyPhrasesAsync(result.AnonymizedResponseText);
                }

                // Step 3: Azure OpenAI Analysis
                if (request.IncludeRiskAssessment)
                {
                    result.RiskAssessment = await AssessMentalHealthRiskAsync(result.AnonymizedResponseText, request.QuestionText);
                }

                if (request.IncludeWorkplaceInsights)
                {
                    result.Insights = await GenerateWorkplaceInsightsAsync(result.AnonymizedResponseText, request.QuestionText);
                }

                result.IsAnalysisComplete = true;
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error in complete response analysis for ResponseId: {ResponseId}", request.ResponseId);
                throw;
            }
        }

        public async Task<List<ResponseAnalysisResult>> AnalyzeQuestionResponsesAsync(int questionId, List<AnalysisRequest> requests)
        {
            var results = new List<ResponseAnalysisResult>();

            foreach (var request in requests)
            {
                try
                {
                    var result = await AnalyzeCompleteResponseAsync(request);
                    results.Add(result);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "Error analyzing response {ResponseId} for question {QuestionId}", request.ResponseId, questionId);
                    // Continue with other responses even if one fails
                }
            }

            return results;
        }

        public async Task<QuestionnaireAnalysisOverview> GenerateQuestionnaireOverviewAsync(int questionnaireId)
        {
            try
            {
                // Get all responses for this questionnaire
                var responses = await _context.Responses
                    .Include(r => r.Questionnaire)
                    .Include(r => r.ResponseDetails)
                    .ThenInclude(rd => rd.Question)
                    .Where(r => r.QuestionnaireId == questionnaireId)
                    .ToListAsync();

                if (!responses.Any())
                {
                    return new QuestionnaireAnalysisOverview
                    {
                        QuestionnaireId = questionnaireId,
                        QuestionnaireTitle = "No responses found",
                        TotalResponses = 0
                    };
                }

                // Analyze text responses
                var analysisResults = new List<ResponseAnalysisResult>();
                foreach (var response in responses)
                {
                    foreach (var detail in response.ResponseDetails)
                    {
                        if (!string.IsNullOrWhiteSpace(detail.TextResponse))
                        {
                            var request = new AnalysisRequest
                            {
                                ResponseId = response.Id,
                                QuestionId = detail.QuestionId,
                                ResponseText = detail.TextResponse,
                                QuestionText = detail.Question?.Text ?? ""
                            };

                            var analysisResult = await AnalyzeCompleteResponseAsync(request);
                            analysisResults.Add(analysisResult);
                        }
                    }
                }

                // Generate overview
                var overview = new QuestionnaireAnalysisOverview
                {
                    QuestionnaireId = questionnaireId,
                    QuestionnaireTitle = responses.First().Questionnaire?.Title ?? "Unknown",
                    TotalResponses = responses.Count,
                    AnalyzedResponses = analysisResults.Count,
                    LastAnalyzedAt = DateTime.UtcNow
                };

                if (analysisResults.Any())
                {
                    // Calculate sentiment distribution
                    var sentimentResults = analysisResults.Where(r => r.SentimentAnalysis != null).ToList();
                    if (sentimentResults.Any())
                    {
                        overview.OverallPositiveSentiment = sentimentResults.Average(r => r.SentimentAnalysis!.PositiveScore);
                        overview.OverallNegativeSentiment = sentimentResults.Average(r => r.SentimentAnalysis!.NegativeScore);
                        overview.OverallNeutralSentiment = sentimentResults.Average(r => r.SentimentAnalysis!.NeutralScore);
                    }

                    // Calculate risk distribution
                    var riskResults = analysisResults.Where(r => r.RiskAssessment != null).ToList();
                    if (riskResults.Any())
                    {
                        overview.LowRiskResponses = riskResults.Count(r => r.RiskAssessment!.RiskLevel == RiskLevel.Low);
                        overview.ModerateRiskResponses = riskResults.Count(r => r.RiskAssessment!.RiskLevel == RiskLevel.Moderate);
                        overview.HighRiskResponses = riskResults.Count(r => r.RiskAssessment!.RiskLevel == RiskLevel.High);
                        overview.CriticalRiskResponses = riskResults.Count(r => r.RiskAssessment!.RiskLevel == RiskLevel.Critical);
                    }

                    // Get top workplace issues
                    overview.TopWorkplaceIssues = analysisResults
                        .SelectMany(r => r.Insights)
                        .GroupBy(i => i.Category)
                        .OrderByDescending(g => g.Count())
                        .Take(5)
                        .Select(g => g.First())
                        .ToList();

                    // Get common key phrases
                    overview.MostCommonKeyPhrases = analysisResults
                        .Where(r => r.KeyPhrases != null)
                        .SelectMany(r => r.KeyPhrases!.KeyPhrases)
                        .GroupBy(k => k)
                        .OrderByDescending(g => g.Count())
                        .Take(10)
                        .Select(g => g.Key)
                        .ToList();

                    // Generate executive summary
                    overview.ExecutiveSummary = await GenerateExecutiveSummaryAsync(analysisResults);
                }

                return overview;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error generating questionnaire overview for QuestionnaireId: {QuestionnaireId}", questionnaireId);
                throw;
            }
        }

        public async Task<List<ResponseAnalysisResult>> BatchAnalyzeResponsesAsync(List<AnalysisRequest> requests)
        {
            var results = new List<ResponseAnalysisResult>();
            var tasks = new List<Task<ResponseAnalysisResult>>();

            // Process in batches to avoid overwhelming the API
            const int batchSize = 5;
            for (int i = 0; i < requests.Count; i += batchSize)
            {
                var batch = requests.Skip(i).Take(batchSize);
                foreach (var request in batch)
                {
                    tasks.Add(AnalyzeCompleteResponseAsync(request));
                }

                // Wait for current batch to complete before starting next
                var batchResults = await Task.WhenAll(tasks);
                results.AddRange(batchResults);
                tasks.Clear();

                // Small delay between batches to respect API limits
                await Task.Delay(1000);
            }

            return results;
        }

        #endregion

        #region Mental Health Specific Methods

        public async Task<List<ResponseAnalysisResult>> IdentifyHighRiskResponsesAsync(int questionnaireId)
        {
            try
            {
                var overview = await GenerateQuestionnaireOverviewAsync(questionnaireId);
                var allResults = await ExportAnonymizedAnalysisAsync(questionnaireId);

                return allResults
                    .Where(r => r.RiskAssessment != null &&
                           (r.RiskAssessment.RiskLevel >= RiskLevel.High || r.RiskAssessment.RequiresImmediateAttention))
                    .OrderByDescending(r => r.RiskAssessment!.RiskScore)
                    .ToList();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error identifying high risk responses for QuestionnaireId: {QuestionnaireId}", questionnaireId);
                throw;
            }
        }

        public async Task<List<WorkplaceInsight>> AnalyzeMentalHealthTrendsAsync(int questionnaireId, DateTime fromDate, DateTime toDate)
        {
            try
            {
                var responses = await _context.Responses
                    .Include(r => r.ResponseDetails)
                    .ThenInclude(rd => rd.Question)
                    .Where(r => r.QuestionnaireId == questionnaireId &&
                               r.SubmissionDate >= fromDate &&
                               r.SubmissionDate <= toDate)
                    .OrderBy(r => r.SubmissionDate)
                    .ToListAsync();

                // This would typically involve more complex trend analysis
                // For now, return general insights
                var insights = new List<WorkplaceInsight>
                {
                    new WorkplaceInsight
                    {
                        Category = "Trend Analysis",
                        Issue = $"Analysis of {responses.Count} responses from {fromDate:yyyy-MM-dd} to {toDate:yyyy-MM-dd}",
                        RecommendedIntervention = "Regular monitoring and follow-up assessments recommended",
                        Priority = 3,
                        IdentifiedAt = DateTime.UtcNow
                    }
                };

                return insights;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error analyzing mental health trends for QuestionnaireId: {QuestionnaireId}", questionnaireId);
                throw;
            }
        }

        public async Task<Dictionary<string, QuestionnaireAnalysisOverview>> CompareTeamMentalHealthAsync(int questionnaireId, List<string> teamIdentifiers)
        {
            // This would require team identification in responses
            // For now, return a basic implementation
            var result = new Dictionary<string, QuestionnaireAnalysisOverview>();

            foreach (var team in teamIdentifiers)
            {
                result[team] = await GenerateQuestionnaireOverviewAsync(questionnaireId);
            }

            return result;
        }

        public async Task<List<WorkplaceInsight>> GenerateInterventionRecommendationsAsync(int questionnaireId)
        {
            try
            {
                var overview = await GenerateQuestionnaireOverviewAsync(questionnaireId);
                return overview.TopWorkplaceIssues;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error generating intervention recommendations for QuestionnaireId: {QuestionnaireId}", questionnaireId);
                throw;
            }
        }

        #endregion

        #region Reporting Methods

        public async Task<string> GenerateDetailedAnalysisReportAsync(int questionnaireId)
        {
            try
            {
                var overview = await GenerateQuestionnaireOverviewAsync(questionnaireId);
                var highRiskResponses = await IdentifyHighRiskResponsesAsync(questionnaireId);

                var report = new StringBuilder();
                report.AppendLine($"# Mental Health Analysis Report");
                report.AppendLine($"**Questionnaire:** {overview.QuestionnaireTitle}");
                report.AppendLine($"**Analysis Date:** {DateTime.Now:yyyy-MM-dd HH:mm}");
                report.AppendLine($"**Total Responses:** {overview.TotalResponses}");
                report.AppendLine($"**Analyzed Responses:** {overview.AnalyzedResponses}");
                report.AppendLine();

                report.AppendLine("## Executive Summary");
                report.AppendLine(overview.ExecutiveSummary);
                report.AppendLine();

                report.AppendLine("## Risk Distribution");
                report.AppendLine($"- Low Risk: {overview.LowRiskResponses}");
                report.AppendLine($"- Moderate Risk: {overview.ModerateRiskResponses}");
                report.AppendLine($"- High Risk: {overview.HighRiskResponses}");
                report.AppendLine($"- Critical Risk: {overview.CriticalRiskResponses}");
                report.AppendLine();

                if (highRiskResponses.Any())
                {
                    report.AppendLine("## High Risk Responses Requiring Attention");
                    report.AppendLine($"Found {highRiskResponses.Count} responses requiring immediate attention.");
                    report.AppendLine();
                }

                report.AppendLine("## Top Workplace Issues");
                foreach (var issue in overview.TopWorkplaceIssues.Take(5))
                {
                    report.AppendLine($"- **{issue.Category}:** {issue.Issue}");
                    report.AppendLine($"  - Recommended Action: {issue.RecommendedIntervention}");
                }

                return report.ToString();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error generating detailed analysis report for QuestionnaireId: {QuestionnaireId}", questionnaireId);
                throw;
            }
        }

        public async Task<List<ResponseAnalysisResult>> ExportAnonymizedAnalysisAsync(int questionnaireId)
        {
            try
            {
                var responses = await _context.Responses
                    .Include(r => r.ResponseDetails)
                    .ThenInclude(rd => rd.Question)
                    .Where(r => r.QuestionnaireId == questionnaireId)
                    .ToListAsync();

                var results = new List<ResponseAnalysisResult>();

                foreach (var response in responses)
                {
                    foreach (var detail in response.ResponseDetails)
                    {
                        if (!string.IsNullOrWhiteSpace(detail.TextResponse))
                        {
                            var request = new AnalysisRequest
                            {
                                ResponseId = response.Id,
                                QuestionId = detail.QuestionId,
                                ResponseText = detail.TextResponse,
                                QuestionText = detail.Question?.Text ?? ""
                            };

                            var result = await AnalyzeCompleteResponseAsync(request);
                            results.Add(result);
                        }
                    }
                }

                return results;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error exporting anonymized analysis for QuestionnaireId: {QuestionnaireId}", questionnaireId);
                throw;
            }
        }

        public async Task<QuestionnaireAnalysisOverview> GenerateManagementDashboardAsync(int questionnaireId)
        {
            return await GenerateQuestionnaireOverviewAsync(questionnaireId);
        }

        #endregion

        #region Utility Methods

        public async Task<bool> TestAzureLanguageServiceConnectionAsync()
        {
            try
            {
                await _textAnalyticsClient.AnalyzeSentimentAsync("Test connection");
                return true;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Azure Language Service connection test failed");
                return false;
            }
        }

        public async Task<bool> TestAzureOpenAIConnectionAsync()
        {
            try
            {
                var messages = new List<ChatMessage>
                {
                    new UserChatMessage("Test connection")
                };

                var chatOptions = new ChatCompletionOptions();

                await _chatClient.CompleteChatAsync(messages, chatOptions);
                return true;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Azure OpenAI connection test failed");
                return false;
            }
        }

        public Task<bool> ValidateAnalysisRequestAsync(AnalysisRequest request)
        {
            return Task.FromResult(!string.IsNullOrWhiteSpace(request.ResponseText) &&
                   request.ResponseId > 0 &&
                   request.QuestionId > 0);
        }

        public async Task<Dictionary<string, bool>> GetServiceHealthStatusAsync()
        {
            var status = new Dictionary<string, bool>();

            status["AzureLanguageService"] = await TestAzureLanguageServiceConnectionAsync();
            status["AzureOpenAI"] = await TestAzureOpenAIConnectionAsync();

            return status;
        }

        #endregion

        #region IDisposable

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    // Dispose managed resources
                    _context?.Dispose();
                }
                _disposed = true;
            }
        }

        #endregion

        #region Private JSON Helpers (no new models)

        private static readonly Regex JsonObjectRegex =
            new(@"(\{(?:[^{}]|(?<o>\{)|(?<-o>\}))*(?(o)(?!))\})",
                RegexOptions.Singleline | RegexOptions.Compiled);

        private static bool TryExtractJsonObject(string text, out string json)
        {
            json = text?.Trim() ?? "";

            // strip markdown code fences if present
            if (json.StartsWith("```"))
            {
                json = Regex.Replace(json, "^```(?:json)?\\s*|\\s*```$", "",
                                     RegexOptions.IgnoreCase | RegexOptions.Singleline).Trim();
            }

            if (json.StartsWith("{") && json.EndsWith("}"))
                return true;

            var m = JsonObjectRegex.Match(json);
            if (!m.Success) return false;

            json = m.Value;
            return true;
        }

        private static JsonDocument? ParseLenient(string content, out string? error)
        {
            error = null;

            if (!TryExtractJsonObject(content, out var jsonOnly))
            {
                error = "No JSON object found in model response.";
                return null;
            }

            var docOptions = new JsonDocumentOptions
            {
                AllowTrailingCommas = true,
                CommentHandling = JsonCommentHandling.Skip
            };

            try
            {
                return JsonDocument.Parse(jsonOnly, docOptions);
            }
            catch (Exception ex)
            {
                error = ex.Message;
                return null;
            }
        }

        private static T? DeserializeLenient<T>(string content, out string? error)
        {
            error = null;

            if (!TryExtractJsonObject(content, out var jsonOnly))
            {
                // also try plain array (for CategorizeResponseAsync)
                var trimmed = (content ?? "").Trim();
                if (typeof(T) == typeof(List<string>) && trimmed.StartsWith("[") && trimmed.EndsWith("]"))
                {
                    jsonOnly = trimmed;
                }
                else
                {
                    error = "No JSON object/array found in model response.";
                    return default;
                }
            }

            var options = new JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true,
                AllowTrailingCommas = true,
                NumberHandling = JsonNumberHandling.AllowReadingFromString
            };

            try
            {
                return JsonSerializer.Deserialize<T>(jsonOnly, options);
            }
            catch (Exception ex)
            {
                error = ex.Message;
                return default;
            }
        }

        private static bool TryGetDoubleFlexible(JsonElement el, out double value)
        {
            value = 0;
            if (el.ValueKind == JsonValueKind.Number) return el.TryGetDouble(out value);
            if (el.ValueKind == JsonValueKind.String) return double.TryParse(el.GetString(), out value);
            return false;
        }

        private static bool TryGetBoolFlexible(JsonElement el, out bool value)
        {
            value = false;
            if (el.ValueKind == JsonValueKind.True) { value = true; return true; }
            if (el.ValueKind == JsonValueKind.False) { value = false; return true; }
            if (el.ValueKind == JsonValueKind.String) return bool.TryParse(el.GetString(), out value);
            return false;
        }

        #endregion
    }
}
