// using System;
using System;
using System.Collections.Generic;
using System.IO;

// using System.IO;

using FairyGUI;
using FGUI.LG_Common;
using FGUI.LG_live;
using SGModule.Common.Extensions;
using UnityEngine;
using UnityEngine.Video;

namespace RedHotRoast
{
    public class LiveUI : BaseUI
    {
        private const int MaxVisibleCount = 6; // 一屏最多6个播放器
        private const int PreloadCount = 2; // 上下各预加载一屏
        private static readonly Dictionary<item_live, VideoPlayer> dictionary_ = new();
        private readonly Dictionary<int, GLoader> activeLoaders = new();
        private readonly Dictionary<int, bool> _fileIsExist = new();
        private LiveUICtrl ctrl;

        private float late_time = 0.1f;
        private List<Live> LiveConfig;
        private LiveModel model;
        private com_live ui;


        private GameObject videoParent;

        public LiveUI(LiveUICtrl ctrl) : base(ctrl)
        {
            uiName = UIConst.LiveUI;
            this.ctrl = ctrl;
        }

        protected override void SetUIInfo(UIInfo uiInfo)
        {
            uiInfo.packageName = "LG_live";
            uiInfo.assetName = "com_live";
            uiInfo.layerType = UILayerType.Popup;
            uiInfo.isNeedOpenAnim = false;
            uiInfo.isNeedCloseAnim = false;
            uiInfo.isNeedUIMask = true;
        }

        private void UpdateEvent()
        {
            late_time = 0.1f;
        }

        private void Refresh(object param = null)
        {
            var index = param.As<int>();
            // ui.list_.itemRenderer = RendererList;
            // Debug.Log($"LiveConfig.Count==2=== {LiveConfig.Count}");
            // ui.list_.numItems = LiveConfig.Count;


            if (ui.list_.GetChildAt(index) is item_live item)
            {
                var livedata_ = PreDownloadManager.GetLiveDataByIndex(LiveConfig[index], index);
                item.state.selectedIndex = livedata_.progress >= 100 ? 0 : 1;
                item.img_mask.fillAmount = (float)(100 - livedata_.progress) / 100;
                BindPlayerToItem(item, index);

                if (LiveConfig[index].SubscribeUnlock == 1)
                {
                    if (livedata_.progress < 100) item.vip.selectedIndex = 1;
                    else item.vip.selectedIndex = 2;
                }
                else item.vip.selectedIndex = 0;
            }
        }

        // 初始化页面逻辑
        private void InitView()
        {
        }

        #region 生命周期

        protected override void OnInit()
        {
            videoParent = new GameObject("VideoPlayerParent");
            VideoPlayerPool.Instance.Init(videoParent, MaxVisibleCount);
        }

        protected override void OnClose()
        {
            // 归还所有播放器
            foreach (var kvp in dictionary_)
                VideoPlayerPool.Instance.ReturnPlayer(kvp.Value);

            dictionary_.Clear();
            VideoPlayerPool.Instance.DisposeAll();
            UnityEngine.Object.Destroy(videoParent);

            foreach (var t in loader_list)
                if (t != null && !t.isDisposed && t.texture != null)
                {
                    t.texture.Dispose();
                    t.texture = null;
                }

            MemoryManager.CleanMemoryMonitor();
            activeLoaders.Clear();
            _fileIsExist.Clear();

            GLoaderPool.Instance.DisposeAll();
        }

        protected override void OnBind()
        {
            ui = baseUI as com_live;
        }

        private readonly List<GLoader> loader_list = new();


        protected override void OnOpenBefore(object args)
        {
            LiveConfig = ConfigSystem.GetConfig<Live>();

            ui.list_.itemRenderer = RendererList;
            Debug.Log($"LiveConfig.Count==1=== {LiveConfig.Count}");
            ui.list_.numItems = LiveConfig.Count;

            ui.btn_close.SetClick(() => { CtrlCloseUI(); });

            InitView();

            // 滚动过程中实时刷新可见播放器
            ui.list_.scrollPane.onScroll.Add(OnScrollUpdate);
            ui.list_.scrollPane.onScrollEnd.Add(OnScrollEnd);

            // 打开页面时初始化一次
            OnScrollEnd();
        }

