using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.IO;
using TMPro;

namespace MaskShop
{
    /// <summary>
    /// Manages mask delivery, ogre photo, and scoring
    /// </summary>
    public class MaskDeliverySystem : MonoBehaviour
    {
        [Header("References")]
        [SerializeField] private WorkbenchZone workbenchZone;
        [SerializeField] private ScoringSystem scoringSystem;
        [SerializeField] private ProgressionSystem progressionSystem;
        [SerializeField] private Button deliverButton;
        [SerializeField] private Button nextOgre;

        [Header("Photo Settings")]
        [SerializeField] private Transform ogrePhotoPosition;
        [SerializeField] private Camera photoCamera;
        [SerializeField] private int screenshotWidth = 1920;
        [SerializeField] private int screenshotHeight = 1080;
        [SerializeField] private string screenshotFolder = "MaskPhotos";

        [Header("UI")]
        [SerializeField] private GameObject resultsPanel;
        [SerializeField] private TextMeshProUGUI scoreText;
        [SerializeField] private TextMeshProUGUI rankText;
        [SerializeField] private TextMeshProUGUI xpGainedText;
        [SerializeField] private Image photoDisplayImage;

        [Header("Ogre Reaction")]
        [SerializeField] private float reactionDelay = 1f;
        [SerializeField] private float photoDelay = 0.5f;

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

        // State
        private MaskAssembly currentMask;
        private MaskRequest currentRequest;
        private GameObject currentOgre;
        private bool isDeliveryInProgress = false;
        private bool waitingForUserToContinue = false;

        private void Start()
        {
            if (deliverButton != null)
            {
                deliverButton.onClick.AddListener(OnDeliverButtonClicked);
                deliverButton.interactable = false;
            }
            if (nextOgre != null)
            {
                nextOgre.onClick.AddListener(OnDeliverButtonClicked);
                nextOgre.interactable = false;
            }

            if (resultsPanel != null)
            {
                resultsPanel.SetActive(false);
            }
        }

        private void OnEnable()
        {
            WorkbenchZone.OnMaskPlaced += OnMaskPlaced;
            OgreEvents.OnMaskRequested += OnMaskRequested;
        }

        private void OnDisable()
        {
            WorkbenchZone.OnMaskPlaced -= OnMaskPlaced;
            OgreEvents.OnMaskRequested -= OnMaskRequested;
        }

        /// <summary>
        /// Called when mask is placed on workbench
        /// </summary>
        private void OnMaskPlaced(MaskAssembly maskAssembly)
        {
            currentMask = maskAssembly;

            if (deliverButton != null)
            {
                deliverButton.interactable = true;
            }
        }

        /// <summary>
        /// Called when ogre makes a request
        /// </summary>
        private void OnMaskRequested(MaskRequest request)
        {
            currentRequest = request;

            // Find the current ogre in scene
            OgreBehavior[] ogres = FindObjectsOfType<OgreBehavior>();
            if (ogres.Length > 0)
            {
                currentOgre = ogres[0].gameObject;
            }
        }

        /// <summary>
        /// Called when deliver button is clicked
        /// </summary>
        private void OnDeliverButtonClicked()
        {
            if (isDeliveryInProgress)
                return;

            if (currentMask == null)
            {
                Debug.LogWarning("MaskDeliverySystem: No mask to deliver!");
                return;
            }

            if (currentRequest == null)
            {
                Debug.LogWarning("MaskDeliverySystem: No active request!");
                return;
            }

            StartCoroutine(DeliverySequence());
        }

