using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using Module.Log;

public enum IMAGE_CHECK_STATE
{
    NONE = 0,
    PASS = 1,
    CHECKING = 2,
    BACK = 3,
}

[RequireComponent(typeof(Image))]
public class NetImage : MonoBehaviour
{

    public Image _Image;
    public Image _ImageChecking;

    void Awake()
    {
        _Image = GetComponent<Image>();
        //InitImageUrl();
        SetUsingImage(this);
    }

    private void OnDestroy()
    {
        RemoveUsingImage(this);
    }

    #region image catch

    private static Dictionary<string, string> _CatchImages;
    private static Dictionary<string, List<GetImageCallBack>> _LoadingImgCallBack = new Dictionary<string, List<GetImageCallBack>>();
    private static string _FoldPath;
    private static string _FilePath;

    protected delegate void GetImageCallBack(Texture2D texture, IMAGE_CHECK_STATE imgState);

    protected static void LoadTexture(string url, GetImageCallBack imgCallback, ulong playerGuid, bool isHeadPic)
    {
        if (_CatchImages == null)
        {
            InitImagePath();
        }

        Debug.Log("LoadTexture:" + url);
        if (!_LoadingImgCallBack.ContainsKey(url))
        {
            _LoadingImgCallBack.Add(url, new List<GetImageCallBack>());
            _LoadingImgCallBack[url].Add(imgCallback);
            GameManager.gameManager.StartCoroutine(LoadImage(url, playerGuid, isHeadPic));
        }
        else
        {
            _LoadingImgCallBack[url].Add(imgCallback);
        }
    }

    private static IEnumerator LoadImage(string url, ulong playerGuid, bool isHeadPic)
    {
        string imgUrl = url;
        WWW w = null;

        //imgUrl = "http://serv.zhanyou-game.com:8098/api/Image/get";
        imgUrl = isHeadPic ? Community.Instance.HeadPicDownUrl : Community.Instance.BlogPicDownUrl;

        WWWForm form = new WWWForm();

        string timeStamp = GCGame.Utils.GetTimeStamp();
        string randomStr = GCGame.Utils.GetRandomStr();
        string sign = GCGame.Utils.GetSignString(timeStamp, randomStr, Community.Instance._ApiKey);

        form.AddField("timestamp", timeStamp);
        form.AddField("nonce_str", randomStr);
        form.AddField("sign", sign);
        if (isHeadPic)
        {
            form.AddField("type", "head_image");
        }
        else
        {
            form.AddField("type", "weibo_image");
        }
        form.AddField("guid", playerGuid.ToString());
        form.AddField("image", url);

        // Upload to a cgi script
        w = new WWW(imgUrl, form);

        yield return w;

        if (!string.IsNullOrEmpty(w.error))
        {
            //GuiTextDebug.debug("img url error:" + w.error);
            LogModule.ErrorLog("load image error:" + w.error + ", " + imgUrl);
            GUIData.AddNotifyData(w.error);
            _LoadingImgCallBack.Remove(url);
            yield break;
        }
        else
        {
            Texture2D texture = null;
            //如果有本地缓存,显示本地缓存
            if (_CatchImages.ContainsKey(url))
            {
                imgUrl = GetPlatFromPath(_CatchImages[url]);
                GuiTextDebug.debug("img url local:" + imgUrl);
                WWW localWWW = new WWW(imgUrl);

                yield return localWWW;
                if (!string.IsNullOrEmpty(localWWW.error))
                {
                    //GuiTextDebug.debug("img url error:" + w.error);
                    LogModule.ErrorLog("load image error:" + localWWW.error + ", " + imgUrl);
                    GUIData.AddNotifyData("#{39031}");
                    _LoadingImgCallBack.Remove(url);
                    yield break;
                }
                else
                {
                    texture = localWWW.texture;
                }
            }

            var uploadRet = JsonUtility.FromJson<ImgDownloadRet>(w.text);
            LogModule.DebugLog(w.text);
            IMAGE_CHECK_STATE imgState = IMAGE_CHECK_STATE.PASS;
            if (uploadRet.errno == 0)
            {
                if (uploadRet.data.Length > 0 && uploadRet.data[0].status == 1)
                {
                    if (!_CatchImages.ContainsKey(url))
                    {//没有本地缓存,从服务器加载
                        string imgdownUrl = uploadRet.data[0].url;

                        w = new WWW(imgdownUrl);

                        yield return w;

                        if (!string.IsNullOrEmpty(w.error))
                        {
                            //GuiTextDebug.debug("img url error:" + w.error);
                            LogModule.ErrorLog("load image error:" + w.error + ", " + imgUrl);
                            GUIData.AddNotifyData("#{39031}");
                        }
                        else
                        {

                            AddImagePath(url, w.texture);

                            texture = w.texture;
                        }
                    }
                }
                else if (uploadRet.data[0].status == 2)
                {
                    //审核没通过
                    imgState = IMAGE_CHECK_STATE.BACK;
                }
                else
                {
                    //图片审核中
                    if (!_CatchImages.ContainsKey(url))
                    {//如果没有本地缓存显示提示1
                        imgState = IMAGE_CHECK_STATE.CHECKING;
                    }
                    else
                    {//有本地缓存,显示提示2
                        imgState = IMAGE_CHECK_STATE.CHECKING;
                    }

                }

                for (int i = 0; i < _LoadingImgCallBack[url].Count; ++i)
                {
                    try
                    {
                        _LoadingImgCallBack[url][i](texture, imgState);
                    }
                    catch (System.Exception e)
                    { }
                }
            }
            else
            {
                GUIData.AddNotifyData(uploadRet.msg);
                for (int i = 0; i < _LoadingImgCallBack[url].Count; ++i)
                {
                    try
                    {
                        _LoadingImgCallBack[url][i](texture, IMAGE_CHECK_STATE.CHECKING);
                    }
                    catch (System.Exception e)
                    { }
                }
            }

            _LoadingImgCallBack.Remove(url);

        }
    }

