using UnityEngine;

using System.Collections;



namespace MaskShop

{

    /// <summary>

    /// Controls the behavior of an ogre customer in the mask shop

    /// </summary>

    public class OgreBehavior : MonoBehaviour

    {

        [Header("Movement Settings")]

        [SerializeField] private Transform shopPosition;

        [SerializeField] private float moveSpeed = 2f;

        [SerializeField] private float arrivalThreshold = 0.1f;



        [Header("Request Settings")]

        [SerializeField] private RequestGenerator requestGenerator;

        [SerializeField] private float requestDelay = 0.5f;



        [Header("Visual Feedback")]

        [SerializeField] private bool showDebugInfo = true;



        // Estado interno

        private MaskRequest currentRequest;

        private bool hasArrived = false;

        private bool hasGeneratedRequest = false;

        private bool isWaitingForCompletion = false;



        private void OnEnable()

        {

            // Suscribirse al evento de completado de solicitud

            OgreEvents.OnRequestCompleted += OnRequestCompleted;

        }



        private void OnDisable()

        {

            // Desuscribirse del evento

            OgreEvents.OnRequestCompleted -= OnRequestCompleted;

        }



        private void Start()

        {

            if (!shopPosition) shopPosition = GameObject.Find("ShopPosition")?.transform;



            StartCoroutine(OgreRoutine());



        }



        /// <summary>

        /// Corrutina principal del comportamiento del ogro

        /// </summary>

        private IEnumerator OgreRoutine()

        {

            // Paso 1: Moverse hacia la tienda

            yield return MoveToShop();



            // Paso 2: Esperar un momento antes de hacer la solicitud

            yield return new WaitForSeconds(requestDelay);



            // Paso 3: Generar y anunciar la solicitud

            GenerateRequest();



            // Paso 4: Esperar a que la solicitud sea completada

            yield return WaitForRequestCompletion();



            // Paso 5: Finalizar la rutina

            FinishRoutine();

        }



        /// <summary>

        /// Mueve al ogro hacia la posición de la tienda

        /// </summary>

        private IEnumerator MoveToShop()
        {
            if (shopPosition == null)
            {
                Debug.LogError("OgreBehavior: Shop position is not assigned!");
                yield break;
            }

            Vector3 startPos = transform.position;
            Vector3 targetPos = shopPosition.position;
            Vector3 dir = (targetPos - startPos).normalized;

            float distance = Vector3.Distance(startPos, targetPos);

            // Tiempo real basado en velocidad
            float moveDuration = distance / moveSpeed;

            // Límites solo para evitar casos extremos
            moveDuration = Mathf.Max(moveDuration, 0.25f);

            bool finished = false;

            // Movimiento principal
            LeanTween.move(gameObject, targetPos, moveDuration)
                .setEaseOutCubic()
                .setOnComplete(() => finished = true);

            // Rotación acompasada
            LeanTween.rotate(gameObject, shopPosition.rotation.eulerAngles, moveDuration * 0.85f)
                .setEaseOutQuad();

            yield return new WaitUntil(() => finished);

            // Overshoot proporcional pero acotado
            float overshootAmount = Mathf.Clamp(distance * 0.05f, 0.05f, 0.25f);
            Vector3 overshootPos = targetPos + dir * overshootAmount;

            LeanTween.move(gameObject, overshootPos, 0.1f)
                .setEaseOutQuad()
                .setOnComplete(() =>
                {
                    LeanTween.move(gameObject, targetPos, 0.12f)
                        .setEaseInOutQuad();
                });

            // Squash sutil
            LeanTween.scale(gameObject, Vector3.one * 1.04f, 0.08f)
                .setEaseOutQuad()
                .setOnComplete(() =>
                {
                    LeanTween.scale(gameObject, Vector3.one, 0.1f);
                });

            hasArrived = true;

            if (showDebugInfo)
                Debug.Log($"OgreBehavior: Arrived");
        }





        /// <summary>