        /// <summary>
        /// Main delivery sequence
        /// </summary>
        private IEnumerator DeliverySequence()
        {
            isDeliveryInProgress = true;

            if (deliverButton != null)
            {
                deliverButton.interactable = false;
            }

            if (showDebugInfo)
            {
                Debug.Log("MaskDeliverySystem: Starting delivery sequence");
            }

            // 1. Evaluate the mask
            MaskEvaluation evaluation = scoringSystem.EvaluateMask(currentMask, currentRequest);

            // 2. Move ogre to photo position and equip mask
            yield return MoveOgreToPhoto();

            // 3. Wait for ogre reaction
            yield return new WaitForSeconds(reactionDelay);

            // 4. Take photo
            yield return new WaitForSeconds(photoDelay);
            Texture2D photo = TakePhoto();

            // 5. Show results
            ShowResults(evaluation, photo);

            // 6. Award XP (se muestra en UI pero aún no se otorga)
            // El XP se otorgará cuando el usuario cierre el panel

            // ========== NUEVO: PAUSA AQUÍ ESPERANDO AL USUARIO ==========
            waitingForUserToContinue = true;

            if (showDebugInfo)
            {
                Debug.Log("MaskDeliverySystem: Waiting for user to close results panel...");
            }

            // Esperar hasta que el usuario presione el botón "Cerrar"
            yield return new WaitUntil(() => !waitingForUserToContinue);

            if (showDebugInfo)
            {
                Debug.Log("MaskDeliverySystem: User closed results, continuing...");
            }
            // ============================================================

            // 7. Otorgar XP AHORA (después de que el usuario cierre)
            if (progressionSystem != null)
            {
                progressionSystem.AwardXP(evaluation);
            }

            // 8. Complete the request (esto desbloquea al ogre)
            OgreEvents.RaiseRequestCompleted(currentRequest);

            if (showDebugInfo)
            {
                Debug.Log("MaskDeliverySystem: Request completed, ogre will leave");
            }

            // 9. Pequeña espera para que el ogre comience a salir
            yield return new WaitForSeconds(0.5f);

            // 10. Cleanup
            CleanupDelivery();

            isDeliveryInProgress = false;

            if (showDebugInfo)
            {
                Debug.Log("MaskDeliverySystem: Delivery sequence complete, ready for next customer");
            }
        }
        /// <summary>
        /// Moves ogre to photo position and equips mask
        /// </summary>
        private IEnumerator MoveOgreToPhoto()
        {
            if (currentOgre == null || ogrePhotoPosition == null)
            {
                if (showDebugInfo)
                {
                    Debug.LogWarning("MaskDeliverySystem: Missing ogre or photo position");
                }
                yield break;
            }

            // Detach mask from workbench
            GameObject maskObject = currentMask.gameObject;
            maskObject.transform.SetParent(null);

            // Move ogre to photo position
            float moveSpeed = 3f;
            Vector3 targetPos = ogrePhotoPosition.position;

            while (Vector3.Distance(currentOgre.transform.position, targetPos) > 0.1f)
            {
                currentOgre.transform.position = Vector3.MoveTowards(
                    currentOgre.transform.position,
                    targetPos,
                    moveSpeed * Time.deltaTime
                );

                yield return null;
            }

            currentOgre.transform.position = targetPos;
            currentOgre.transform.rotation = ogrePhotoPosition.rotation;

            // Attach mask to ogre's head
            Transform ogreHead = FindOgreHead(currentOgre.transform);
            if (ogreHead != null)
            {
                maskObject.transform.SetParent(ogreHead);
                maskObject.transform.localPosition = Vector3.zero;
                maskObject.transform.localRotation = Quaternion.identity;
            }
            else
            {
                // Fallback: attach to ogre root
                maskObject.transform.SetParent(currentOgre.transform);
                maskObject.transform.localPosition = new Vector3(0, 2f, 0); // Approximate head position
            }

            if (showDebugInfo)
            {
                Debug.Log("MaskDeliverySystem: Ogre equipped with mask");
            }
        }
        public void OnCloseResultsButtonClicked()
        {
            if (showDebugInfo)
            {
                Debug.Log("MaskDeliverySystem: Close Results button clicked");
            }

            // Ocultar panel de resultados
            if (resultsPanel != null)
            {
                resultsPanel.SetActive(false);
            }

            // Destrabar el flujo de DeliverySequence
            waitingForUserToContinue = false;
        }
        /// <summary>
        /// Finds the ogre's head transform
        /// </summary>
        private Transform FindOgreHead(Transform ogre)
        {
            // Try common head bone names
            string[] headNames = { "HeadSlot" };

            foreach (string name in headNames)
            {
                Transform head = FindDeepChild(ogre, name);
                if (head != null)
                    return head;
            }

            return null;
        }