        private void OnScrollUpdate()
        {
            if (LiveConfig == null || LiveConfig.Count == 0) return;
            var firstVisibleIndex = ui.list_.GetFirstChildInView();
            var lastVisibleIndex = Mathf.Min(firstVisibleIndex + MaxVisibleCount - 1, ui.list_.numItems - 1);

            var startIndex = Mathf.Max(0, firstVisibleIndex - PreloadCount);
            var endIndex = Mathf.Min(ui.list_.numItems - 1, lastVisibleIndex + PreloadCount);

            // 回收超出范围 loader
            var keysToRemove = new List<int>();
            foreach (var kv in activeLoaders)
            {
                var idx = kv.Key;
                if (idx < startIndex || idx > endIndex)
                {
                    GLoaderPool.Instance.ReturnLoader(kv.Value);
                    var oldItem = ui.list_.GetChildAt(idx) as item_live;
                    if (oldItem != null) {
                        (oldItem.img_cover as com_loaderMask_circlle).loader = null;
                    }
                    keysToRemove.Add(idx);
                }
            }

            foreach (var k in keysToRemove) activeLoaders.Remove(k);

            // 分配 loader 并加载图片
            for (var i = startIndex; i <= endIndex; i++)
            {
                if (activeLoaders.ContainsKey(i)) continue;

                var item = ui.list_.GetChildAt(i) as item_live;
                if (item == null) continue;

                if ((item.img_cover as com_loaderMask_circlle).loader != null && !(item.img_cover as com_loaderMask_circlle).loader.isDisposed)
                    GLoaderPool.Instance.ReturnLoader((item.img_cover as com_loaderMask_circlle).loader);

                var loader = GLoaderPool.Instance.GetLoader();
                (item.img_cover as com_loaderMask_circlle).loader = loader;
                item.img_cover.AddChild(loader);
                loader.SetSize(item.img_cover.width, item.img_cover.height);
                item.img_cover.visible = true;

                _fileIsExist.TryGetValue(i, out var value);
                if (!value)
                {
                    var localPath = Path.Combine(TextureHelper.getResPath(), "LiveVideoCovers", LiveConfig[i].Name + "_cover" + ".jpg");
                    if (File.Exists(localPath))
                    {
                        _fileIsExist[i] = true;
                        Debug.Log($"[SetImgLoader] 本地存在，直接加载 {LiveConfig[i].Name + "_cover"}");
                        CrazyAsyKit.StartCoroutine(TextureHelper.LoadTexture(LiveConfig[i].Name + "_cover", loader, null,
                            "LiveVideoCovers/"));
                    }
                    else
                    {
                        _fileIsExist[i] = false;
                        CrazyAsyKit.StartCoroutine(LiveVideoManager.Instance.LoadCover(LiveConfig[i].Name + "_cover", tex =>
                        {
                            if (tex != null)
                            {
                                if (loader != null)
                                {
                                    loader.texture = new NTexture(tex);
                                    loader.visible = true;
                                }
                            }
                            else
                            {
                                Debug.LogWarning("封面获取失败");
                            }
                        }));
                    }
                }
                else
                {
                    CrazyAsyKit.StartCoroutine(TextureHelper.LoadTexture(LiveConfig[i].Name + "_cover", loader, null,
                        "LiveVideoCovers/"));
                }

                activeLoaders[i] = loader;
            }
        }


        private HashSet<item_live> lastVisibleItems = new();

        private void OnScrollEnd()
        {
            var tasks = new List<(GLoader loader, string fileName, Action<NTexture> callback, string folder, string localFolder)>();
            var firstVisibleIndex = ui.list_.GetFirstChildInView();
            var lastVisibleIndex = Mathf.Min(firstVisibleIndex + MaxVisibleCount - 1, ui.list_.numItems - 1);

            var startIndex = Mathf.Max(0, firstVisibleIndex - PreloadCount);
            var endIndex = Mathf.Min(ui.list_.numItems - 1, lastVisibleIndex + PreloadCount);
            for (var i = startIndex; i <= endIndex; i++)
            {
                _fileIsExist.TryGetValue(i, out var value);

                if (value) continue;
                if (ui.list_.GetChildAt(i) is item_live item)
                {    
                    if ((item.img_cover as com_loaderMask_circlle).loader != null && !(item.img_cover as com_loaderMask_circlle).loader.isDisposed)
                        GLoaderPool.Instance.ReturnLoader((item.img_cover as com_loaderMask_circlle).loader);
                    var loader = GLoaderPool.Instance.GetLoader();
                    (item.img_cover as com_loaderMask_circlle).loader = loader;
                    item.img_cover.AddChild(loader);
                    loader.SetSize(item.img_cover.width, item.img_cover.height);

                    var idx = i;
                    tasks.Add((loader, LiveConfig[i].Name + "_cover", texture =>
                    {
                        if (texture != null) _fileIsExist[idx] = true;
                    }, "LiveAlbums/", FolderNames.VideoCoversName));

                    activeLoaders[i] = loader;
                }
            }

            TextureHelper.SetImgLoaders(tasks);

            Debug.Log($"[OnScrollEnd]==lastVisibleItems=== {lastVisibleItems.Count}");
            VideoLoadScheduler.ClearAll();
            // 1️⃣ 回收上一次的可见播放器
            foreach (var oldItem in lastVisibleItems)
                if (dictionary_.TryGetValue(oldItem, out var player))
                {
                    player.Pause();
                    player.targetTexture?.Release();
                    VideoPlayerPool.Instance.ReturnPlayer(player);
                    dictionary_.Remove(oldItem);
                    oldItem.com_loader.visible = false;
                    oldItem.img_cover.visible = true;
                }

            lastVisibleItems.Clear();


            // 2️⃣ 获取当前可见项
            var firstIndex = ui.list_.GetFirstChildInView();
            var lastIndex = Mathf.Min(firstIndex + MaxVisibleCount, ui.list_.numItems);

            HashSet<item_live> newVisibleItems = new();
            for (var i = firstIndex; i < lastIndex; i++) 
            {
                if (ui.list_.GetChildAt(i) is item_live item)
                {
                    // 分配播放器
                    newVisibleItems.Add(item);
                    if (!dictionary_.ContainsKey(item))
                    {
                        var player = VideoPlayerPool.Instance.GetPlayer();
                        if (player != null)
                        {
                            dictionary_[item] = player;
                            BindPlayerToItem(item, i);
                        }
                    }    
                }
            }

            // 3️⃣ 保存为“上一次可见项”
            lastVisibleItems = newVisibleItems;
        }