    private static void InitImagePath()
    {
        _CatchImages = new Dictionary<string, string>();
        _FoldPath = Application.persistentDataPath + "/ImagePath";
        _FilePath = _FoldPath + "/ImagePath.txt";

        GCGame.Utils.CheckTargetPath(_FilePath);

        if (!File.Exists(_FilePath))
        {
            var file = File.Create(_FilePath);
            file.Close();
            return;
        }

        StreamReader streamReader = new StreamReader(_FilePath);
        while (!streamReader.EndOfStream)
        {
            var pathLine = streamReader.ReadLine();
            var pathSplit = pathLine.Split('\t');
            if (pathSplit.Length > 1)
            {
                if (!_CatchImages.ContainsKey(pathSplit[0]))
                {
                    _CatchImages.Add(pathSplit[0], pathSplit[1]);
                }
            }
        }
        streamReader.Close();
    }

    private static void AddImagePath(string url, Texture2D texture)
    {
        if (_CatchImages == null)
        {
            InitImagePath();
        }

        //var nameSplit = url.Split('=');
        //if (nameSplit.Length > 1)
        {
            string localPath = Application.persistentDataPath + "/ImagePath/" + url;
            if (File.Exists(localPath))
            {
                if(_CatchImages.ContainsKey(url))
                    _CatchImages.Remove(url);
                File.Delete(localPath);
            }

            byte[] bytes = texture.EncodeToPNG();
            File.WriteAllBytes(localPath, bytes);

            StreamWriter fileStream = File.AppendText(_FilePath);
            fileStream.WriteLine(url + "\t" + localPath);
            fileStream.Close();

            _CatchImages.Add(url, localPath);
        }
    }

    private static string GetPlatFromPath(string path)
    {
        if (Application.isEditor)
            return "file:///" + path.Replace("\\", "/"); // Use the build output folder directly.
        else if (Application.platform == RuntimePlatform.IPhonePlayer)
            return "file://" + path;
        else if (Application.isMobilePlatform || Application.isConsolePlatform)
            return "file://" + path;
        else // For standalone player.
            return "file://" + path;
    }

    #endregion

    #region using image

    public static List<NetImage> _UsingImage = new List<NetImage>();

    public static void SetUsingImage(NetImage netImage)
    {
        _UsingImage.Add(netImage);
    }

    public static void RemoveUsingImage(NetImage netImage)
    {
        _UsingImage.Remove(netImage);
    }

    public static void ChangeHeadPic(string url, Texture2D image, IMAGE_CHECK_STATE imgState)
    {
        for (int i = 0; i < _UsingImage.Count; ++i)
        {
            if (_UsingImage[i] == null)
                continue;

            if (_UsingImage[i].NetImageUrl != url)
                continue;

            _UsingImage[i].SetNetImage(image, imgState);
        }
    }

    #endregion

    #region 

    protected string _NetImageUrl;
    public string NetImageUrl
    {
        get
        {
            return _NetImageUrl;
        }
        set
        {
            _NetImageUrl = value;
        }
    }

    protected Texture2D _NetTexture;
    public Texture2D NetTexture
    {
        get
        {
            return _NetTexture;
        }
    }

    public void ClearNetImage()
    {
        _ImageChecking.gameObject.SetActive(false);
    }