        /// Genera una solicitud de máscara

        /// </summary>

        private void GenerateRequest()

        {

            if (requestGenerator == null)

            {

                Debug.LogError("OgreBehavior: RequestGenerator is not assigned!");

                return;

            }



            currentRequest = requestGenerator.GenerateRequest();

            hasGeneratedRequest = true;



            // Disparar el evento de solicitud

            OgreEvents.RaiseMaskRequested(currentRequest);



            if (showDebugInfo)

            {

                Debug.Log($"OgreBehavior: Ogre requests: {currentRequest.requestText}");

                LogRequestDetails();

            }

        }



        /// <summary>

        /// Espera a que la solicitud sea completada

        /// </summary>

        private IEnumerator WaitForRequestCompletion()

        {

            isWaitingForCompletion = true;



            if (showDebugInfo)

            {

                Debug.Log("OgreBehavior: Ogre is waiting for mask completion...");

            }



            // Esperar hasta que la solicitud sea completada

            while (isWaitingForCompletion)

            {

                yield return null;

            }



            if (showDebugInfo)

            {

                Debug.Log("OgreBehavior: Mask completed! Ogre is satisfied.");

            }

        }



        /// <summary>

        /// Callback cuando una solicitud es completada

        /// </summary>

        private void OnRequestCompleted(MaskRequest completedRequest)

        {

            // Verificar si esta solicitud es la actual

            if (completedRequest == currentRequest)

            {

                isWaitingForCompletion = false;

            }

        }



        /// <summary>

        /// Finaliza la rutina del ogro

        /// </summary>

        private void FinishRoutine()

        {

            if (showDebugInfo)

            {

                Debug.Log("OgreBehavior: Ogre routine finished!");

            }



            // Disparar evento de finalización

            OgreEvents.RaiseOgreFinished();



            // Aquí puedes añadir lógica adicional:

            // - Animación de salida

            // - Movimiento fuera de la tienda

            // - Destruir el objeto después de un tiempo



            // Por ahora, destruimos el ogro

            Destroy(gameObject, 1f);

        }



        /// <summary>

        /// Muestra información detallada de la solicitud en el log

        /// </summary>

        private void LogRequestDetails()

        {

            Debug.Log("=== Request Details ===");

            Debug.Log($"Mood: {(currentRequest.HasMood() ? currentRequest.mood.ParameterName : "Not specified")}");

            Debug.Log($"Palette: {(currentRequest.HasPalette() ? currentRequest.palette.ParameterName : "Not specified")}");

            Debug.Log($"Texture: {(currentRequest.HasTexture() ? currentRequest.texture.ParameterName : "Not specified")}");

            Debug.Log($"Gimmick: {(currentRequest.HasGimmick() ? currentRequest.gimmick.ParameterName : "Not specified")}");

            Debug.Log($"Total parameters: {currentRequest.GetRequestedParametersCount()}/4");

            Debug.Log("=====================");

        }



        /// <summary>

        /// Método público para completar manualmente la solicitud (para testing)

        /// </summary>

        public void CompleteRequest()

        {

            if (currentRequest != null)

            {

                OgreEvents.RaiseRequestCompleted(currentRequest);

            }

        }



        // Getters públicos

        public MaskRequest GetCurrentRequest() => currentRequest;

        public bool HasArrived() => hasArrived;

        public bool HasGeneratedRequest() => hasGeneratedRequest;

        public bool IsWaitingForCompletion() => isWaitingForCompletion;



#if UNITY_EDITOR

        private void OnDrawGizmos()

        {

            if (shopPosition != null)

            {

                // Dibujar línea hacia la posición de la tienda

                Gizmos.color = hasArrived ? Color.green : Color.yellow;

                Gizmos.DrawLine(transform.position, shopPosition.position);



                // Dibujar esfera en la posición objetivo

                Gizmos.color = Color.red;

                Gizmos.DrawWireSphere(shopPosition.position, 0.5f);

            }

        }

#endif

    }

}