using UnityEngine;
using System.Collections.Generic;

namespace MaskShop
{
    /// <summary>
    /// Represents a mask being assembled with decorations
    /// </summary>
    public class MaskAssembly : MonoBehaviour
    {
        [Header("Assembly Info")]
        [SerializeField] private MaskMold baseMold;

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

        // Decoration tracking
        private Dictionary<string, Transform> decorationSlots = new Dictionary<string, Transform>();
        private List<AppliedDecoration> appliedDecorations = new List<AppliedDecoration>();

        /// <summary>
        /// Initializes the mask assembly
        /// </summary>
        public void Initialize(MaskMold moldData)
        {
            baseMold = moldData;
            FindDecorationSlots();

            if (showDebugInfo)
            {
                Debug.Log($"MaskAssembly: Initialized with {baseMold.MoldName}");
                Debug.Log($"MaskAssembly: Found {decorationSlots.Count} decoration slots");
            }
        }

        /// <summary>
        /// Finds all decoration slot transforms in the mold
        /// </summary>
        private void FindDecorationSlots()
        {
            if (baseMold == null || baseMold.DecorationSlotNames == null)
                return;

            foreach (string slotName in baseMold.DecorationSlotNames)
            {
                Transform slot = FindDeepChild(transform, slotName);

                if (slot != null)
                {
                    decorationSlots[slotName] = slot;

                    if (showDebugInfo)
                    {
                        Debug.Log($"MaskAssembly: Found slot '{slotName}' at {slot.position}");
                    }
                }
                else
                {
                    // Create slot if not found
                    GameObject slotObj = new GameObject(slotName);
                    slotObj.transform.SetParent(transform);
                    slotObj.transform.localPosition = Vector3.zero;
                    decorationSlots[slotName] = slotObj.transform;

                    if (showDebugInfo)
                    {
                        Debug.LogWarning($"MaskAssembly: Slot '{slotName}' not found, created new one");
                    }
                }
            }
        }

        /// <summary>
        /// Recursively finds a child transform by name
        /// </summary>
        private Transform FindDeepChild(Transform parent, string name)
        {
            foreach (Transform child in parent)
            {
                if (child.name == name)
                    return child;

                Transform result = FindDeepChild(child, name);
                if (result != null)
                    return result;
            }
            return null;
        }

        /// <summary>
        /// Applies a decoration to the mask with QTE result
        /// </summary>
        public void ApplyDecoration(DecorationItem decorationData, QTEResult qteResult)
        {
            if (decorationData == null || decorationData.DecorationPrefab == null)
            {
                Debug.LogWarning("MaskAssembly: Invalid decoration data or prefab!");
                return;
            }

            // Get target slot
            Transform targetSlot = GetTargetSlot(decorationData.TargetSlotName);

            if (targetSlot == null)
            {
                Debug.LogWarning($"MaskAssembly: Slot '{decorationData.TargetSlotName}' not found!");
                return;
            }

            // Instantiate decoration
            GameObject decorationInstance = Instantiate(decorationData.DecorationPrefab, targetSlot);

            // Apply positioning based on QTE result
            ApplyPositioning(decorationInstance, decorationData, qteResult);

            // Track applied decoration
            AppliedDecoration applied = new AppliedDecoration
            {
                decorationData = decorationData,
                instance = decorationInstance,
                qteResult = qteResult,
                slot = targetSlot
            };

            appliedDecorations.Add(applied);

            if (showDebugInfo)
            {
                Debug.Log($"MaskAssembly: Applied {decorationData.DecorationName} with {qteResult} result");
            }
        }

