using System;
using System.Collections;
using System.IO;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;

namespace TwitchInGames.Test {
    public class UnitTest_User : UnitTest_Auth {
#pragma warning disable 649 // Field '*' is never assigned to, and will always have its default value *
        [SerializeField]
        private Image profileImage;

        [SerializeField]
        private Text inputLogin;

        [SerializeField]
        private Toggle toggleDownloadDefault;

        [SerializeField]
        private Sprite defaultSprite;
#pragma warning restore 649

        protected override void Start() {
            base.Start();
            if(profileImage.gameObject.activeSelf) {
                profileImage.gameObject.SetActive(false);
            }
        }

        public void FetchCurrentUser() {
            if(String.IsNullOrEmpty(authToken)) {
                output.text = "Auth Token is null.\nPlease call GetAuthToken first.";
            } else {
                StartCoroutine(InternalFetchCurrentUser());
            }
        }

        private IEnumerator InternalFetchCurrentUser() {
            var coroutine = User.FetchCurrent(clientId, authToken);
            yield return coroutine;
            try {
                var user = coroutine.Value;
                OnFetchUser(user);
            } catch(Exception ex) {
                Debug.LogErrorFormat("FetchCurrentUser error: {0}", ex);
            }
        }

        public void FetchOtherUser() {
            StartCoroutine(InternalFetchOtherUser());
        }

        public IEnumerator InternalFetchOtherUser() {
            string login = inputLogin.text;
            Coroutine<User> coroutine;
            if(login.All(Char.IsDigit)) {
                coroutine = User.FetchOtherById(clientId, login);
            } else {
                coroutine = User.FetchOtherByLogin(clientId, login);
            }
            yield return coroutine;
            try {
                var user = coroutine.Value;
                OnFetchUser(user);
            } catch(Exception ex) {
                Debug.LogErrorFormat("FetchOtherUser error: {0}", ex);
            }
        }

        public void DownloadProfileImage() {
            profileImage.gameObject.SetActive(false);
            output.text = "";
            StartCoroutine(InternalDownloadProfileImage());
        }

        private IEnumerator InternalDownloadProfileImage() {
            // Get the user.
            string login = inputLogin.text;
            Coroutine<User> userCoroutine;
            if(login.All(Char.IsDigit)) {
                userCoroutine = User.FetchOtherById(clientId, login);
            } else {
                userCoroutine = User.FetchOtherByLogin(clientId, login);
            }
            yield return userCoroutine;
            User user;
            try {
                user = userCoroutine.Value;
            } catch(Exception ex) {
                Debug.LogErrorFormat("DownloadProfileImage error: {0}", ex);
                yield break;
            }

            // Get the user's profile image.
            var imageCoroutine = user.FetchProfileImage();
            yield return imageCoroutine;
            try {
                var image = imageCoroutine.Value;
                OnDownloadProfileImage(image);
            } catch(Exception ex) {
                Debug.LogErrorFormat("DownloadProfileImage error: {0}", ex);
            }
        }

        private void OnFetchUser(User userInfo) {
            if(String.IsNullOrEmpty(userInfo.Login)) {
                profileImage.sprite = null;
                output.text = "Failed to fetch user!";
                profileImage.gameObject.SetActive(false);
                return;
            }

            profileImage.gameObject.SetActive(true);
            profileImage.sprite = defaultSprite;

            output.text = "";
            StringBuilder sb = new StringBuilder();
            sb.Append(userInfo.Login);
            sb.Append(" (");
            sb.Append(userInfo.DisplayName);
            sb.Append(")");
            sb.AppendLine();
            sb.AppendLine();
            sb.Append("ID: ");
            sb.Append(userInfo.Id);
            sb.AppendLine();
            sb.Append("Bio: ");
            sb.Append(userInfo.Description);
            sb.AppendLine();
            sb.Append("Email: ");
            sb.Append(userInfo.Email);
            sb.AppendLine();
            sb.Append("View Count: ");
            sb.Append(userInfo.ViewCount);
            sb.AppendLine();
            sb.Append("Broadcaster Type: ");
            sb.Append(userInfo.BroadcasterType);
            sb.AppendLine();
            sb.Append("Type: ");
            sb.Append(userInfo.Type);
            sb.AppendLine();

            sb.AppendLine();
            sb.Append("Profile Image URL: ");
            sb.AppendLine();
            sb.Append(userInfo.ProfileImageUrl);

            output.text = sb.ToString();

            StartCoroutine(DisplayProfileImage(userInfo.ProfileImageUrl));
        }

        private void OnDownloadProfileImage(Texture2D imageTexture) {
            if(imageTexture != null) {
                var textureData = imageTexture.GetRawTextureData();
                output.text = String.Format("Profile image downloaded; size is {0} bytes.", textureData.Length);
            } else {
                output.text = "No Image downloaded.";
            }
        }

        private IEnumerator DisplayProfileImage(string url) {
            url = url == "" ? "https://static-cdn.jtvnw.net/jtv_user_pictures/xarth/404_user_300x300.png" : url;
            WWW www = new WWW(url);
            yield return www;
            profileImage.sprite = Sprite.Create(www.texture, new Rect(0, 0, www.texture.width, www.texture.height), new Vector2(0, 0));
        }
    }
}
