using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Video;
using UnityEngine.InputSystem;
using System.Collections;

#if UNITY_WEBGL && !UNITY_EDITOR
using System.Runtime.InteropServices;
#endif

public class MapFullscreenVideo : MonoBehaviour
{
    private VideoPlayer videoPlayer;
    private RenderTexture renderTexture;
    private RawImage display;
    private CanvasGroup canvasGroup;
    private MapStep stepData;
    private System.Action onComplete;
    private bool canSkip = false;
    private bool hasCompleted = false;
    private bool usingWebglDomVideo = false;

#if UNITY_WEBGL && !UNITY_EDITOR
    [DllImport("__Internal")] private static extern void WVO_Create(string url, string fit, int loop, int muted);
    [DllImport("__Internal")] private static extern void WVO_Play();
    [DllImport("__Internal")] private static extern void WVO_Dispose();
    [DllImport("__Internal")] private static extern void WVO_SetObjectFit(string fit);
    [DllImport("__Internal")] private static extern void WVO_SetOnEnded(string goName, string methodName);
    [DllImport("__Internal")] private static extern void WVO_ShowSkipButton(string label, string goName, string methodName);
    [DllImport("__Internal")] private static extern void WVO_HideSkipButton();
#endif

    public void Initialize(MapStep step, System.Action onVideoComplete)
    {
        stepData = step;
        onComplete = onVideoComplete;

        canvasGroup = gameObject.AddComponent<CanvasGroup>();
        canvasGroup.alpha = 0f;

        // Important: nom stable pour callback WebGL (SendMessage)
        gameObject.name = "MapFullscreenVideo";

        CreateVideoPlayer();
        StartCoroutine(FadeInAndPlay());
    }

    void CreateVideoPlayer()
    {
        RectTransform rectTransform = GetComponent<RectTransform>();
        rectTransform.anchorMin = Vector2.zero;
        rectTransform.anchorMax = Vector2.one;
        rectTransform.offsetMin = Vector2.zero;
        rectTransform.offsetMax = Vector2.zero;

        GameObject bgObj = new GameObject("BlackBackground");
        bgObj.transform.SetParent(transform, false);
        RectTransform bgRect = bgObj.AddComponent<RectTransform>();
        bgRect.anchorMin = Vector2.zero;
        bgRect.anchorMax = Vector2.one;
        bgRect.offsetMin = Vector2.zero;
        bgRect.offsetMax = Vector2.zero;
        Image bgImage = bgObj.AddComponent<Image>();
        bgImage.color = Color.black;
        bgImage.raycastTarget = false;  // Désactiver les raycast sur le fond noir

        // En WebGL, RenderTexture + VideoPlayer est très coûteux et peut mener à abort(OOM).
        // => on utilise la vidéo DOM via WebGLVideoOverlay.jslib.
#if UNITY_WEBGL && !UNITY_EDITOR
        usingWebglDomVideo = true;
        try
        {
            // callback fin vidéo -> OnWebGLVideoEnded()
            WVO_SetOnEnded(gameObject.name, "OnWebGLVideoEnded");
            string fit = "contain";
            WVO_Create(stepData.videoUrl, fit, 0 /*loop*/, 0 /*muted*/);
            WVO_Play();
        }
        catch
        {
            // si le pont JS échoue, on laissera simplement l'écran noir + skip (pas de crash)
        }

        if (stepData.skipable)
            CreateSkipButton();
        return;
#else
        // Desktop / Editor: RenderTexture plus raisonnable (évite de saturer la mémoire GPU)
        renderTexture = new RenderTexture(1280, 720, 0);
        renderTexture.Create();

        GameObject videoPlayerObj = new GameObject("VideoPlayer");
        videoPlayerObj.transform.SetParent(transform, false);

        videoPlayer = videoPlayerObj.AddComponent<VideoPlayer>();
        videoPlayer.playOnAwake = false;
        videoPlayer.renderMode = VideoRenderMode.RenderTexture;
        videoPlayer.targetTexture = renderTexture;
        videoPlayer.isLooping = false;
        videoPlayer.aspectRatio = VideoAspectRatio.FitInside;
        
        // Configuration audio AVANT de définir l'URL (important!)
        videoPlayer.audioOutputMode = VideoAudioOutputMode.AudioSource;
        videoPlayer.controlledAudioTrackCount = 1;  // Activer le contrôle de la piste audio
        
        AudioSource audioSource = videoPlayerObj.AddComponent<AudioSource>();
        audioSource.playOnAwake = false;
        audioSource.volume = 1.0f;
        audioSource.spatialBlend = 0f;  // 2D audio (pas de spatialisation 3D)
        audioSource.priority = 0;  // Priorité maximale
        audioSource.bypassEffects = false;
        audioSource.bypassListenerEffects = false;
        audioSource.bypassReverbZones = true;
        
        videoPlayer.EnableAudioTrack(0, true);  // Activer explicitement la piste audio 0
        videoPlayer.SetTargetAudioSource(0, audioSource);
        
        // Définir l'URL APRÈS la configuration audio
        videoPlayer.url = stepData.videoUrl;

        GameObject displayObj = new GameObject("VideoDisplay");
        displayObj.transform.SetParent(transform, false);

        RectTransform displayRect = displayObj.AddComponent<RectTransform>();
        displayRect.anchorMin = Vector2.zero;
        displayRect.anchorMax = Vector2.one;
        displayRect.offsetMin = Vector2.zero;
        displayRect.offsetMax = Vector2.zero;

        display = displayObj.AddComponent<RawImage>();
        display.texture = renderTexture;
        display.color = Color.white;
        display.raycastTarget = false;  // IMPORTANT: Désactiver les raycast pour que les clics ne soient pas détectés sur la vidéo

        videoPlayer.loopPointReached += OnVideoFinished;
        videoPlayer.errorReceived += OnVideoError;
        videoPlayer.prepareCompleted += OnVideoPrepared;

        if (stepData.skipable)
        {
            CreateSkipButton();
        }

        videoPlayer.Prepare();
#endif
    }

