using System;
using System.Collections.Generic;
using EventsAppQuest.Core;
using EventsAppQuest.Domain.Models;
using UnityEngine;

namespace EventsAppQuest.Presentation
{
    /// <summary>
    /// Consolida a avaliação de qualidade/diagnóstico final da sessão Quest a partir de
    /// engagement (contadores), outcome, export, handoff, shareable e decisão.
    /// Mantém tudo em memória; preparado para futura integração com analytics.
    /// </summary>
    public class QuestSessionQualityAssessmentController : MonoBehaviour
    {
        private QuestPresentationSession _session;

        /// <summary>Avaliação actual (pode ser null até CalculateAssessment).</summary>
        public QuestSessionQualityAssessment Current => _session?.CurrentQualityAssessment;

        public void Bind(QuestPresentationSession session)
        {
            _session = session;
        }

        /// <summary>Calcula ou recalcula a avaliação de qualidade a partir do estado actual da sessão.</summary>
        public void CalculateAssessment()
        {
            if (_session == null) return;
            try
            {
                var outcome = _session.CurrentCommercialOutcome;
                var export = _session.CurrentExportPayload;
                var handoff = _session.CurrentHandoffReport;
                var stats = export?.InteractionStats;
                var decision = _session.DecisionSummary;
                var rec = _session.RecommendationSummary;

                var sessionId = handoff?.SessionId ?? export?.SessionId ?? outcome?.SessionId ?? ("Quest_" + DateTime.UtcNow.ToString("yyyyMMddHHmmss"));

                // Engagement-like data from session counters when no dedicated engagement layer
                var hotspotOpens = stats?.HotspotsOpened ?? _session.HotspotContextOpenCount;
                var comparisonsOpens = stats?.ComparisonsOpened ?? _session.ComparisonOpenCount;
                var closingOpens = stats?.ClosingOpened ?? _session.ClosingOpenCount;
                var ctaCount = stats?.CTAConfirmations ?? _session.CTAConfirmationCount;
                var totalInteractions = stats?.TotalInteractionCount ?? (hotspotOpens + comparisonsOpens + closingOpens + ctaCount);
                var guidedViewed = stats?.GuidedStepsViewed ?? Math.Max(1, _session.CurrentGuidedStepIndex + 1);

                // Sub-scores (0–100 heuristics)
                var presentationScore = CalculatePresentationQualityScore();
                var commercialScore = CalculateCommercialClarityScore(outcome, decision, rec, handoff, _session.CurrentShareableSummary);
                var interactionScore = CalculateInteractionQualityScore(hotspotOpens, comparisonsOpens, closingOpens, ctaCount, totalInteractions);
                var decisionScore = CalculateDecisionReadinessScore(outcome);
                var engagementScore = CalculateEngagementContributionScore(totalInteractions, guidedViewed, _session.TotalSteps, ctaCount);

                // Overall: weighted average
                var overall = (int)Mathf.Clamp(
                    (presentationScore * 0.25f) + (commercialScore * 0.25f) + (interactionScore * 0.2f) + (decisionScore * 0.15f) + (engagementScore * 0.15f),
                    0f, 100f);

                var strengths = new List<string>();
                var weaknesses = new List<string>();
                var suggestions = new List<string>();

                if (presentationScore >= 60) strengths.Add("Apresentação com plano e conteúdo estruturado.");
                else weaknesses.Add("Plano ou conteúdo da apresentação limitado.");
                if (commercialScore >= 60) strengths.Add("Clareza comercial e decisão documentada.");
                else weaknesses.Add("Pouca clareza comercial ou decisão indefinida.");
                if (interactionScore >= 50) strengths.Add("Interação com hotspots e fechamento realizada.");
                else weaknesses.Add("Pouca interação com hotspots ou fechamento.");
                if (decisionScore >= 50) strengths.Add("Decisão ou próximo passo definido.");
                else weaknesses.Add("Decisão ainda em exploração; definir próximo passo.");
                if (engagementScore >= 50) strengths.Add("Engajamento durante a sessão.");
                else weaknesses.Add("Baixo engajamento; considerar mais passos ou CTA.");

                if (handoff != null) strengths.Add("Relatório de handoff disponível.");
                if (_session.CurrentShareableSummary != null) strengths.Add("Resumo compartilhável gerado.");
                if (export == null) weaknesses.Add("Payload de exportação não gerado.");
                if (ctaCount == 0 && closingOpens > 0) suggestions.Add("Confirmar CTA no fechamento para melhor follow-up.");
                if (totalInteractions < 3) suggestions.Add("Explorar mais hotspots e comparações para enriquecer a sessão.");
                if (overall < 50) suggestions.Add("Completar fechamento, gerar export e handoff para melhor qualidade.");

                var qualityLabel = overall >= 76 ? "StrongCommercialInterest" : (overall >= 51 ? "High" : (overall >= 26 ? "Medium" : "Low"));

                _session.CurrentQualityAssessment = new QuestSessionQualityAssessment
                {
                    SessionId = sessionId ?? "",
                    PresentationQualityScore = presentationScore,
                    CommercialClarityScore = commercialScore,
                    InteractionQualityScore = interactionScore,
                    DecisionReadinessScore = decisionScore,
                    EngagementContributionScore = engagementScore,
                    Strengths = strengths,
                    Weaknesses = weaknesses,
                    ImprovementSuggestions = suggestions,
                    QualityLabel = qualityLabel,
                    GeneratedAt = DateTime.UtcNow
                };
                _session.LastQualityAssessmentGeneratedAt = _session.CurrentQualityAssessment.GeneratedAt;
                _session.HasQualityAssessment = true;
            }
            catch (Exception)
            {
                // Fallback: não quebrar a apresentação
            }
        }

