using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using FairyGUI;
using RedHotRoast;
using SGModule.Common;
using SGModule.NetKit;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.Video;
using Object = UnityEngine.Object;

public class TextureHelper
{
    public static void GetNTexture(string path, string name, UnityAction<NTexture> action)
    {
        if (!nTexturesDic.TryGetValue(path + name, out var spr))
            try
            {
                LoadKit.Instance.LoadSprite(path, name, sprite =>
                {
                    if (sprite != null)
                    {
                        spr = new NTexture(sprite);
                        action?.Invoke(spr);
                        nTexturesDic.TryAdd(path + name, spr);
                    }
                });
            }
            catch (Exception e)
            {
                Debug.LogError(e);
            }
        else
            action?.Invoke(spr);
    }


    public static void GetItemIcon(int itemId, UnityAction<NTexture> action = null)
    {
        var itemIconPath = "Atlas.Item";
        var name = itemId.ToString();
        if (!true)
            if (itemId is 101 or 111)
                name = "102";

        if (itemId is 102 or 106) name += "_normal";

        GetNTexture(itemIconPath, name, action);
    }


    public static IEnumerator GetGalleryFromNet(int imageID, Action<bool> action = null)
    {
        if (imageID == 0)
        {
            action?.Invoke(true);
        }
        else
        {
            var picInfoUrl = $"{LoginKit.Instance.LoginModel.CdnURL}gallery/{imageID}.jpg";
            yield return GetTextureFromNet("Gallery", imageID, picInfoUrl, action);
        }
    }

    public static string GetBankIconUrl(string icon_name)
    {
        return string.Format("ui://G002_main/{0}", icon_name);
    }

    public static void GetGalleryLocal(int imageID, Action<NTexture> action)
    {
        if (!galleryNTexturesDic.TryGetValue(imageID, out var spr))
        {
            var path = $"Gallery/{imageID}";
            var asset = Resources.Load($"Atlas/{path}");
            if (asset)
            {
            }
            else
            {
                CrazyAsyKit.StartCoroutine(GetGalleryFromNet(imageID, isSuccess =>
                {
                    if (isSuccess)
                        CrazyAsyKit.StartCoroutine(GetLocalTexture($"{path}.jpg", texture =>
                        {
                            if (texture == null)
                            {
                                action?.Invoke(null);

                                return;
                            }

                            var spr1 = new NTexture(texture);
                            galleryNTexturesDic.TryAdd(imageID, spr1);
                            action?.Invoke(spr1);
                        }));
                    else
                        action?.Invoke(null);
                }));
            }
        }
        else
        {
            action?.Invoke(spr);
        }
    }

    #region 缓存

    private static readonly Dictionary<string, NTexture> nTexturesDic = new();
    private static readonly Dictionary<int, NTexture> avatarNTexturesDic = new();
    private static readonly Dictionary<int, NTexture> galleryNTexturesDic = new();

    #endregion

    #region 加载Texture

    private static IEnumerator GetLocalTexture(string imagePath, Action<Texture> action)
    {
        var file = $"{Application.persistentDataPath}/{imagePath}";
        var fileInfo = new FileInfo(file);
        if (!fileInfo.Exists)
        {
            action?.Invoke(null);
            yield break;
        }

        var avatarPath = $"file://{file}";
        var uwr = UnityWebRequestTexture.GetTexture(avatarPath);
        yield return uwr.SendWebRequest();
        if (uwr.result is UnityWebRequest.Result.ConnectionError or UnityWebRequest.Result.ProtocolError)
        {
            action?.Invoke(null);
            yield break;
        }

        var texture2D = DownloadHandlerTexture.GetContent(uwr);

        action?.Invoke(texture2D);
    }

    private class DownloadTask
    {
        public Action<NTexture> Callback;
        public string FileName;
        public string Folder;
        public GLoader Loader;
        public string LocalFolder;
        public bool IsGameBg;

    }

    public static string imgUrl = "";

    // 普通队列
    private static readonly Queue<DownloadTask> normalQueue = new();