    void OnVideoPrepared(VideoPlayer vp)
    {
        // Garder seulement un log minimal pour confirmer que la vidéo est prête
        if (vp.audioTrackCount == 0)
        {
            Debug.LogWarning("[MapFullscreenVideo] ⚠️ Cette vidéo n'a AUCUNE piste audio !");
        }
    }

    void OnVideoError(VideoPlayer vp, string message)
    {
        Debug.LogError("========================================");
        Debug.LogError("❌❌❌ VIDEO ERROR ❌❌❌");
        Debug.LogError("========================================");
        Debug.LogError($"ERROR MESSAGE: {message}");
        Debug.LogError($"URL TENTEE: {stepData.videoUrl}");
        Debug.LogError($"VideoPlayer.url: {vp.url}");
        Debug.LogError($"VideoPlayer.source: {vp.source}");
        Debug.LogError($"VideoPlayer.isPrepared: {vp.isPrepared}");
        Debug.LogError($"VideoPlayer.isPlaying: {vp.isPlaying}");
        Debug.LogError("========================================");
        
        // Si erreur, passer au step suivant quand même
        if (!hasCompleted)
        {
            hasCompleted = true;
            Debug.LogWarning("[MapFullscreenVideo] ⚠️ SKIPPING VIDEO - Passage au step suivant");
            StartCoroutine(FadeOutAndFinish());
        }
    }

    void CreateSkipButton()
    {
#if UNITY_WEBGL && !UNITY_EDITOR
        // En WebGL, la vidéo est au-dessus du canvas Unity (DOM overlay).
        // Donc le bouton Unity UI serait caché -> on crée un bouton DOM "PASSER" au-dessus de la vidéo.
        if (usingWebglDomVideo)
        {
            try { WVO_ShowSkipButton("PASSER", gameObject.name, "OnWebGLSkipClicked"); } catch { }
            return;
        }
#endif

        GameObject skipObj = new GameObject("SkipButton");
        skipObj.transform.SetParent(transform, false);

        RectTransform skipRect = skipObj.AddComponent<RectTransform>();
        skipRect.anchorMin = new Vector2(1f, 0f);
        skipRect.anchorMax = new Vector2(1f, 0f);
        skipRect.pivot = new Vector2(1f, 0f);
        skipRect.sizeDelta = new Vector2(200f, 60f);
        skipRect.anchoredPosition = new Vector2(-30f, 30f);

        Image skipBg = skipObj.AddComponent<Image>();
        skipBg.color = new Color(0f, 0f, 0f, 0.7f);

        Button skipButton = skipObj.AddComponent<Button>();
        skipButton.targetGraphic = skipBg;
        skipButton.onClick.AddListener(SkipVideo);

        GameObject textObj = new GameObject("Text");
        textObj.transform.SetParent(skipObj.transform, false);

        RectTransform textRect = textObj.AddComponent<RectTransform>();
        textRect.anchorMin = Vector2.zero;
        textRect.anchorMax = Vector2.one;
        textRect.offsetMin = Vector2.zero;
        textRect.offsetMax = Vector2.zero;

        TMPro.TextMeshProUGUI skipText = textObj.AddComponent<TMPro.TextMeshProUGUI>();
        skipText.text = "PASSER";
        skipText.fontSize = 20;
        skipText.alignment = TMPro.TextAlignmentOptions.Center;
        skipText.color = Color.white;
    }

