namespace TeamViewerApi.TeamViewer
{
    using System;
    using System.Net;
    using System.Runtime.Serialization;
    using Newtonsoft.Json;
    using Helpers;

    [DataContract]
    public class Session
    {
        private static IgnorableSerializerContractResolver jsonCreateResolver;
        private static IgnorableSerializerContractResolver jsonSaveResolver;

        static Session()
        {
            Session.jsonCreateResolver = new IgnorableSerializerContractResolver();
            Session.jsonCreateResolver.Ignore(typeof(Session), "code");
            Session.jsonCreateResolver.Ignore(typeof(Session), "state");
            Session.jsonCreateResolver.Ignore(typeof(Session), "online");
            Session.jsonCreateResolver.Ignore(typeof(Session), "groupid");
            Session.jsonCreateResolver.Ignore(typeof(Session), "assigned_userid");
            Session.jsonCreateResolver.Ignore(typeof(Session), "assigned_at");
            Session.jsonCreateResolver.Ignore(typeof(Session), "end_customer_link");
            Session.jsonCreateResolver.Ignore(typeof(Session), "supporter_link");
            Session.jsonCreateResolver.Ignore(typeof(Session), "created_at");
            Session.jsonCreateResolver.Ignore(typeof(Session), "closed_at");
            Session.jsonCreateResolver.Ignore(typeof(Session), "custom_api");
            Session.jsonCreateResolver.Ignore(typeof(User), "id");
            Session.jsonCreateResolver.Ignore(typeof(User), "language");
            Session.jsonCreateResolver.Ignore(typeof(User), "permissions");
            Session.jsonCreateResolver.Ignore(typeof(User), "active");
            Session.jsonCreateResolver.Ignore(typeof(User), "custom_quicksupport_id");
            Session.jsonCreateResolver.Ignore(typeof(User), "custom_quickjoin_id");

            Session.jsonSaveResolver = new IgnorableSerializerContractResolver();
            Session.jsonSaveResolver.Ignore(typeof(Session), "code");
            Session.jsonSaveResolver.Ignore(typeof(Session), "online");
            Session.jsonSaveResolver.Ignore(typeof(Session), "groupname");
            Session.jsonSaveResolver.Ignore(typeof(Session), "assigned_userid");
            Session.jsonSaveResolver.Ignore(typeof(Session), "assigned_at");
            Session.jsonSaveResolver.Ignore(typeof(Session), "end_customer_link");
            Session.jsonSaveResolver.Ignore(typeof(Session), "supporter_link");
            Session.jsonSaveResolver.Ignore(typeof(Session), "created_at");
            Session.jsonSaveResolver.Ignore(typeof(Session), "valid_until");
            Session.jsonSaveResolver.Ignore(typeof(Session), "closed_at");
            Session.jsonSaveResolver.Ignore(typeof(Session), "custom_api");
            Session.jsonSaveResolver.Ignore(typeof(User), "id");
            Session.jsonSaveResolver.Ignore(typeof(User), "language");
            Session.jsonSaveResolver.Ignore(typeof(User), "permissions");
            Session.jsonSaveResolver.Ignore(typeof(User), "active");
            Session.jsonSaveResolver.Ignore(typeof(User), "custom_quicksupport_id");
            Session.jsonSaveResolver.Ignore(typeof(User), "custom_quickjoin_id");
        }

        [DataMember(Name = "code")]
        public string Code { get; set; }

        [DataMember(Name = "state")]
        public string State { get; set; }

        [DataMember(Name = "online")]
        public bool Online { get; set; }

        [DataMember(Name = "groupid")]
        public string GroupId { get; set; }

        [DataMember(Name = "groupname")]
        public string GroupName { get; set; }

        [DataMember(Name = "waiting_message")]
        public string WaitingMessage { get; set; }

        [DataMember(Name = "end_customer")]
        public User Customer { get; set; }

        [DataMember(Name = "description")]
        public string CustomerDescription { get; set; }

        [DataMember(Name = "assigned_userid")]
        public string AssignedUserId { get; set; }

        [DataMember(Name = "assigned_at")]
        public DateTime? DateAssigned { get; set; }

        [DataMember(Name = "end_customer_link")]
        public string CustomerLink { get; set; }

        [DataMember(Name = "supporter_link")]
        public string SupporterLink { get; set; }

        [DataMember(Name = "created_at")]
        public DateTime? DateCreated { get; set; }

        [DataMember(Name = "valid_until")]
        public DateTime? DateIsValid { get; set; }

        [DataMember(Name = "closed_at")]
        public DateTime? DateClosed { get; set; }

        [DataMember(Name = "custom_api")]
        public string CustomApi { get; set; }

        /// <summary>
        /// Get session
        /// </summary>
        /// <param name="accessToken">Token</param>
        /// <param name="code">Session code</param>
        public static Session GetSession(string accessToken, string code)
        {
            string url = string.Format("{0}/{1}", TeamViewer.URL.SESSIONS, code);

            Rest.Properties properties = new Rest.Properties(accessToken, url, TeamViewer.Rest.Method.GET);
            Rest.Connection connection = new Rest.Connection(properties);

            string json = connection.SendRequest();

            Session result = null;

            if (!string.IsNullOrEmpty(json))
                result = JsonConvert.DeserializeObject<Session>(json);

            return result;
        }

        /// <summary>
        /// Save changes in session
        /// </summary>
        /// <param name="accessToken">Token</param>
        /// <param name="session">Session</param>
        public static void SaveSession(string accessToken, Session session)
        {
            string json = JsonConvert.SerializeObject(session, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, ContractResolver = Session.jsonSaveResolver });

            string url = string.Format("{0}/{1}", TeamViewer.URL.SESSIONS, session.Code);

            Rest.Properties properties = new Rest.Properties(accessToken, url, TeamViewer.Rest.Method.PUT, json);
            Rest.Connection connection = new Rest.Connection(properties);

            connection.SendRequest();
        }

        /// <summary>
        /// Creates new session
        /// </summary>
        /// <param name="accessToken">Token</param>
        /// <param name="session">Session</param>
        public static Session CreateSession(string accessToken, Session session)
        {
            string json = JsonConvert.SerializeObject(session, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, ContractResolver = Session.jsonCreateResolver });

            Rest.Properties properties = new Rest.Properties(accessToken, TeamViewer.URL.SESSIONS, TeamViewer.Rest.Method.POST, json);
            Rest.Connection connection = new Rest.Connection(properties);

            json = connection.SendRequest();

            Session result = null;

            if (!string.IsNullOrEmpty(json))
                result = JsonConvert.DeserializeObject<Session>(json);

            return result;
        }
    }
}