    private static Coroutine normalCoroutine;

    // 优先队列
    private static readonly Queue<DownloadTask> priorityQueue = new();
    private static Coroutine priorityCoroutine;


    // ====================== 并发配置 ======================
    private static int maxPriorityConcurrent = 3; // ✅ 可配置最大并发数
    private static int priorityRunning = 0;       // 当前正在运行的任务数

    #region 材质池

    private static class MaterialPool
    {
        private static readonly Stack<Material> blurMats = new();
        private static readonly Stack<Material> normalMats = new();

        public static Material GetBlur()
        {
            if (blurMats.Count > 0) return blurMats.Pop();
            var shader = Resources.Load<Shader>("RedHotRoastAssets/Shader/Blur");
            if (!shader) return null;
            return new Material(shader);
        }

        public static Material GetNormal()
        {
            if (normalMats.Count > 0) return normalMats.Pop();
            var shader = Resources.Load<Shader>("RedHotRoastAssets/Shader/FairyGUI/FairyGUI-Image");
            if (!shader) return null;
            return new Material(shader);
        }

        public static void Return(Material mat)
        {
            if (!mat) return;
            var name = mat.shader.name;
            if (name.Contains("Blur")) blurMats.Push(mat);
            else normalMats.Push(mat);
        }

        public static void Clear()
        {
            foreach (var mat in blurMats) Object.Destroy(mat);
            blurMats.Clear();
            foreach (var mat in normalMats) Object.Destroy(mat);
            normalMats.Clear();
        }
    }

    #endregion

    #region 图片加载接口

    public static string getResPath()
    {
        // 删除旧资源
        if (!DataMgr.curResVersion.Value.IsNullOrWhiteSpace() && DataMgr.curResVersion.Value != ConfigSystem.GetCommonConf().ResVersion)
        {
            var oldFolder = Path.Combine(Application.persistentDataPath, DataMgr.curResVersion.Value);
            if (Directory.Exists(oldFolder))
            {
                Directory.Delete(oldFolder, true);
            }
            DataMgr.curResVersion.Value = ConfigSystem.GetCommonConf().ResVersion;
        }
        else if (DataMgr.curResVersion.Value.IsNullOrWhiteSpace())
        {
            DataMgr.curResVersion.Value = ConfigSystem.GetCommonConf().ResVersion;
        }

        if (ConfigSystem.GetCommonConf().ResVersion.IsNullOrWhiteSpace())
        {
            Debug.LogError("获取资源路径失败");
            return Application.persistentDataPath;
        }

        string curFolder = Path.Combine(Application.persistentDataPath, ConfigSystem.GetCommonConf().ResVersion);
        return curFolder;
    }

    public static void SetImgLoader(GLoader loader, string fileName, Action<NTexture> callback,
        string folder, string localFolder, bool priority = true, bool isLoad = false, bool isGameBg = false)
    {
        var localPath = Path.Combine(getResPath(), localFolder, fileName + ".jpg");
        if (File.Exists(localPath))
        {
            Debug.Log($"[SetImgLoader] 本地存在，直接加载 {fileName}");
            CrazyAsyKit.StartCoroutine(LoadTexture(fileName, loader, callback, localFolder, isGameBg));
            return;
        }

        if (isLoad)
        {
            Debug.Log($"[SetImgLoader] 兼容老逻辑，直接加载 {fileName}");
            return;
        }

        var task = new DownloadTask
        {
            Loader = loader,
            FileName = fileName,
            Folder = folder,
            Callback = callback,
            LocalFolder = localFolder,
            IsGameBg = isGameBg

        };

        if (priority)
            EnqueuePriorityTask(task, isBatch: false); // 👈 单任务标记
        else
            EnqueueNormalTask(loader, fileName, callback, folder, localFolder);
    }