        /// <summary>
        /// Recursively finds child 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>
        /// Takes a screenshot photo
        /// </summary>
        private Texture2D TakePhoto()
        {
            if (photoCamera == null)
            {
                Debug.LogWarning("MaskDeliverySystem: No photo camera assigned, using main camera");
                photoCamera = Camera.main;
            }

            // Create render texture
            RenderTexture rt = new RenderTexture(screenshotWidth, screenshotHeight, 24);
            photoCamera.targetTexture = rt;

            // Render
            Texture2D screenshot = new Texture2D(screenshotWidth, screenshotHeight, TextureFormat.RGB24, false);
            photoCamera.Render();

            RenderTexture.active = rt;
            screenshot.ReadPixels(new Rect(0, 0, screenshotWidth, screenshotHeight), 0, 0);
            screenshot.Apply();

            // Cleanup
            photoCamera.targetTexture = null;
            RenderTexture.active = null;
            Destroy(rt);

            // Save to file
            SaveScreenshot(screenshot);

            if (showDebugInfo)
            {
                Debug.Log("MaskDeliverySystem: Photo taken!");
            }

            return screenshot;
        }

        /// <summary>
        /// Saves screenshot to disk
        /// </summary>
        private void SaveScreenshot(Texture2D screenshot)
        {
            string folderPath = Path.Combine(Application.persistentDataPath, screenshotFolder);

            if (!Directory.Exists(folderPath))
            {
                Directory.CreateDirectory(folderPath);
            }

            string timestamp = System.DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
            string filename = $"Mask_{timestamp}.png";
            string filepath = Path.Combine(folderPath, filename);

            byte[] bytes = screenshot.EncodeToPNG();
            File.WriteAllBytes(filepath, bytes);

            if (showDebugInfo)
            {
                Debug.Log($"MaskDeliverySystem: Screenshot saved to {filepath}");
            }
        }

        /// <summary>
        /// Shows results UI
        /// </summary>
        private void ShowResults(MaskEvaluation evaluation, Texture2D photo)
        {
            if (resultsPanel != null)
            {
                resultsPanel.SetActive(true);
            }

            if (scoreText != null)
            {
                scoreText.text = $"Score: {evaluation.finalScore}";
            }

            if (rankText != null)
            {
                rankText.text = $"Rank: {evaluation.rank}";

                // Color based on rank
                rankText.color = evaluation.rank switch
                {
                    MaskRank.S => new Color(1f, 0.84f, 0f), // Gold
                    MaskRank.A => new Color(0f, 0.8f, 1f), // Cyan
                    MaskRank.B => new Color(0f, 1f, 0f),   // Green
                    MaskRank.C => new Color(1f, 0.65f, 0f), // Orange
                    MaskRank.D => new Color(0.8f, 0.8f, 0.8f), // Gray
                    _ => Color.white
                };
            }

            if (xpGainedText != null)
            {
                int xpGained = progressionSystem != null ?
                    progressionSystem.GetCurrentXP() : 0;
                xpGainedText.text = $"+{xpGained} XP";
            }

            if (photoDisplayImage != null && photo != null)
            {
                Sprite photoSprite = Sprite.Create(
                    photo,
                    new Rect(0, 0, photo.width, photo.height),
                    new Vector2(0.5f, 0.5f)
                );
                photoDisplayImage.sprite = photoSprite;
            }

            if (showDebugInfo)
            {
                Debug.Log($"MaskDeliverySystem: Results shown - Score: {evaluation.finalScore}, Rank: {evaluation.rank}");
            }
            if (nextOgre != null)
            {
                nextOgre.interactable = true;
            }
        }

        /// <summary>
        /// Cleans up after delivery
        /// </summary>
        private void CleanupDelivery()
        {
            // Clear workbench
            if (workbenchZone != null)
            {
                workbenchZone.ClearWorkbench();
            }

            // Hide results
            if (resultsPanel != null)
            {
                resultsPanel.SetActive(false);
            }

            // Reset state
            currentMask = null;
            currentRequest = null;
            currentOgre = null;

            if (showDebugInfo)
            {
                Debug.Log("MaskDeliverySystem: Delivery cleanup complete");
            }
        }

        /// <summary>
        /// Manual trigger for delivery (for testing)
        /// </summary>
        [ContextMenu("Test Delivery")]
        public void TestDelivery()
        {
            OnDeliverButtonClicked();
        }
    }
}