    public void SetNetImage(string netImageUrl, ulong playGuid, bool isHeadPic = true)
    {
        //_ImageChecking.gameObject.SetActive(false);
        //if (_NetImageUrl == netImageUrl && _Image.sprite != null)
        //    return;
        _NetImageUrl = netImageUrl;
        //StartCoroutine(GetWWWImage());
        _Image.sprite = null;
        _Image.enabled = false;
        Debug.Log("SetNetImage:" + netImageUrl);
        LoadTexture(netImageUrl, SetNetImage, playGuid, isHeadPic);
    }

    public virtual void SetNetImage(Texture2D texture2D, IMAGE_CHECK_STATE imgState)
    {
        if (_ImageChecking == null)
        {
            Debug.Log("_ImageChecking is null:" + gameObject.name);
        }
        _ImageChecking.gameObject.SetActive(false);
        if (texture2D != null)
        {
            _Image.enabled = true;
            _NetTexture = new Texture2D((int)_Image.rectTransform.rect.width, (int)_Image.rectTransform.rect.height);
            int minPos = 0;
            int maxPosX = texture2D.width - 1;
            int maxPos = texture2D.height - 1;
            float rateX = texture2D.width / _Image.rectTransform.rect.width;
            float rateY = texture2D.height / _Image.rectTransform.rect.height;
            for (int i = 0; i < _NetTexture.width; ++i)
            {
                for (int j = 0; j < _NetTexture.height; ++j)
                {
                    int sampleX = Mathf.Clamp((int)(i * rateX), minPos, maxPosX);
                    int sampleY = Mathf.Clamp((int)(j * rateY), minPos, maxPosX);
                    _NetTexture.SetPixel(i, j, texture2D.GetPixel(sampleX, sampleY));
                }
            }
            _NetTexture.Apply();

            _Image.gameObject.SetActive(true);
            _Image.sprite = Sprite.Create(_NetTexture, new Rect(0, 0, _NetTexture.width, _NetTexture.height), new Vector2(0.5f, 0.5f));

            if (imgState == IMAGE_CHECK_STATE.CHECKING)
            {
                _ImageChecking.gameObject.SetActive(true);
                LoadAssetBundle.Instance.SetImageSprite(_ImageChecking, "ImageChecking2");
                //_Image.sprite = null;
            }
            else if (imgState == IMAGE_CHECK_STATE.BACK)
            {
                _ImageChecking.gameObject.SetActive(true);
                LoadAssetBundle.Instance.SetImageSprite(_ImageChecking, "ImageChecking3");
            }
        }
        else
        {
            _Image.sprite = null;
            if (imgState == IMAGE_CHECK_STATE.CHECKING)
            {
                _ImageChecking.gameObject.SetActive(true);
                LoadAssetBundle.Instance.SetImageSprite(_ImageChecking, "ImageChecking1");
            }
            else if (imgState == IMAGE_CHECK_STATE.BACK)
            {
                _ImageChecking.gameObject.SetActive(true);
                LoadAssetBundle.Instance.SetImageSprite(_ImageChecking, "ImageChecking3");
            }
        }
    }
    
    public virtual void CleanUpImage()
    {
        _Image.gameObject.SetActive(false);
        _NetTexture = null;
        _NetImageUrl = "";
    }

    public virtual void UploadImage(UploadCallBack upLoadSucess, UploadCallBack uploadFail)
    {
        _UploadSucess = upLoadSucess;
        _UploadFail = uploadFail;
        //UploadHeadPic(this);
        var timeMark = System.DateTime.Now - new System.DateTime(0);
        _NetImageUrl = "playerIcon" + CommunityLogic.CommunityPlayerInfo.GUID + (ulong)timeMark.TotalSeconds;
        //Community.Instance._HeadPicUpLoadUrl = _NetImageUrl;
        StartCoroutine(UploadImage(new List<Texture2D>() { NetTexture }, true));
        ChangeHeadPic(_NetImageUrl, NetTexture, IMAGE_CHECK_STATE.CHECKING);
        AddImagePath(_NetImageUrl, NetTexture);
    }
    #endregion

    #region 

    //public static string _HeadIconUrl = "http://serv.zhanyou-game.com:8098/imgupload/FileUpLoad";
    //public static string _ImageUpLoadUrl = "http://serv.zhanyou-game.com:8098/imgupload/FileUpLoad";
    //public static string _ImageDownUrl = "http://serv.zhanyou-game.com:8098/imgupload/FileDown?img=20170815191800.png";