    /// <summary>
    ///     批量加载任务（优先队列，串行）
    /// </summary>
    public static void SetImgLoaders(
        List<(GLoader loader, string fileName, Action<NTexture> callback, string folder, string localFolder)> tasks)
    {
        Debug.Log($"[BatchSetImgLoader] 收到 {tasks.Count} 个任务");

        // 清空旧任务（批量任务才清空）
        if (priorityCoroutine != null)
        {
            CrazyAsyKit.StopCoroutine(priorityCoroutine);
            priorityCoroutine = null;
        }

        priorityQueue.Clear();

        foreach (var task in tasks)
        {
            var downloadTask = new DownloadTask
            {
                Loader = task.loader,
                FileName = task.fileName,
                Folder = task.folder,
                Callback = task.callback,
                LocalFolder = task.localFolder,
                IsGameBg = false

            };

            EnqueuePriorityTask(downloadTask, isBatch: true); // 👈 批量标记
        }

        if (priorityCoroutine == null)
            priorityCoroutine = CrazyAsyKit.StartCoroutine(ProcessPriorityQueue());
    }


    private static void EnqueuePriorityTask(DownloadTask task, bool isBatch)
    {
        // 去重：如果已在队列中就跳过
        foreach (var queued in priorityQueue)
        {
            if (queued.FileName == task.FileName)
            {
                Debug.Log($"[PriorityQueue] 跳过重复任务 {task.FileName}");
                return;
            }
        }

        if (isBatch)
            Debug.Log($"[PriorityQueue] 批量添加任务 {task.FileName}");
        else
            Debug.Log($"[PriorityQueue] 单任务添加 {task.FileName}");

        priorityQueue.Enqueue(task);

        if (priorityCoroutine == null)
            priorityCoroutine = CrazyAsyKit.StartCoroutine(ProcessPriorityQueue());
    }


    #endregion

    #region 普通队列逻辑

    private static void EnqueueNormalTask(GLoader loader, string fileName, Action<NTexture> callback, string folder, string localFolder)
    {
        normalQueue.Enqueue(new DownloadTask
        {
            Loader = loader,
            FileName = fileName,
            Folder = folder,
            Callback = callback,
            LocalFolder = localFolder
        });

        if (normalCoroutine == null)
            normalCoroutine = CrazyAsyKit.StartCoroutine(ProcessNormalQueue());
    }

    private static IEnumerator ProcessNormalQueue()
    {
        while (normalQueue.Count > 0)
        {
            var task = normalQueue.Dequeue();
            yield return DownloadCoroutine(task);
        }

        normalCoroutine = null;
    }

    private static IEnumerator ProcessPriorityQueue()
    {
        while (priorityQueue.Count > 0 || priorityRunning > 0)
        {
            // 如果没达到最大并发，就从队列里拉一个任务出来
            while (priorityRunning < maxPriorityConcurrent && priorityQueue.Count > 0)
            {
                var task = priorityQueue.Dequeue();
                priorityRunning++;
                Debug.Log($"[PriorityQueue] 开始下载 {task.FileName}");

                // 启动一个子协程跑下载
                CrazyAsyKit.StartCoroutine(RunPriorityTask(task));
            }

            yield return null; // 每帧检查一次
        }

        priorityCoroutine = null;
        Debug.Log("[PriorityQueue] 批量任务完成");
    }


    private static IEnumerator RunPriorityTask(DownloadTask task)
    {
        yield return DownloadCoroutine(task);

        priorityRunning--;
        Debug.Log($"[PriorityQueue] 完成 {task.FileName}");
    }