    IEnumerator FadeInAndPlay()
    {
#if UNITY_WEBGL && !UNITY_EDITOR
        if (usingWebglDomVideo)
        {
            // Pas de "Prepare" côté Unity: on fade l'UI et on laisse la vidéo DOM gérer son chargement.
            float fadeElapsedW = 0f;
            float fadeTimeW = 0.5f;
            while (fadeElapsedW < fadeTimeW)
            {
                fadeElapsedW += Time.deltaTime;
                canvasGroup.alpha = Mathf.Lerp(0f, 1f, fadeElapsedW / fadeTimeW);
                yield return null;
            }
            canvasGroup.alpha = 1f;
            canSkip = true;
            yield break;
        }
#endif

        float timeout = 10f;
        float elapsed = 0f;

        while (!videoPlayer.isPrepared && elapsed < timeout)
        {
            elapsed += Time.deltaTime;
            yield return null;
        }

        if (!videoPlayer.isPrepared)
        {
            Debug.LogError("[MapFullscreenVideo] Video preparation timeout!");
            if (!hasCompleted)
            {
                hasCompleted = true;
                StartCoroutine(FadeOutAndFinish());
            }
            yield break;
        }

        // Vérification AudioListener
        AudioListener listener = FindFirstObjectByType<AudioListener>();
        if (listener == null)
        {
            Debug.LogError("[MapFullscreenVideo] ❌ AUCUN AudioListener trouvé dans la scène !");
        }
        
        videoPlayer.Play();

        float fadeElapsed = 0f;
        float fadeTime = 0.5f;

        while (fadeElapsed < fadeTime)
        {
            fadeElapsed += Time.deltaTime;
            canvasGroup.alpha = Mathf.Lerp(0f, 1f, fadeElapsed / fadeTime);
            yield return null;
        }

        canvasGroup.alpha = 1f;
        canSkip = true;
    }

    void Update()
    {
        if (canSkip && stepData.skipable)
        {
            // Permettre le skip avec la touche Escape seulement
            if (Keyboard.current != null && Keyboard.current.escapeKey.wasPressedThisFrame)
            {
                SkipVideo();
            }
            
            // Le skip par clic souris est maintenant géré uniquement par le bouton UI
            // On ne détecte plus les clics globaux sur la vidéo
            
            // WebGL fallback pour le bouton uniquement
            #if UNITY_WEBGL && !UNITY_EDITOR
            if (WebGLClickReceiver.WasClickedThisFrame())
            {
                // Note: En WebGL, le clic sur le bouton UI sera géré par le système UI normal
                // Cette détection est pour d'autres cas spécifiques si nécessaire
            }
            #endif
        }
    }

    void SkipVideo()
    {
        if (!canSkip || hasCompleted) return;

        canSkip = false;
        hasCompleted = true;

#if UNITY_WEBGL && !UNITY_EDITOR
        if (usingWebglDomVideo)
        {
            try { WVO_HideSkipButton(); } catch { }
            try { WVO_Dispose(); } catch { }
        }
#endif
        StartCoroutine(FadeOutAndFinish());
    }

    /// <summary>
    /// Callback appelé par la .jslib quand la vidéo DOM (WebGL) se termine.
    /// </summary>
    public void OnWebGLVideoEnded()
    {
        if (hasCompleted) return;
        if (stepData != null && stepData.autoAdvance)
        {
            hasCompleted = true;
            StartCoroutine(FadeOutAndFinish());
        }
    }

    /// <summary>
    /// Callback appelé par le bouton DOM "PASSER" (WebGL).
    /// </summary>
    public void OnWebGLSkipClicked()
    {
        if (canSkip && stepData != null && stepData.skipable)
        {
            SkipVideo();
        }
    }
    
    /// <summary>
    /// Appelé par WebGLClickReceiver quand un clic est reçu depuis JavaScript
    /// </summary>
    public void OnWebGLClick()
    {
        if (canSkip && stepData.skipable)
        {
            SkipVideo();
        }
    }

    void OnVideoFinished(VideoPlayer vp)
    {
        if (hasCompleted) return;

        if (stepData.autoAdvance)
        {
            hasCompleted = true;
            StartCoroutine(FadeOutAndFinish());
        }
    }

    IEnumerator FadeOutAndFinish()
    {
        onComplete?.Invoke();

        float elapsed = 0f;
        float fadeTime = 0.5f;

        while (elapsed < fadeTime)
        {
            elapsed += Time.deltaTime;
            canvasGroup.alpha = Mathf.Lerp(1f, 0f, elapsed / fadeTime);
            yield return null;
        }

        canvasGroup.alpha = 0f;

#if UNITY_WEBGL && !UNITY_EDITOR
        if (usingWebglDomVideo)
        {
            try { WVO_HideSkipButton(); } catch { }
        }
#endif

        if (videoPlayer != null && videoPlayer.isPlaying)
        {
            videoPlayer.Stop();
        }

        Destroy(gameObject);
    }

    void OnDestroy()
    {
#if UNITY_WEBGL && !UNITY_EDITOR
        if (usingWebglDomVideo)
        {
            try { WVO_HideSkipButton(); } catch { }
            try { WVO_Dispose(); } catch { }
        }
#endif
        if (renderTexture != null)
        {
            renderTexture.Release();
            Destroy(renderTexture);
        }
    }
}