using UnityEngine;
using System.Collections.Generic;

namespace MaskShop
{
    /// <summary>
    /// Evaluates mask quality and calculates scores
    /// </summary>
    public class ScoringSystem : MonoBehaviour
    {
        [Header("Score Weights")]
        [SerializeField, Range(0f, 1f)] private float moldWeight = 0.25f;
        [SerializeField, Range(0f, 1f)] private float decorationsWeight = 0.50f;
        [SerializeField, Range(0f, 1f)] private float qteWeight = 0.25f;

        [Header("QTE Score Values")]
        [SerializeField] private int perfectQTEScore = 100;
        [SerializeField] private int goodQTEScore = 70;
        [SerializeField] private int badQTEScore = 30;

        [Header("Bonus Multipliers")]
        [SerializeField] private float allParametersMatchBonus = 1.5f;
        [SerializeField] private float allPerfectQTEBonus = 1.3f;

        [Header("Debug")]
        [SerializeField] private bool showDebugInfo = true;

        /// <summary>
        /// Evaluates a completed mask against the request
        /// </summary>
        public MaskEvaluation EvaluateMask(MaskAssembly mask, MaskRequest request)
        {
            MaskEvaluation evaluation = new MaskEvaluation();
            evaluation.request = request;

            // 1. Evaluate mold/texture match
            float moldScore = EvaluateMold(mask, request);
            evaluation.moldScore = moldScore;

            // 2. Evaluate decorations match
            DecorationEvaluation decorationEval = EvaluateDecorations(mask, request);
            evaluation.decorationScore = decorationEval.score;
            evaluation.matchedMood = decorationEval.matchedMood;
            evaluation.matchedGimmick = decorationEval.matchedGimmick;
            evaluation.matchedPalette = decorationEval.matchedPalette;

            // 3. Evaluate QTE performance
            QTEEvaluation qteEval = EvaluateQTEPerformance(mask);
            evaluation.qteScore = qteEval.score;
            evaluation.perfectQTEs = qteEval.perfectCount;
            evaluation.goodQTEs = qteEval.goodCount;
            evaluation.badQTEs = qteEval.badCount;

            // 4. Calculate weighted total
            float baseScore = (moldScore * moldWeight) +
                            (decorationEval.score * decorationsWeight) +
                            (qteEval.score * qteWeight);

            // 5. Apply bonuses
            float finalScore = baseScore;

            // All parameters matched bonus
            if (decorationEval.allParametersMatched)
            {
                finalScore *= allParametersMatchBonus;
                evaluation.earnedAllParametersBonus = true;
            }

            // All perfect QTEs bonus
            if (qteEval.allPerfect)
            {
                finalScore *= allPerfectQTEBonus;
                evaluation.earnedAllPerfectBonus = true;
            }

            evaluation.finalScore = Mathf.RoundToInt(finalScore * 1000); // Scale to 0-1000+

            // Determine rank
            evaluation.rank = DetermineRank(finalScore);

            if (showDebugInfo)
            {
                LogEvaluation(evaluation);
            }

            return evaluation;
        }

        /// <summary>
        /// Evaluates if the mold matches the requested texture
        /// </summary>
        private float EvaluateMold(MaskAssembly mask, MaskRequest request)
        {
            MaskMold baseMold = mask.GetBaseMold();

            if (baseMold == null)
                return 0f;

            // If no texture was requested, any mold is acceptable
            if (!request.HasTexture())
                return 1f;

            // Check if mold matches requested texture
            return baseMold.MatchesTexture(request.texture) ? 1f : 0f;
        }

        /// <summary>
        /// Evaluates decorations against request
        /// </summary>
        private DecorationEvaluation EvaluateDecorations(MaskAssembly mask, MaskRequest request)
        {
            DecorationEvaluation eval = new DecorationEvaluation();
            List<AppliedDecoration> appliedDecorations = mask.GetAppliedDecorations();

            int totalRequiredParameters = 0;
            int matchedParameters = 0;

            // Check mood match
            if (request.HasMood())
            {
                totalRequiredParameters++;
                bool moodMatched = false;

                foreach (AppliedDecoration decoration in appliedDecorations)
                {
                    if (decoration.decorationData.ContributesToMood(request.mood))
                    {
                        moodMatched = true;
                        break;
                    }
                }

                if (moodMatched)
                {
                    matchedParameters++;
                    eval.matchedMood = true;
                }
            }

            // Check gimmick match
            if (request.HasGimmick())
            {
                totalRequiredParameters++;
                bool gimmickMatched = false;

                foreach (AppliedDecoration decoration in appliedDecorations)
                {
                    if (decoration.decorationData.ContributesToGimmick == request.gimmick)
                    {
                        gimmickMatched = true;
                        break;
                    }
                }

                if (gimmickMatched)
                {
                    matchedParameters++;
                    eval.matchedGimmick = true;
                }
            }

            // Check palette match
            if (request.HasPalette())
            {
                totalRequiredParameters++;
                bool paletteMatched = false;

                foreach (AppliedDecoration decoration in appliedDecorations)
                {
                    if (decoration.decorationData.ContributesToPalette == request.palette)
                    {
                        paletteMatched = true;
                        break;
                    }
                }

                if (paletteMatched)
                {
                    matchedParameters++;
                    eval.matchedPalette = true;
                }
            }

            // Calculate score
            if (totalRequiredParameters > 0)
            {
                eval.score = (float)matchedParameters / totalRequiredParameters;
                eval.allParametersMatched = (matchedParameters == totalRequiredParameters);
            }
            else
            {
                // No specific decorations requested
                eval.score = 1f;
                eval.allParametersMatched = true;
            }

            return eval;
        }