    private static IEnumerator DownloadCoroutine(DownloadTask task)
    {
        var localPath = Path.Combine(getResPath(), task.LocalFolder, task.FileName + ".jpg");

        var tempPath = localPath + ".tmp";
        var url = imgUrl + task.Folder + task.FileName + ".jpg";
        Debug.Log($"[Download] 下载 tempPath=0== {tempPath}  \n url==={url}");
        if (File.Exists(localPath))
        {
            Debug.Log($"[SetImgLoader] 本地存在，直接加载 {task.FileName}");
            yield return LoadTexture(task.FileName, task.Loader, task.Callback, task.LocalFolder, task.IsGameBg);
            yield break;
        }

        // ⚠️ 确保遗留的临时文件被清理掉
        Debug.Log($"[Download] tempPath=1== {tempPath}");
        if (File.Exists(tempPath))
        {
            Debug.Log($"[Download] 删除遗留临时文件 {tempPath}");
            File.Delete(tempPath);
        }

        // 确保目录存在
        string tempDir = Path.GetDirectoryName(tempPath);
        if (!Directory.Exists(tempDir))
        {
            Directory.CreateDirectory(tempDir);
        }

        var attempt = 0;
        while (attempt < 3)
        {
            Debug.Log($"[Download] 正在下载 {task.FileName}  次数：{attempt}");
            attempt++;
            using (var www = UnityWebRequest.Get(url))
            {
                yield return www.SendWebRequest();
                if (www.result == UnityWebRequest.Result.Success)
                {
                    try
                    {
                        Debug.Log($"[Download] 下载成功，保存临时文件 {tempPath}");
                        File.WriteAllBytes(tempPath, www.downloadHandler.data);

                        if (File.Exists(localPath)) File.Delete(localPath);

                        File.Move(tempPath, localPath);
                        // 解密文件
                        // Debug.Log($"[Download] 开始解密文件 {task.FileName}");
                        // Rescrypt.DecryptFile(tempPath, localPath, ConfigManager.GameConfig.packageName);
                        // Debug.Log($"[Download] 解密完成，保存路径：{localPath}");
                    }
                    catch (Exception e)
                    {
                        Debug.LogError($"[Download] 解密或保存失败：{e}");
                        yield break;
                    }

                    if (task.Loader != null)
                        yield return LoadTexture(task.FileName, task.Loader, task.Callback, task.LocalFolder, task.IsGameBg);
                    yield break;
                }

                yield return new WaitForSeconds(1f);
            }
        }

        task.Callback?.Invoke(null);
    }

// 用字典记录每个 loader 的当前请求
private static readonly Dictionary<GLoader, UnityWebRequest> loaderRequests = new();

public static IEnumerator LoadTexture(string fileName, GLoader loader, Action<NTexture> callback = null,
    string folder = "", bool isGameBg = false)
{
    string encryptedPath = Path.Combine(getResPath(), folder, fileName + ".jpg");

    if (!File.Exists(encryptedPath))
    {
        Debug.LogWarning($"[LoadEncryptedTexture] 加密文件不存在: {encryptedPath}");
        callback?.Invoke(null);
        yield break;
    }

    Debug.Log($"[LoadTexture] 开始加载本地图片 {fileName}");

    // 如果这个 loader 已经有旧请求，先取消掉
    if (loader != null && loaderRequests.TryGetValue(loader, out var oldReq))
    {
        if (!oldReq.isDone)
        {
            Debug.Log($"[LoadTexture] 取消上一次未完成的加载 {fileName}");
            oldReq.Abort();
        }
        loaderRequests.Remove(loader);
    }

    using (var www = UnityWebRequestTexture.GetTexture("file://" + GetDecryptedImagePath(fileName, folder)))
    {
        // 记录当前请求
        if (loader != null) loaderRequests[loader] = www;

        yield return www.SendWebRequest();

        // 如果这个 loader 的请求已经被替换，就直接丢弃结果
        if (loader != null && (!loaderRequests.ContainsKey(loader) || loaderRequests[loader] != www))
        {
            Debug.Log($"[LoadTexture] 请求已被新任务替换，丢弃结果 {fileName}");
            yield break;
        }

        if (loader != null)  loaderRequests.Remove(loader);

        if (www.result == UnityWebRequest.Result.Success)
        {
            var tex = DownloadHandlerTexture.GetContent(www);
            var nTex = new NTexture(tex) { destroyMethod = DestroyMethod.Destroy };
            tex.name = fileName;

            // 清理旧纹理
            if (loader != null && loader.texture != null)
            {
                loader.texture.Dispose();
                if (loader.texture.nativeTexture != null)
                {
                    UnityEngine.Object.Destroy(loader.texture.nativeTexture);
                }
                loader.texture = null;
            }

            if (loader != null && !loader.isDisposed)
            {
                loader.texture = nTex;
                Debug.Log($"[LoadTexture] 图片已设置到 Loader {fileName}");
                callback?.Invoke(nTex);
            }
            else
            {
                Debug.Log($"[LoadTexture] Loader 不存在或已销毁 {fileName}");
            }

            if (isGameBg)
            {
                callback?.Invoke(nTex);
            }
        }
        else
        {
            Debug.LogError($"[LoadTexture] 加载失败 {www.error}");
            callback?.Invoke(null);
        }
    }

    if (loader != null && !loader.isDisposed)
        loader.visible = true;
}