    public delegate void UploadCallBack(List<string> uploadFileName);
    protected static UploadCallBack _UploadSucess;
    protected static UploadCallBack _UploadFail;

    private static NetImage _UploadingImage;

    //private static void InitImageUrl()
    //{
    //    CG_REQ_MENGDAO_URL packet = (CG_REQ_MENGDAO_URL)PacketDistributed.CreatePacket(MessageID.PACKET_CG_REQ_MENGDAO_URL);
    //    packet.Nilparam = 1;
    //    packet.SendPacket();
    //}

    //public static void InitImageUrlRet(GC_RET_MENGDAO_URL packet)
    //{
    //    _ImageUpLoadUrl = packet.Blogpiuploadcurl;
    //    _ImageDownUrl = packet.Blogpicdownurl;
    //}

    private static void UploadHeadPic(NetImage uploadImage)
    {
        _UploadingImage = uploadImage;
        CG_REQ_HEAD_PIC_FILE_NAME packet = (CG_REQ_HEAD_PIC_FILE_NAME)PacketDistributed.CreatePacket(MessageID.PACKET_CG_REQ_HEAD_PIC_FILE_NAME);
        packet.Nilparam = 1;
        packet.SendPacket();
    }

    public static void RetHeadPicName(GC_RET_HEAD_PIC_FILE_NAME packet)
    {
        if (_UploadingImage == null)
            return;

        if (string.IsNullOrEmpty(packet.Headpicname))
            return;

        _UploadingImage.NetImageUrl = packet.Headpicname;
        _UploadingImage.StartCoroutine(UploadImage(new List<Texture2D>() { _UploadingImage.NetTexture }, true));

        ChangeHeadPic(_UploadingImage._NetImageUrl, _UploadingImage.NetTexture, IMAGE_CHECK_STATE.CHECKING);
    }
    
    protected static IEnumerator UploadImage(List<Texture2D> uploadImages, bool isHeadPic)
    {



        string url = isHeadPic? Community.Instance.HeadPicUpLoadUrl: Community.Instance.BlogPicUpLoadUrl;

        WWWForm form = new WWWForm();
        //form.AddBinaryData("FileUpLoad", bytes, fileName, "image/png");

        string timeStamp = GCGame.Utils.GetTimeStamp();
        string randomStr = GCGame.Utils.GetRandomStr();
        string sign = GCGame.Utils.GetSignString(timeStamp, randomStr, Community.Instance._ApiKey);

        
        form.AddField("timestamp", timeStamp);
        form.AddField("nonce_str", randomStr);
        form.AddField("sign", sign);
        if (isHeadPic)
        {
            form.AddField("type", "head_image");
        }
        else
        {
            form.AddField("type", "weibo_image");
        }
        form.AddField("guid", GameManager.gameManager.PlayerDataPool.MainPlayerBaseAttr.Guid.ToString());
        form.AddField("server_id", LoginData.GetServerListDataByID(PlayerPreferenceData.LastServer).m_id.ToString());

        string imgField = uploadImages.Count > 1 ? "image[]" : "image";
        for (int i = 0; i < uploadImages.Count; ++i)
        {
            byte[] bytes = uploadImages[i].EncodeToPNG();
            form.AddBinaryData(imgField, bytes, i + ".png", "image/png");
        }

        // Upload to a cgi script
        WWW w = new WWW(url, form);
        yield return w;
        if (!string.IsNullOrEmpty(w.error))
        {
            if (_UploadFail != null)
                _UploadFail.Invoke(null);
            LogModule.ErrorLog("image upload error:" + w.error);
        }
        else
        {
            string result = w.text;
            LogModule.DebugLog(result);
            var uploadRet = JsonUtility.FromJson<ImgUploadRet>(result);
            if (uploadRet.errno != 0)
            {
                GUIData.AddNotifyData(uploadRet.msg);
                _UploadFail.Invoke(null);
            }
            else
            {
                if (_UploadSucess != null)
                    _UploadSucess.Invoke(new List<string>(uploadRet.data));

                for (int i = 0; i < uploadImages.Count; ++i)
                {
                    AddImagePath(uploadRet.data[i], uploadImages[i]);
                }
            }
            LogModule.DebugLog("Finished Uploading Screenshot");
        }
    }

    #endregion

    #region info from json

    [System.Serializable]
    public class ImgUploadRet
    {
        public int errno;
        public string msg;
        public string[] data;
    }

    [System.Serializable]
    public class ImgDownloadRet
    {
        public int errno;
        public string msg;
        public ImgInfo[] data;
    }

    [System.Serializable]
    public class ImgInfo
    {
        public string key;
        public int status;
        public string url;
    }

    #endregion

}