        private int CalculatePresentationQualityScore()
        {
            if (_session == null) return 0;
            var score = 0;
            if (_session.MRPlan != null) score += 25;
            if (_session.GuidedSteps != null && _session.GuidedSteps.Count > 0) score += 25;
            if (_session.Hotspots != null && _session.Hotspots.Count > 0) score += 25;
            if (_session.CurrentClosingState != null || _session.ClosingOpenCount > 0) score += 25;
            return Math.Min(100, score);
        }

        private int CalculateCommercialClarityScore(QuestCommercialOutcome outcome, ProposalDecisionSummary decision, ProposalRecommendationSummary rec, QuestSessionHandoffReport handoff, QuestSessionShareableSummary shareable)
        {
            var score = 0;
            if (outcome != null && !string.IsNullOrEmpty(outcome.OutcomeSummary)) score += 20;
            if (decision != null) score += 20;
            if (rec != null) score += 20;
            if (handoff != null && !string.IsNullOrEmpty(handoff.SuggestedNextAction)) score += 20;
            if (shareable != null && !string.IsNullOrEmpty(shareable.ExecutiveSummary)) score += 20;
            return Math.Min(100, score);
        }

        private int CalculateInteractionQualityScore(int hotspotOpens, int comparisonsOpens, int closingOpens, int ctaCount, int totalInteractions)
        {
            var score = 0;
            if (hotspotOpens > 0) score += 25;
            if (comparisonsOpens > 0) score += 25;
            if (closingOpens > 0) score += 25;
            if (ctaCount > 0) score += 25;
            return Math.Min(100, score);
        }

        private int CalculateDecisionReadinessScore(QuestCommercialOutcome outcome)
        {
            var state = outcome?.FinalDecisionState ?? QuestCommercialDecisionState.ExplorationOnly;
            switch (state)
            {
                case QuestCommercialDecisionState.ReadyToClose: return 100;
                case QuestCommercialDecisionState.ReadyToAdvance: return 80;
                case QuestCommercialDecisionState.NeedsFollowUp: return 60;
                case QuestCommercialDecisionState.Interested: return 40;
                default: return 20;
            }
        }

        private int CalculateEngagementContributionScore(int totalInteractions, int guidedViewed, int totalSteps, int ctaCount)
        {
            var score = 0;
            if (totalSteps > 0) score += (int)Mathf.Clamp((guidedViewed / (float)totalSteps) * 40f, 0f, 40f);
            if (totalInteractions >= 3) score += 30;
            if (totalInteractions >= 6) score += 15;
            if (ctaCount > 0) score += 15;
            return Math.Min(100, score);
        }

        /// <summary>Limpa a avaliação actual e os metadados na sessão.</summary>
        public void ClearAssessment()
        {
            if (_session == null) return;
            _session.CurrentQualityAssessment = null;
            _session.LastQualityAssessmentGeneratedAt = null;
            _session.HasQualityAssessment = false;
        }
    }
}