    public static string GetDecryptedImagePath(string fileName, string localFolder)
    {
        string tempPath = Path.Combine(Application.temporaryCachePath, FolderNames.GameCache, localFolder, fileName + "_temp.jpg");
        // Debug.Log($"获取解密路径: {tempPath}");

        if (!File.Exists(tempPath))
        {
            Debug.Log($"！！！！！！！！！！！！临时文件不存在: {fileName}");
            // 确保目录存在
            Directory.CreateDirectory(Path.GetDirectoryName(tempPath));

            string encPath = Path.Combine(getResPath(), localFolder, fileName + ".jpg");
            Debug.Log(encPath);
            if (!File.Exists(encPath)) return null;
            Debug.Log($"！！！！！！！！！！！！写入一张: {fileName}");
            byte[] decryptedBytes = Rescrypt.DecryptFileToBytes(encPath);
            File.WriteAllBytes(tempPath, decryptedBytes);
        }
        return tempPath;
    }

    public static IEnumerator WriteTempBeforeOpenCoroutine_()
    {
        System.Diagnostics.Stopwatch stopwatch = System.Diagnostics.Stopwatch.StartNew();

        var levelUnlocks = ConfigSystem.GetConfig<LevelUnlock>();
        var FreeImageLibrary_ = ConfigSystem.GetConfig<FreeImageLibrary>();
        var ADImageLibrary_ = ConfigSystem.GetConfig<ADImageLibrary>();
        var SpecialImageLibrary_ = ConfigSystem.GetConfig<SpecialImageLibrary>();
        var VIPImageLibrary_ = ConfigSystem.GetConfig<VIPImageLibrary>();
        for (int i = 0; i < GameHelper.GetCommonModel().MultiModal - 1; i++)
        {
            GetDecryptedImagePath(levelUnlocks[i].Name, FolderNames.AlbumName);
            yield return null;
        }
        var LevelUnlockListNew = DataMgr.LevelUnlockListNew.Value;
        for (int i = 0; i <LevelUnlockListNew.Count; i++)
        {
            switch (LevelUnlockListNew[i].type)
            {
                case 0:
                    GetDecryptedImagePath(FreeImageLibrary_[LevelUnlockListNew[i].config_index].Name, FolderNames.AlbumName);
                    break;
                case 1:
                    GetDecryptedImagePath(ADImageLibrary_[LevelUnlockListNew[i].config_index].Name, FolderNames.AlbumName);
                    break;
                case 2:
                    GetDecryptedImagePath(SpecialImageLibrary_[LevelUnlockListNew[i].config_index].Name, FolderNames.AlbumName);
                    break;
                case 3:
                    GetDecryptedImagePath(VIPImageLibrary_[LevelUnlockListNew[i].config_index].Name, FolderNames.AlbumName);
                    break;
            }
            yield return null;
        }

        stopwatch.Stop();
        UnityEngine.Debug.Log($"WriteTempBeforeOpen 协程执行耗时: {stopwatch.ElapsedMilliseconds} 毫秒");
    }


    #endregion


    private static IEnumerator WaitForReady(VideoPlayer player, Action onReady)
    {
        while (!player.isPrepared)
            yield return null;

        onReady?.Invoke();
    }

