using System;
using System.Collections.Generic;
using System.IO;
using FairyGUI;
using FGUI.LG_secretAlbums;
using SGModule.NetKit;
using UnityEngine;

namespace RedHotRoast
{
    public class SecretAlbumsUI : BaseUI
    {
        private const int MaxVisibleCount = 6; // 一屏显示6个
        private const int PreloadCount = 2; // 上下各预加载一屏

        private readonly Dictionary<int, bool> _fileIsExist = new();
        private readonly Dictionary<int, GLoader> activeLoaders = new();
        private SecretAlbumsUICtrl ctrl;
        private SecretAlbumsModel model;
        private com_scAlbums ui;

        public SecretAlbumsUI(SecretAlbumsUICtrl ctrl) : base(ctrl)
        {
            uiName = UIConst.SecretAlbumsUI;
            this.ctrl = ctrl;
        }

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

        private void UnlockSuccess(object str = null)
        {
            ui.sc_list.itemRenderer = ItemRender;
            ui.sc_list.numItems = _secretData.Count;
        }


        // 初始化页面逻辑
        private void InitView()
        {
            ui.btn_gold.GetChild("text_gold").text = GameHelper.Get101Str();
            ui.btn_close.SetClick(CtrlCloseUI);

            UnlockSuccess();


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

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

        private void InitScroll()
        {
            ui.sc_list.scrollPane.onScroll.Add(OnScrollUpdate);
            ui.sc_list.scrollPane.onScrollEnd.Add(OnScrollEnd); // 保留结束时的整理

            OnScrollEnd();
        }

        // 滑动过程中实时更新
        private void OnScrollUpdate()
        {
            UpdateVisibleAndPreload();
        }

        // 核心刷新逻辑
        private void UpdateVisibleAndPreload()
        {
            if (_secretData == null || _secretData.Count == 0) return;

            var firstVisibleIndex = ui.sc_list.GetFirstChildInView();
            var lastVisibleIndex = Mathf.Min(firstVisibleIndex + MaxVisibleCount - 1, ui.sc_list.numItems - 1);

            var startIndex = Mathf.Max(0, firstVisibleIndex - PreloadCount);
            var endIndex = Mathf.Min(ui.sc_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.sc_list.GetChildAt(idx) as item_scalnums;
                    if (oldItem != null) oldItem.com_pic.picture = 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.sc_list.GetChildAt(i) as item_scalnums;
                if (item == null) continue;

                if (item.com_pic.picture != null && !item.com_pic.picture.isDisposed)
                    GLoaderPool.Instance.ReturnLoader(item.com_pic.picture);

                var loader = GLoaderPool.Instance.GetLoader();
                item.com_pic.picture = loader;
                item.com_pic.AddChild(loader);
                loader.SetSize(item.com_pic.width, item.com_pic.height);

                _fileIsExist.TryGetValue(i, out var value);
                if (!value)
                {
                    var localPath = Path.Combine(TextureHelper.getResPath(), _secretData[i].Name + ".jpg");

                    if (File.Exists(localPath))
                    {
                        _fileIsExist[i] = true;
                        Debug.Log($"[SetImgLoader] 本地存在，直接加载 {_secretData[i].Name}");
                        CrazyAsyKit.StartCoroutine(TextureHelper.LoadTexture(_secretData[i].Name, loader, null,
                            "SecretAlbums/"));
                    }
                    else
                    {
                        _fileIsExist[i] = false;
                    }
                }
                else
                {
                    CrazyAsyKit.StartCoroutine(TextureHelper.LoadTexture(_secretData[i].Name, loader, null,
                        "SecretAlbums/"));
                }

                activeLoaders[i] = loader;
            }

            // Debug.Log($"[ScrollUpdate] active loaders={activeLoaders.Count}, pool={GLoaderPool.Instance.GetPoolCount()}, inUse={GLoaderPool.Instance.GetInUseCount()}");
        }

        private void OnScrollEnd()
        {
            if (_secretData == null || _secretData.Count == 0) return;

            var firstVisibleIndex = ui.sc_list.GetFirstChildInView();
            var lastVisibleIndex = Mathf.Min(firstVisibleIndex + MaxVisibleCount - 1, ui.sc_list.numItems - 1);

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

            // Debug.Log($"[ScrollEnd] start index={startIndex} end index={endIndex}");


            var tasks = new List<(GLoader loader, string fileName, Action<NTexture> callback, string folder, string localFolder)>();
            // 分配 loader 并加载图片
            for (var i = startIndex; i <= endIndex; i++)
            {
                _fileIsExist.TryGetValue(i, out var value);

                if (value) continue;
                var item = ui.sc_list.GetChildAt(i) as item_scalnums;
                if (item == null) continue;
                if (item.com_pic.picture != null && !item.com_pic.picture.isDisposed)
                    GLoaderPool.Instance.ReturnLoader(item.com_pic.picture);
                var loader = GLoaderPool.Instance.GetLoader();
                item.com_pic.picture = loader;
                item.com_pic.AddChild(loader);
                loader.SetSize(item.com_pic.width, item.com_pic.height);

                var idx = i;
                tasks.Add((loader, _secretData[i].Name, texture =>
                {
                    if (texture != null) _fileIsExist[idx] = true;
                }, "SecretAlbums/", FolderNames.SecretName));

                activeLoaders[i] = loader;
            }

            TextureHelper.SetImgLoaders(tasks);
        }


        private void ItemRender(int index, GObject obj)
        {
            var item = (item_scalnums)obj;

            item.text_id.text = _secretData[index].id.ToString();

            var isUnlock = DataMgr.SecretUnlockList.Value.Contains(index);

            item.btn_unlock.pay_type.selectedIndex = _secretData[index].PayType;

            if (_secretData[index].PayType == 0)
                item.btn_unlock.title = GameHelper.getPrice((decimal)_secretData[index].DiscountPrice);
            else if (_secretData[index].PayType == 1)
                item.btn_unlock.title = _secretData[index].GoldCoins.ToString();
            else if (_secretData[index].PayType == 2) item.btn_unlock.title = _secretData[index].AD + "AD";

            if (isUnlock)
            {
                item.btn_unlock.pay_type.selectedIndex = 3;
                if (_secretData[index].SubscribeUnlock == 1)
                {
                    item.vip.selectedIndex = 1;
                    item.btn_unlock.pay_type.selectedIndex = 5;
                }
                item.btn_unlock.title = Language.GetContent("go");
            }
            else
            {
                if (_secretData[index].SubscribeUnlock == 1)
                {
                    item.vip.selectedIndex = 1;
                    item.btn_unlock.pay_type.selectedIndex = 4;
                }
            }

            item.btn_null.SetClick(GotoNext);

            item.un_lock.selectedIndex = isUnlock ? 1 : 0;

            item.btn_unlock.SetClick(GotoNext);

            item.peple_num.text = GetPepleNum(_secretData[index].Quantity).ToString();

            item.hot.selectedIndex = _secretData[index].HotType;

            void GotoNext()
            {
                var data = new AlbumPreviewData
                {
                    Index = index,
                    State = _secretData[index].State,
                    Price = _secretData[index].Price,
                    PayType = _secretData[index].PayType,
                    SubscribeUnlock = _secretData[index].SubscribeUnlock,
                    DiscountPrice = _secretData[index].DiscountPrice,
                    Name = _secretData[index].Name,
                    Name2 = _secretData[index].Name2,
                    GoldCoins = _secretData[index].GoldCoins,
                    AD = _secretData[index].AD,
                    CD = _secretData[index].CD
                };
                UICtrlDispatcher.Instance.Dispatch(UICtrlMsg.SecretAlbumsNextUI_Open, data);
            }
        }

        private int GetPepleNum(float quantity)
        {
            // 获取当前时间
            var now = DateTime.Now;

            // 计算当天已经过去的分钟数（从凌晨 0 点开始算）
            var minutesPassedToday = now.Hour * 60 + now.Minute;

            // 计算人数
            var num = Mathf.FloorToInt(quantity * minutesPassedToday);

            return num;
        }

        #region 生命周期

        protected override void OnInit()
        {
            // 初始化GLoader池，设置最大缓存数
            GLoaderPool.Instance.Init(null, 10, 464, 642);
        }

        protected override void OnClose()
        {
            // 1. 解除 UI 对 Loader 的引用
            for (var i = 0; i < ui.sc_list.numChildren; i++)
            {
                var item = ui.sc_list.GetChildAt(i) as item_scalnums;
                if (item != null && item.com_pic.picture != null) item.com_pic.picture = null; // 清掉 GLoader 引用
            }

            activeLoaders.Clear();
            _fileIsExist.Clear();

            GLoaderPool.Instance.DisposeAll();

            TextureHelper.ClearMaterialPool();

            // 强制卸载未使用的资源
            Resources.UnloadUnusedAssets();
            MemoryManager.CleanMemoryMonitor();
        }

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

        private List<SecretAlbums> _secretData = new();

        protected override void OnOpenBefore(object args)
        {
            if (Screen.safeArea.y != 0)
            {
                ui.btn_gold.y += 68;
                ui.btn_close.y += 68;
                ui.sc_list.y += 68;
            }

            var eventName = GameHelper.IsAdModelOfPay() ? ADEventTrack.Event : ADEventTrack.MaxPayEvent;
            TrackKit.SendEvent(eventName, ADEventTrack.Property.shop_show);

            _secretData = ConfigSystem.GetConfig<SecretAlbums>();
            InitView();
        }

        protected override void OnOpen(object args)
        {
        }

        protected override void OnHide()
        {
        }

        protected override void OnDisplay(object args)
        {
        }

        #endregion

        #region 消息
        public void SetTopCurr(object a = null)
        {
            ui.btn_gold.GetChild("text_gold").text = GameHelper.Get101Str();
        }
        protected override void AddListener()
        {
            GameDispatcher.Instance.AddListener(GameMsg.UnlockSecretSuccess, UnlockSuccess);
            GameDispatcher.Instance.AddListener(GameMsg.Update101, SetTopCurr);
        }

        protected override void RemoveListener()
        {
            GameDispatcher.Instance.RemoveListener(GameMsg.UnlockSecretSuccess, UnlockSuccess);
            GameDispatcher.Instance.RemoveListener(GameMsg.Update101, SetTopCurr);
        }

        #endregion
    }

    public class AlbumPreviewData
    {
        public int AD;
        public int CD;
        public float DiscountPrice;
        public int GoldCoins;
        public int Index;
        public string Name;
        public string Name2;
        public int PayType;
        public float Price;
        public int[] State;
        public int SubscribeUnlock;
    }

    public enum UnlockPayType
    {
        Pay = 0,
        Coin = 1,
        Ad = 2,
        None = 3
    }
}