using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Net;
using System.Runtime.Serialization.Json;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace TileSamples.Data
{
    public class TwitterItem
    {
        public DateTime PublishDate { get; set; }
        public string Handle { get; set; }
        public string Title { get; set; }
        public string Link { get; set; }
    }


    public class FeedData
    {
        // twitter search link
        internal const string Link = "http://search.twitter.com/search.json?q=from:{0}&rpp=20&include_entities=true";

        /// <summary>
        /// Searches and gets the index of the first older item already in the list
        /// </summary>
        /// <param name="date">The date of the item being compared to the list</param>
        /// <returns>The index of the first oldest item, otherwise the number of items in the list</returns>
        public static int GetFirstIndexOfOlderTwitterItem(DateTime date, ObservableCollection<TwitterItem> tItems)
        {
            if (tItems.Count > 0)
            {
                TwitterItem tfi = tItems.FirstOrDefault(d => d.PublishDate < date);
                if (tfi == null)
                    return tItems.Count;
                else
                    return tItems.IndexOf(tfi);

            }
            else
            {
                return 0;
            }
        }

        /// <summary>
        /// Loads twits.
        /// </summary>
        /// <param name="uri">The uri to load twitter data.</param>
        /// <returns></returns>
        public static async Task<ObservableCollection<TwitterItem>> Load(string uri)
        {
            ObservableCollection<TwitterItem> result = new ObservableCollection<TwitterItem>();
            try
            {
                var client = WebRequest.CreateHttp(uri);
                var response = await client.GetResponseAsync();

                #region ** parse twitter data
                using (System.IO.Stream stream = response.GetResponseStream())
                {
                    // parse Json data
                    DataContractJsonSerializer rootSer = new DataContractJsonSerializer(typeof(RootObject));

                    RootObject root = (RootObject)rootSer.ReadObject(stream);
                    foreach (Result res in root.results)
                    {
                        TwitterItem ti = new TwitterItem();
                        ti.Title = res.text;
                        DateTimeOffset dateOffset;
                        if (DateTimeOffset.TryParse(res.created_at, out dateOffset))
                        {
                            ti.PublishDate = dateOffset.UtcDateTime;
                        }
                        ti.Handle = res.from_user;
                        if (res.entities.urls != null && res.entities.urls.Count > 0)
                        {
                            ti.Link = res.entities.urls[0].url;
                        }
                        result.Insert(GetFirstIndexOfOlderTwitterItem(ti.PublishDate, result), ti);
                    }
                }
                #endregion
            }
            catch
            {
            }
            return result;
        }
    }

    /// <summary>
    /// The next classes were generated from Json, returned by twitter search api, by the 
    /// http://json2csharp.com service.
    /// They can be used to deserialize Json using System.Runtime.Serialization.Json.DataContractJsonSerializer.
    /// </summary>
    public class Entities
    {
        public List<object> hashtags { get; set; }
        public List<Url> urls { get; set; }
        public List<object> user_mentions { get; set; }
    }

    public class Url
    {
        public string url { get; set; }
        public string expanded_url { get; set; }
        public string display_url { get; set; }
        public List<int> indices { get; set; }
    }

    public class Metadata
    {
        public string result_type { get; set; }
    }

    public class Result
    {
        public string created_at { get; set; }
        public Entities entities { get; set; }
        public string from_user { get; set; }
        public int from_user_id { get; set; }
        public string from_user_id_str { get; set; }
        public string from_user_name { get; set; }
        public object geo { get; set; }
        public object id { get; set; }
        public string id_str { get; set; }
        public string iso_language_code { get; set; }
        public Metadata metadata { get; set; }
        public string profile_image_url { get; set; }
        public string profile_image_url_https { get; set; }
        public string source { get; set; }
        public string text { get; set; }
        public string to_user { get; set; }
        public int to_user_id { get; set; }
        public string to_user_id_str { get; set; }
        public string to_user_name { get; set; }
        public long in_reply_to_status_id { get; set; }
        public string in_reply_to_status_id_str { get; set; }
    }

    public class RootObject
    {
        public double completed_in { get; set; }
        public long max_id { get; set; }
        public string max_id_str { get; set; }
        public int page { get; set; }
        public string query { get; set; }
        public string refresh_url { get; set; }
        public List<Result> results { get; set; }
        public int results_per_page { get; set; }
        public int since_id { get; set; }
        public string since_id_str { get; set; }
    }

}