    public static void SaveImageToAlbum(string fileName, string encryptedFolder, Action onSuccess = null)
    {
        try
        {
            // 加密图片路径
            string encryptedPath = Path.Combine(getResPath(), encryptedFolder, fileName + ".jpg");

            if (!File.Exists(encryptedPath))
            {
                Debug.LogWarning($"加密图片不存在: {encryptedPath}");
                return;
            }

            // 解密为字节数组
            byte[] decryptedBytes = Rescrypt.DecryptFileToBytes(encryptedPath);

            // 写入临时路径（系统可访问）
            string tempPath = Path.Combine(Application.temporaryCachePath, fileName + "_temp.jpg");
            File.WriteAllBytes(tempPath, decryptedBytes);
            BrigdeIOS.SaveImageWithCustomDate(tempPath);

            // 保存到系统相册
            //             NativeGallery.SaveImageToGallery(tempPath, "MyAlbum", fileName + ".jpg", (bool success, string path) =>
            //             {
            //                 if (success)
            //                 {
            //                     GameHelper.ShowTips("save_successed", true);
            //                     onSuccess?.Invoke();
            //                 }
            //                 else
            //                 {
            //                     Debug.LogWarning("保存到相册失败");
            //                 }
            // 
            //                 // 可选：清理临时文件
            //                 if (File.Exists(tempPath))
            //                     File.Delete(tempPath);
            //             });
        }
        catch (Exception ex)
        {
            Debug.LogError($"保存加密图片到相册失败: {ex.Message}");
        }
    }


    public static void SaveVideoToAlbum(string fileName, Action onSuccess = null)
    {
        try
        {
            string localPath = Path.Combine(getResPath(), FolderNames.VideoName, fileName + ".mp4");
            BrigdeIOS.SaveVideoWithCustomDate(localPath);
            //             File.SetCreationTime(localPath, DateTime.Now);
            //             File.SetCreationTimeUtc(localPath, DateTime.Now);
            //             File.SetLastWriteTime(localPath, DateTime.Now);
            //             File.SetLastWriteTimeUtc(localPath, DateTime.Now);
            //             // CrazyAsyKit.StartCoroutine(GetSaveVideo(fileName, (isSuccess) =>
            //             // {
            // 
            //             // }));
            //             NativeGallery.SaveVideoToGallery(localPath, "MyAlbum", "my_video.mp4", (bool success, string path) =>
            //             {
            //                 if (success)
            //                 {
            //                     GameHelper.ShowTips("save_successed", true);
            //                     onSuccess?.Invoke();
            //                 }
            //             });
        }
        catch (Exception ex)
        {
            Debug.LogError($"保存加密视频到相册失败: {ex.Message}");
        }
    }



    public static void SetVideoLoader(VideoPlayer player, GLoader loader, string fileName,
        Action<VideoPlayer> action = null, bool play = true)
    {

        VideoLoadScheduler.EnqueueLoad(player, fileName, loader, videoPlayer =>
        {
            Debug.Log("RendererList------视频加载成功！-" + fileName);
            Debug.Log("[绑定播放器 EnqueueLoad]=========1=== ");
            if (videoPlayer != null)
            {
                Debug.Log("视频加载成功！");
                action?.Invoke(videoPlayer);
            }
            else
            {
                Debug.Log("视频加载失败！");
                VideoPlayerPool.Instance.ReturnPlayer(player);
                action?.Invoke(null);
            }
        }, play);
    }

    public static void SetImageMosaic(GLoader loader, int num = 80)
    {
        var shader = Resources.Load<Shader>("RedHotRoastAssets/Shader/Mosaic");
        if (shader == null)
        {
            Debug.LogError("找不到 Shader：Custom/Mosaic。请确保 shader 名称正确并已包含到构建中。");
            return;
        }

        var material = new Material(shader);
        material.SetFloat("_BlockSize", num); // 假设你 shader 中的 blockSize 参数是这个
        loader.material = material;
    }