        /// <summary>
        /// Evaluates QTE performance
        /// </summary>
        private QTEEvaluation EvaluateQTEPerformance(MaskAssembly mask)
        {
            QTEEvaluation eval = new QTEEvaluation();
            List<AppliedDecoration> appliedDecorations = mask.GetAppliedDecorations();

            if (appliedDecorations.Count == 0)
            {
                eval.score = 1f;
                return eval;
            }

            int totalScore = 0;
            int maxPossibleScore = 0;

            foreach (AppliedDecoration decoration in appliedDecorations)
            {
                int qteScore = 0;

                switch (decoration.qteResult)
                {
                    case QTEResult.Perfect:
                        qteScore = perfectQTEScore;
                        eval.perfectCount++;
                        break;

                    case QTEResult.Good:
                        qteScore = goodQTEScore;
                        eval.goodCount++;
                        break;

                    case QTEResult.Bad:
                        qteScore = badQTEScore;
                        eval.badCount++;
                        break;
                }

                totalScore += qteScore;
                maxPossibleScore += perfectQTEScore;
            }

            eval.score = (float)totalScore / maxPossibleScore;
            eval.allPerfect = (eval.perfectCount == appliedDecorations.Count);

            return eval;
        }

        /// <summary>
        /// Determines rank based on final score
        /// </summary>
        private MaskRank DetermineRank(float normalizedScore)
        {
            if (normalizedScore >= 0.95f)
                return MaskRank.S;
            else if (normalizedScore >= 0.85f)
                return MaskRank.A;
            else if (normalizedScore >= 0.70f)
                return MaskRank.B;
            else if (normalizedScore >= 0.50f)
                return MaskRank.C;
            else
                return MaskRank.D;
        }

        /// <summary>
        /// Logs detailed evaluation information
        /// </summary>
        private void LogEvaluation(MaskEvaluation evaluation)
        {
            Debug.Log("=== MASK EVALUATION ===");
            Debug.Log($"Mold Score: {evaluation.moldScore * 100:F1}%");
            Debug.Log($"Decoration Score: {evaluation.decorationScore * 100:F1}%");
            Debug.Log($"  - Mood Match: {evaluation.matchedMood}");
            Debug.Log($"  - Gimmick Match: {evaluation.matchedGimmick}");
            Debug.Log($"  - Palette Match: {evaluation.matchedPalette}");
            Debug.Log($"QTE Score: {evaluation.qteScore * 100:F1}%");
            Debug.Log($"  - Perfect: {evaluation.perfectQTEs}");
            Debug.Log($"  - Good: {evaluation.goodQTEs}");
            Debug.Log($"  - Bad: {evaluation.badQTEs}");
            Debug.Log($"Bonuses:");
            Debug.Log($"  - All Parameters: {evaluation.earnedAllParametersBonus}");
            Debug.Log($"  - All Perfect QTEs: {evaluation.earnedAllPerfectBonus}");
            Debug.Log($"FINAL SCORE: {evaluation.finalScore} (Rank {evaluation.rank})");
            Debug.Log("======================");
        }
    }

    /// <summary>
    /// Rank classification
    /// </summary>
    public enum MaskRank
    {
        D,  // Poor
        C,  // Average
        B,  // Good
        A,  // Excellent
        S   // Perfect
    }

    /// <summary>
    /// Complete evaluation of a mask
    /// </summary>
    [System.Serializable]
    public class MaskEvaluation
    {
        public MaskRequest request;

        public float moldScore;
        public float decorationScore;
        public float qteScore;

        public bool matchedMood;
        public bool matchedGimmick;
        public bool matchedPalette;

        public int perfectQTEs;
        public int goodQTEs;
        public int badQTEs;

        public bool earnedAllParametersBonus;
        public bool earnedAllPerfectBonus;

        public int finalScore;
        public MaskRank rank;
    }

    /// <summary>
    /// Internal decoration evaluation data
    /// </summary>
    public class DecorationEvaluation
    {
        public float score;
        public bool matchedMood;
        public bool matchedGimmick;
        public bool matchedPalette;
        public bool allParametersMatched;
    }

    /// <summary>
    /// Internal QTE evaluation data
    /// </summary>
    public class QTEEvaluation
    {
        public float score;
        public int perfectCount;
        public int goodCount;
        public int badCount;
        public bool allPerfect;
    }
}