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

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

        static Meeting()
        {
            Meeting.jsonSaveResolver = new IgnorableSerializerContractResolver();
            Meeting.jsonSaveResolver.Ignore(typeof(Meeting), "id");
            Meeting.jsonSaveResolver.Ignore(typeof(Meeting), "participant_web_link");

            Meeting.jsonCreateResolver = new IgnorableSerializerContractResolver();
            Meeting.jsonCreateResolver.Ignore(typeof(Meeting), "id");
            Meeting.jsonCreateResolver.Ignore(typeof(Meeting), "participant_web_link");
        }

        [DataMember(Name = "id")]
        public string MeetingId { get; set; }

        [DataMember(Name = "subject")]
        public string Subject { get; set; }

        public DateTime? DateStart { get; set; }

        [DataMember(Name = "start")]
        public string DateStartString
        {
            get
            {
                if (!this.DateStart.HasValue)
                    return null;
                else
                    return this.DateStart.Value.ToUniversalTime().ToString("yyyy-MM-ddThh:mm:ssZ");
            }
            set
            {
                if (value == null)
                    this.DateStart = null;
                else
                {
                    DateTime temp;

                    if (DateTime.TryParse(value, out temp))
                        this.DateStart = temp;
                }
            }
        }

        public DateTime? DateEnd { get; set; }

        [DataMember(Name = "end")]
        public string DateEndString
        {
            get
            {
                if (!this.DateEnd.HasValue)
                    return null;
                else
                    return this.DateEnd.Value.ToUniversalTime().ToString("yyyy-MM-ddThh:mm:ssZ");
            }
            set
            {
                if (value == null)
                    this.DateEnd = null;
                else
                {
                    DateTime temp;

                    if (DateTime.TryParse(value, out temp))
                        this.DateEnd = temp;
                }
            }
        }

        [DataMember(Name = "password")]
        public string Password { get; set; }

        [DataMember(Name = "conference_call_information")]
        public ConferenceCallInformation ConferenceInformation { get; set; }

        [DataMember(Name = "participant_web_link")]
        public string Link { get; set; }

        /// <summary>
        /// Get meeting
        /// </summary>
        /// <param name="accessToken">Token</param>
        /// <param name="meetingId">Meeting Id</param>
        public static Meeting GetMeeting(string accessToken, string meetingId)
        {
            string url = string.Format("{0}/{1}", TeamViewer.URL.MEETINGS, meetingId);

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

            string json = connection.SendRequest();

            Meeting result = null;

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

            return result;
        }

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

            string url = string.Format("{0}/{1}", TeamViewer.URL.MEETINGS, meeting.MeetingId);

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

            connection.SendRequest();
        }

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

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

            json = connection.SendRequest();

            Meeting result = null;

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

            return result;
        }

        /// <summary>
        /// Creates new instant meeting
        /// </summary>
        /// <param name="accessToken">Token</param>
        public static Meeting CreateInstantMeeting(string accessToken)
        {
            string json = "{\"instant\":true}";

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

            json = connection.SendRequest();

            Meeting result = null;

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

            return result;
        }

        /// <summary>
        /// Delete meeting
        /// </summary>
        /// <param name="accessToken">Token</param>
        /// <param name="meeting">Meeting</param>
        public static void DeleteMeeting(string accessToken, Meeting meeting)
        {
            string url = string.Format("{0}/{1}", TeamViewer.URL.MEETINGS, meeting.MeetingId);

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

            connection.SendRequest();
        }

        /// <summary>
        /// Get meeting invitation text
        /// </summary>
        /// <param name="accessToken">Token</param>
        /// <param name="meeting">Meeting</param>
        public static string GetInvitationText(string accessToken, string meetingId, string language = "", string timezone = "")
        {
            string url = string.Format("{0}/{1}/invitation", TeamViewer.URL.MEETINGS, meetingId);

            if (!string.IsNullOrWhiteSpace(language))
                url += "?language=" + language;

            if (!string.IsNullOrWhiteSpace(timezone))
            {
                if (!string.IsNullOrWhiteSpace(language))
                    url += "&timezone=" + timezone;
                else
                    url += "?timezone=" + timezone;
            }

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

            string json = connection.SendRequest();

            if (!string.IsNullOrEmpty(json))
            {
                Invitation invitation = JsonConvert.DeserializeObject<Invitation>(json);

                if (invitation != null)
                    return invitation.Text;
            }

            return string.Empty;
        }
    }
}