    #region 材质处理

    public static void SetImageBlur(GLoader loader)
    {
        if (loader == null || loader.isDisposed || loader.texture == null || loader.material.name == "Custom/Blur") return;
        if (loader.material != null) MaterialPool.Return(loader.material);
        loader.material = MaterialPool.GetBlur();
    }

    public static void CancelImageBlur(GLoader loader)
    {
        if (loader == null || loader.isDisposed || loader.texture == null || loader.material == null || loader.material.name != "Custom/Blur") return;

        if (loader.material != null) MaterialPool.Return(loader.material);
        loader.material = MaterialPool.GetNormal();
    }

    #endregion

    /// <summary>
    ///     彻底清理材质池（切场景/退出游戏时调用）
    /// </summary>
    public static void ClearMaterialPool()
    {
        MaterialPool.Clear();
    }

    private static Sprite _currentBackgroundSprite;
    private static SpriteRenderer _spriteRenderer;
    private static NTexture _currentNTexture; // 新增：缓存 NTexture
    public static void setGamebg(string fileName)
    {
        // 只获取一次组件
        if (_spriteRenderer == null)
        {
            var go = GameObject.Find("game_bg");
            if (go == null)
            {
                Debug.LogError("找不到名为 'game_bg' 的 GameObject！");
                return;
            }
            _spriteRenderer = go.GetComponent<SpriteRenderer>();
            if (_spriteRenderer == null)
            {
                Debug.LogError("'game_bg' 上没有找到 SpriteRenderer 组件！");
                return;
            }
        }

        if (_spriteRenderer && _spriteRenderer.sprite && _spriteRenderer.sprite.texture.name == fileName)
        {
            return;
        }

        // 调用统一的 SetImgLoader，不需要再自己写下载逻辑
        SetImgLoader(null, fileName, nTex =>
        {
            if (nTex != null && nTex.nativeTexture != null)
            {
                Debug.Log("背景图片加载成功！");

                var tex2D = nTex.nativeTexture as Texture2D;
                if (tex2D == null)
                {
                    Debug.LogError("NTexture 转换失败！");
                    return;
                }
                tex2D.name = fileName;
                // 创建 Sprite
                var sprite = Sprite.Create(
                    tex2D,
                    new Rect(0, 0, tex2D.width, tex2D.height),
                    new Vector2(0.5f, 0.5f)
                );
                _spriteRenderer.sprite = sprite;

                if (_currentNTexture != null)
                {
                    _currentNTexture.Dispose();
                    _currentNTexture = null;
                }
                if (_currentBackgroundSprite != null)
                {
                    Object.Destroy(_currentBackgroundSprite);
                    _currentBackgroundSprite = null;
                }

                _currentNTexture = nTex;
                _currentBackgroundSprite = sprite;

                var currentWidth = _spriteRenderer.sprite.bounds.size.x;
                var scaleFactor = 64f / currentWidth;

                // 等比缩放
                _spriteRenderer.transform.localScale = new Vector3(scaleFactor, scaleFactor, 1);
            }
            else
            {
                Debug.LogError("背景图片加载失败！");
            }
        }, "LevelAlbums/", FolderNames.AlbumName, true, false, true); // ✅ 背景一般是立刻需要的，走优先下载
    }


    public static void GetCardIcon(bool isLogo = false, UnityAction<NTexture> action = null)
    {
        var cardIconPath = "logo_default";
        // var paymentTypeVo = GameHelper.GetPaymentTypeVO();
        // if (isLogo)
        // {
        //     cardIconPath = paymentTypeVo.logo_id;
        // }
        // else
        // {
        //     cardIconPath = paymentTypeVo.card_name;
        // }


        GetNTexture("Atlas.Pay", cardIconPath, action);
    }