        private void BindPlayerToItem(item_live item, int index)
        {
            var data = PreDownloadManager.GetLiveDataByIndex(LiveConfig[index], index);

            Debug.Log($"[绑定播放器 进度] progress==1=== {data.progress}");
            if (data.progress < 100) return;

            var player = dictionary_[item];
            var loader = item.com_loader.GetChild("loader") as GLoader;
            item.com_loader.visible = true;

            if (!loader_list.Contains(loader)) loader_list.Add(loader);

            TextureHelper.SetVideoLoader(player, loader, LiveConfig[index].Name, vp =>
            {
                if (vp != null && !item.isDisposed)
                {
                    if (data.progress >= 100)
                    {
                        item.img_cover.visible = false;
                        GameDispatcher.Instance.Dispatch(GameMsg.liveVideoLoaded);
                    }
                }
            });
        }


        private void RendererList(int index, GObject obj)
        {
            var livedata_ = PreDownloadManager.GetLiveDataByIndex(LiveConfig[index], index);

            var item = (item_live)obj;

            // UI状态显示
            item.state.selectedIndex = livedata_.progress < 100 ? 1 : 0;

            if (LiveConfig[index].SubscribeUnlock == 1)
            {
                if (livedata_.progress < 100) item.vip.selectedIndex = 1;
                else item.vip.selectedIndex = 2;
            }
            else item.vip.selectedIndex = 0;

            item.img_mask.fillAmount = (float)(100 - livedata_.progress) / 100;

            // 点击事件
            item.SetClick(() =>
            {
                if (GameHelper.GetLevel() < GameHelper.GetCommonModel().UnlockLive[1])
                {
                    if (DataMgr.IsUnlockLive.Value < 0 && !GameHelper.GetVipPrivilege(Subscription.UnlockLive.As<int>()))
                        UICtrlDispatcher.Instance.Dispatch(UICtrlMsg.SecretUnlockUI_Open, 2);
                    else if (DataMgr.IsUnlockLive.Value == 0)
                        UICtrlDispatcher.Instance.Dispatch(UICtrlMsg.UnlockTipsUI_Open, 2);
                    else
                        HandleDetailOpen(item, index);
                }
                else
                {
                    HandleDetailOpen(item, index);
                }
            });
        }

        private void HandleDetailOpen(item_live item, int index)
        {
            dictionary_.TryGetValue(item, out var player);
            // if (dictionary_.TryGetValue(item, out var player))
                uiCtrlDispatcher.Dispatch(UICtrlMsg.LiveDetailUI_Open, (index, player));
        }

        protected override void OnOpen(object args)
        {
        }

        protected override void OnHide()
        {
        }

        protected override void OnDisplay(object args)
        {
        }

        #endregion

        #region 消息

        protected override void AddListener()
        {
            GameDispatcher.Instance.AddListener(GameMsg.LiveChange, Refresh);
            HallManager.Instance.UpdateEvent += UpdateEvent;
        }

        protected override void RemoveListener()
        {
            GameDispatcher.Instance.RemoveListener(GameMsg.LiveChange, Refresh);
            HallManager.Instance.UpdateEvent -= UpdateEvent;
        }

        #endregion
    }

    public class LiveData
    {
        public int AD_num;
        public int progress;
        public int Singleprogress;
        public long LiveADTime;
    }
}