        /// <summary>
        /// Gets the target slot for a decoration
        /// </summary>
        private Transform GetTargetSlot(string slotName)
        {
            if (string.IsNullOrEmpty(slotName))
            {
                // Use first available slot
                foreach (var availableSlot in decorationSlots.Values)
                {
                    return availableSlot;
                }
                return transform; // Fallback to root
            }

            if (decorationSlots.TryGetValue(slotName, out Transform slot))
            {
                return slot;
            }

            return transform; // Fallback to root
        }
        /// <summary>
        /// Applies positioning based on QTE result
        /// </summary>
        private void ApplyPositioning(GameObject decoration, DecorationItem decorationData, QTEResult qteResult)
        {
            switch (qteResult)
            {
                case QTEResult.Perfect:
                case QTEResult.Good:
                    // Apply default/correct positioning
                    decoration.transform.localPosition = decorationData.DefaultPosition;
                    decoration.transform.localRotation = Quaternion.Euler(decorationData.DefaultRotation);
                    decoration.transform.localScale = decorationData.DefaultScale;
                    break;

                case QTEResult.Bad:
                    // Apply random incorrect positioning
                    ApplyBadPositioning(decoration, decorationData);
                    break;
            }
        }

        /// <summary>
        /// Applies random incorrect positioning for bad QTE results
        /// </summary>
        private void ApplyBadPositioning(GameObject decoration, DecorationItem decorationData)
        {
            // Random position offset
            Vector3 randomOffset = new Vector3(
                Random.Range(-0.2f, 0.2f),
                Random.Range(-0.2f, 0.2f),
                Random.Range(-0.2f, 0.2f)
            );
            decoration.transform.localPosition = decorationData.DefaultPosition + randomOffset;

            // Random rotation offset
            Vector3 randomRotation = new Vector3(
                Random.Range(-30f, 30f),
                Random.Range(-30f, 30f),
                Random.Range(-30f, 30f)
            );
            decoration.transform.localRotation = Quaternion.Euler(decorationData.DefaultRotation + randomRotation);

            // Slightly random scale
            float scaleVariation = Random.Range(0.8f, 1.2f);
            decoration.transform.localScale = decorationData.DefaultScale * scaleVariation;

            if (showDebugInfo)
            {
                Debug.Log($"MaskAssembly: Applied bad positioning to {decorationData.DecorationName}");
            }
        }

        /// <summary>
        /// Applies a palette/material to the mask
        /// </summary>
        public void ApplyPalette(DecorationItem paletteDecoration, QTEResult qteResult)
        {
            if (paletteDecoration.Type != DecorationType.PaletteDecoration)
            {
                Debug.LogWarning("MaskAssembly: Decoration is not a palette type!");
                return;
            }

            if (paletteDecoration.PaletteMaterial == null)
            {
                Debug.LogWarning("MaskAssembly: Palette decoration has no material!");
                return;
            }

            // Apply material to all renderers in the mask
            Renderer[] renderers = GetComponentsInChildren<Renderer>();

            foreach (Renderer renderer in renderers)
            {
                // Only apply to main mask parts, not decorations
                if (!renderer.transform.IsChildOf(transform) || appliedDecorations.Exists(d => d.instance == renderer.gameObject))
                    continue;

                renderer.material = paletteDecoration.PaletteMaterial;
            }

            // Track as applied decoration
            AppliedDecoration applied = new AppliedDecoration
            {
                decorationData = paletteDecoration,
                instance = null, // No instance for material
                qteResult = qteResult,
                slot = null
            };

            appliedDecorations.Add(applied);

            if (showDebugInfo)
            {
                Debug.Log($"MaskAssembly: Applied palette {paletteDecoration.DecorationName}");
            }
        }

        /// <summary>
        /// Gets all applied decorations
        /// </summary>
        public List<AppliedDecoration> GetAppliedDecorations() => appliedDecorations;

        /// <summary>
        /// Gets the base mold data
        /// </summary>
        public MaskMold GetBaseMold() => baseMold;

        /// <summary>
        /// Gets available decoration slots
        /// </summary>
        public Dictionary<string, Transform> GetDecorationSlots() => decorationSlots;
    }

    /// <summary>
    /// Represents a decoration that has been applied to a mask
    /// </summary>
    [System.Serializable]
    public class AppliedDecoration
    {
        public DecorationItem decorationData;
        public GameObject instance;
        public QTEResult qteResult;
        public Transform slot;
    }
}