using Cysharp.Threading.Tasks;
using System;
using System.Linq;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using System.Threading.Tasks;

public class SearchCtrl : SingletonMonoBehaviour<SearchCtrl>
{
    [SerializeField] GameObject opsion;
    [SerializeField] Image searchMenuButtonImage;
    [SerializeField] Sprite[] searchMenuButton;
    [SerializeField] TMP_Text searchMenuButtonText;

    [SerializeField] TMP_InputField name;
    [SerializeField] TMP_Dropdown suitStyle;
    [SerializeField] TMP_Dropdown suitType;
    [SerializeField] TMP_Dropdown region;
    [SerializeField] TMP_Dropdown animalTypes;
    [SerializeField] Toggle[] colors;
    [SerializeField] Sprite[] isOnSprite;

    [SerializeField] ItemPrefab item;
    [SerializeField] Transform results;
    [SerializeField] GameObject listTop;
    [SerializeField] GameObject bar;
    [SerializeField] RectTransform content;

    [SerializeField] Animator searchUI;

    [SerializeField] ModalCtrl model;

    private SearchRequest request;
    private List<Library> librarys = new();

    private Queue<Library> searchResults = new Queue<Library>();

    private bool hasMore;
#if UNITY_EDITOR
    [SerializeField]
#endif
    private List<ItemPrefab> itemPrefabs;
    private UnityEngine.Pool.ObjectPool<ItemPrefab> itemPrefabPool;

    protected override void OnAwake()
    {
        Application.targetFrameRate = 30;
        QualitySettings.vSyncCount = 0;

       itemPrefabPool = new UnityEngine.Pool.ObjectPool<ItemPrefab>(itemPrefabs_OnCreate,itemPrefabs_OnGet, itemPrefabs_OnRelease,null,true, 100);
       itemPrefabs = new List<ItemPrefab>();
        
    }
    #region ObjectPool

    private ItemPrefab itemPrefabs_OnCreate()
    {
        return Instantiate<ItemPrefab>(item, results);
    }

    private void itemPrefabs_OnGet(ItemPrefab itemPrefab)
    {
        itemPrefabs.Add(itemPrefab);
        itemPrefab.gameObject.SetActive(true);
    }

    private void itemPrefabs_OnRelease(ItemPrefab itemPrefab)
    {
        itemPrefab.gameObject.SetActive(false);
        itemPrefabs.Remove(itemPrefab);
    }

    #endregion

    private void OnEnable()
    {
        hasMore = false;
        model.gameObject.SetActive(false);
        searchUI.SetTrigger("reset");
        ResetButton();
        ObjectClear();
    }

    private void ObjectClear()
    {
        //TODO ��Ȱ�� �� �� �ְ� �����
        results.gameObject.SetActive(false);
        listTop.SetActive(false);
        bar.SetActive(false);
        librarys.Clear();
        
           while(itemPrefabPool.CountActive > 0) 
            {
                var item = itemPrefabs[itemPrefabs.Count-1];
                itemPrefabPool.Release(item);
            }
        
    }


    public void OpsionButton()
    {
        //�ɼ�â�� ������ �ʾ����� 250,100
        //�ɼ�â�� �������� 60 ,290
        bool isSelf = !opsion.activeSelf;
        searchMenuButtonImage.sprite = searchMenuButton[(isSelf ? 1 : 0)];
        searchMenuButtonImage.pixelsPerUnitMultiplier = (isSelf ? 3.5f : 1.75f);
        searchMenuButtonText.color = (isSelf ? Color.white : Color.black);
        searchUI.SetBool("isSelf", isSelf);
        ResetButton();
    }

    public void SearchButton()
    {
        ObjectClear();
        request = new SearchRequest();
        request.fursuitName = name.text;
        if (suitStyle.value != 0)
            request.suitStyle = GameManager.Instance.suitStyle[suitStyle.value - 1].code_id;
        if (suitType.value != 0)
            request.suitType = GameManager.Instance.suitType[suitType.value - 1].code_id;
        if (region.value != 0)
            request.suitRegion = GameManager.Instance.region[region.value - 1].code_id;
        if (animalTypes.value != 0)
            request.suitAnimalType = GameManager.Instance.animalTypes[animalTypes.value - 1].code_id;

        _ = SearchSuiters();

            results.gameObject.SetActive(true);
           listTop.SetActive(true);
            bar.SetActive(true);
        //NetworkManager.Instance.CreateRequest<SearchResponse>("library/select/suiters", request, (data) =>
        //{
        //    librarys = data.data;
        //    results.gameObject.SetActive(true);
        //    listTop.SetActive(true);
        //    bar.SetActive(true);
        //    ItemPrefab[] items = new ItemPrefab[data.data.Count];
        //    for (int n = 0; n < data.data.Count; n++)
        //    {
        //        var prefab = Instantiate<ItemPrefab>(item, results);
        //        itemPrefabs.Add(prefab);
        //        items[n] = prefab;
        //    }
        //    for (int n = 0; n < data.data.Count; n++)
        //    {
        //        items[n].Set(data.data[n]);
        //    }
        //    hasMore = data.hasMore;
        //    //LayoutRebuilder.ForceRebuildLayoutImmediate(content);
        //});
    }