    private static IEnumerator GetTextureFromNet(string type, int imgId, string imgUrl, Action<bool> action = null)
    {
        var imagePath = $"{CommonHelper.GetAppSavePath()}/{type}/{imgId}.jpg";
        var fileInfo = new FileInfo(imagePath);
        if (fileInfo.Exists)
        {
            action?.Invoke(true);
            yield break;
        }

        var avatarRequest = UnityWebRequest.Get(imgUrl);
        yield return avatarRequest.SendWebRequest();
        if (avatarRequest.result == UnityWebRequest.Result.ConnectionError ||
            avatarRequest.result == UnityWebRequest.Result.ProtocolError)
        {
            action?.Invoke(false);
        }
        else
        {
            var avatarData = avatarRequest.downloadHandler.data;
            var dirPath = Path.GetDirectoryName(imagePath);
            if (!Directory.Exists(dirPath)) Directory.CreateDirectory(dirPath);

            if (fileInfo.Exists)
                yield break;
            Stream stream = fileInfo.Create();
            stream.Write(avatarData, 0, avatarData.Length);
            stream.Close();
            stream.Dispose();
            action?.Invoke(true);
        }
    }

    #endregion

    #region 头像相关

    public static void SetAvatarToLoader(int avatarId, GLoader _GLoader, bool IsNeedDefAvatar = true)
    {
        if (!avatarNTexturesDic.TryGetValue(avatarId, out var spr))
            try
            {
                Sprite sprite = null;
                if (avatarId == 0)
                {
                    if (!PlayerPrefsKit.ReadBool("IsLogin"))
                    {
                        avatarId = 1;
                        SetAvatarToLoader(avatarId, _GLoader);
                        return;
                    }

                    if (PlayerPrefsKit.ReadString("AvatarUrl").IsNullOrWhiteSpace())
                    {
                        _GLoader.url = "ui://pmf3wbjicxrg4";
                        return;
                    }

                    GetSelfFaceBookAvatar(texture =>
                    {
                        if (_GLoader != null)
                        {
                            if (texture != null)
                                _GLoader.texture = texture;
                            else
                                _GLoader.url = "ui://pmf3wbjicxrg4";
                        }
                    });
                    return;
                }

                if (avatarId > 100)
                {
                    if (IsNeedDefAvatar) _GLoader.url = "ui://pmf3wbjicxrg4";

                    GetFaceBookAvatar(avatarId, e =>
                    {
                        if (_GLoader != null)
                        {
                            if (e == null)
                                _GLoader.url = "ui://pmf3wbjicxrg4";
                            else
                                _GLoader.texture = e;
                        }
                    });
                    return;
                }

                LoadKit.Instance.LoadSprite("Atlas.Avatar", avatarId.ToString(), spr =>
                {
                    sprite = spr;
                    var spr1 = new NTexture(sprite);
                    _GLoader.texture = spr1;
                    avatarNTexturesDic.Add(avatarId, spr1);
                });
            }
            catch (Exception e)
            {
                Debug.LogError(e);
            }
        else
            _GLoader.texture = spr;
    }


    private static IEnumerator GetAvatarLocal(int avatarId, Action<Texture> action)
    {
        yield return GetLocalTexture($"Avatar/{avatarId}.jpg", action);
    }

    #endregion

    #region FaceBook头像相关

    public static void GetFaceBookAvatar(int avatarId, Action<NTexture> action)
    {
        if (!avatarNTexturesDic.TryGetValue(avatarId, out var spr))
            HallManager.Instance.StartCoroutine(GetAvatarLocal(avatarId, texture =>
            {
                if (texture == null)
                {
                    action?.Invoke(null);
                    return;
                }

                spr = new NTexture(texture);
                if (avatarNTexturesDic.ContainsKey(avatarId)) avatarNTexturesDic.Add(avatarId, spr);

                action?.Invoke(spr);
            }));
        else
            action?.Invoke(spr);
    }


    public static void GetSelfFaceBookAvatar(Action<NTexture> action)
    {
        if (!avatarNTexturesDic.TryGetValue(0, out var spr))
        {
        }
        else
        {
            action?.Invoke(spr);
        }
    }

    #endregion
}