    private bool isSearching = false;
    public async UniTask SearchSuiters()
    {
        if (isSearching) return;
        isSearching = true;

        var tcs = new TaskCompletionSource<bool>();

        var searchRequest = NetworkManager.Instance.CreateRequest<SearchResponse>(
            "library/select/suiters",
            request,
            (data) =>
            {
                for (int n = 0; n < data.data.Count; n++)
                {
                    searchResults.Enqueue(data.data[n]);
                }
                hasMore = data.hasMore;
                tcs.SetResult(true); // 응답 완료 신호
            }
        );

       await searchRequest.Send();

        await tcs.Task; // 응답이 완료될 때까지 대기
        await RefreshScroll();
        isSearching = false;

    
    }


    bool isRefreshing = false;
    public async UniTask RefreshScroll()
    {
        if (isRefreshing) return;
        isRefreshing = true;

        if (searchResults.Count > 0)
        {
            while (searchResults.TryDequeue(out var result))
            {
                librarys.Add(result);
            }

          //  librarys.Sort((a,b) => a.owner_id.CompareTo(b.owner_id));
        }

        int n = 0;
        for (; n < itemPrefabs.Count; n++) 
        {
            var item = itemPrefabs[n];
            item.Set(librarys[n]);
            await UniTask.Yield();
        }

        
        for(; n < librarys.Count; n++)
        {
            var item = itemPrefabPool.Get();
            item.Set(librarys[n]);
            await UniTask.Yield();
        }

        for(; n > librarys.Count; n--)
        {
            var item = itemPrefabs.Last();
            itemPrefabPool.Release(item);
            await UniTask.Yield();
        }
         await ApplayImages();
      //  LayoutRebuilder.ForceRebuildLayoutImmediate(content);
        isRefreshing = false;
    }

    private async UniTask ApplayImages()
    {
       for (int i = 0; itemPrefabs.Count > i; i++) 
        {
            await GetImage(itemPrefabs[i].Library);
            itemPrefabs[i].ImageSet();
        }



    }

    public void NextSearch()
    {
        if (isSearching == false) {
        hasMore = false;
        request.page++;
        _ = SearchSuiters();
        }

    }

    public async UniTask<Texture2D> GetImage(Library library)
    {
        if (library._suit_image != null)
        {
            return library._suit_image;
        }

        var tcs = new TaskCompletionSource<Texture2D>();

        var request = NetworkManager.Instance.CreateImageRequest(
            library.imageBase64.Substring(1),
            new object(),
            (data) =>
            {
                library._suit_image = data;
                tcs.SetResult(data);
            },
            (fail) =>
            {
                tcs.SetResult(null); 
            },
            BestHTTP.HTTPMethods.Get
        );

        await request.Send();

        await tcs.Task;        
        return library._suit_image;
    }


    public void ResetButton()
    {
        suitStyle.value = 0;
        suitType.value = 0;
        region.value = 0;
        animalTypes.value = 0;
        for(int n = 0; n < colors.Length; n++)
        {
            colors[n].isOn = false;
            colors[n].image.sprite = isOnSprite[0];
        }
    }

    public void OnToggle(int velue)
    {
        colors[velue].image.sprite = isOnSprite[(colors[velue].isOn ? 1 : 0)];
    }

    public void ModelSet(Library library)
    {
        model.Set(library);
    }

    public void ScrollValue(RectTransform Content) {
        if(Content.anchoredPosition.y < 0.0f)
        {
            Content.anchoredPosition = Vector2.zero;
        }
        else if(hasMore && Content.sizeDelta.y != Screen.height && Content.sizeDelta.y - Screen.height < Content.anchoredPosition.y)
        {
            NextSearch();
        }
    }
}

public class SearchRequest
{
    public int xid;
    public string fursuitName = ""; /*����,��Ʈ �̸�*/
    public string suitMaker; /*������*/
    public string suitRegion = ""; /*Ȱ�� ����*/
    public string suitStyle = ""; /*��Ʈ ��Ÿ��*/
    public string suitAnimalType = ""; /*��Ʈ ���� ��*/
    public string suitType = ""; /*��Ʈ ����*/
    public List<string> colorList = new List<string>(); /*��Ʈ ����*/
    public int page = 1;
    public int size = 5;
    public int offset = 0;
}
public class SearchResponse
{
    public List<Library> data;
    public bool hasMore;
}
public class ImageResponse
{
    public byte[] imageBytes;
}

public class Library : IEquatable<Library>
{
    public string imageBase64;
    public string suit_name;
    public string owner_id;
    public string owner_name;
    public string production_date;
    public string suit_image;//������
    public Texture2D _suit_image = null;
    public string maker;
    public string region;
    public string animal_type;
    public string suit_style;
    public string suit_type;
    public List<string> suit_color;

    public bool Equals(Library other)
    {
      return this.imageBase64 == other.imageBase64 && this.owner_id == other.owner_id && this.maker == other.maker && this.region == other.region && this.animal_type == other.animal_type && this.suit_type == other.suit_type && this.suit_style == other.suit_style;
    }
}