using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Net.Http;
using System.Web;
using System.Xml.Linq;

namespace WebApplication1.Models
{
    public class Wpis
    {
        private string nazwaUżytkownika;
        private string treść;
        private DateTime data;
        private string adresIP;

        public Wpis()
        { }

        [Required(ErrorMessage = "Nazwa użytkownika jest wymagana")]
        [StringLength(256, MinimumLength = 3, ErrorMessage = "Nazwa użytkownika musi mieć długość od 3 do 256 znaków")]
        [RegularExpression(@"[a-zA-Z0-9'.,ąćęłńóśżźĄĆĘŁŃÓŚŻŹ\s]{3,256}", 
            ErrorMessage = "Nazwa użytkownika składa się z niedozwolonych znaków")]
        [DisplayName("Nazwa użytkownika")]
        public string NazwaUżytkownika
        {
            get
            {
                return nazwaUżytkownika;
            }
            set
            {
                nazwaUżytkownika = value;
            }
        }

        [Required(ErrorMessage = "Brak treści wpisu")]
        public string Treść { get { return treść; }  set { treść = value; } }
        public DateTime Data { get { return data; } set { data = value; } }
        public string AdresIP { get { return adresIP; } set { adresIP = value; } }

        public Wpis(string nazwaUżytkownika, string treść, DateTime data, string adresIP)
        {
            this.nazwaUżytkownika = nazwaUżytkownika;
            this.treść = treść;
            this.data = data;
            this.adresIP = adresIP;
        }
    }

    public class Wpisy
    {
        const string url = "http://localhost:5591/";

        private bool czytajWpisyZUsługiRest()
        {
            const string uri = "api/wpisy/wszystkie";
            const string xmlNamespace = "http://schemas.datacontract.org/2004/07/WebApplication1.Models";
            
            try
            {
                using (HttpClient klient = new HttpClient())
                {
                    klient.BaseAddress = new Uri(url);
                    klient.DefaultRequestHeaders.Clear();
                    klient.DefaultRequestHeaders.Accept.Add(
                        new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/xml"));

                    HttpResponseMessage odpowiedź = klient.GetAsync(uri).Result;
                    if(odpowiedź.IsSuccessStatusCode)
                    {
                        string daneOdpowiedzi = odpowiedź.Content.ReadAsStringAsync().Result;
                        XDocument xml = XDocument.Load(new System.IO.StringReader(daneOdpowiedzi));
                        List<XElement> elementy = xml.Root.Elements().ToList();

                        wpisy.Clear();
                        for (int i = 0; i < elementy.Count; ++i)
                        {
                            XElement wpisXml = elementy[i];
                            wpisy.Add(
                                new Wpis(
                                    wpisXml.Element(XName.Get("NazwaUżytkownika", xmlNamespace)).Value,
                                    wpisXml.Element("Treść").Value,
                                    DateTime.Parse(wpisXml.Element("Data").Value),
                                    wpisXml.Element("AdresIP").Value
                                )
                            );
                        }
                    }
                }
                return true;
            }
            catch (Exception exc)
            {
                return false;
            }
        }


        private List<Wpis> wpisy = new List<Wpis>();
        public bool ZapiszDoPlikuPoKażdejZmianie = true;
        string nazwaPlikuXml;
        const string nazwaPlikuLog = @"d:\JacekMatulewski\log.txt";

        public bool ZapiszDoPlikuXml()
        {
            try
            {
                XDocument xml = new XDocument(
                    new XDeclaration("1.0", "utf-8", "yes"),
                    new XElement("Wpisy",
                        new XElement("DataZapisu", DateTime.Now.ToString()),
                        from wpis in wpisy //LINQ = SQL zanurzony w C#
                    select new XElement("Wpis",
                            new XElement("NazwaUżytkownika", wpis.NazwaUżytkownika),
                            new XElement("Treść", wpis.Treść),
                            new XElement("Data", wpis.Data.ToString()),
                            new XElement("AdresIP", wpis.AdresIP)
                        )
                    )
                );
                xml.Save(nazwaPlikuXml);
                return true;
            }
            catch(Exception exc) //wyjątek
            {
                System.IO.File.AppendAllText(
                    nazwaPlikuLog, "Błąd przy zapisie (" + DateTime.Now.ToString() + "): " + exc.Message);
                return false;
            }
        }

        /*
        private bool czytajZPlikuXml()
        {
            try
            {
                XDocument xml = XDocument.Load(nazwaPlikuXml);

                IEnumerable<Wpis> odczytaneWpisy =
                    from wpisXml in xml.Root.Elements("Wpis")
                    select
                        new Wpis(
                            wpisXml.Element("NazwaUżytkownika").Value,
                            wpisXml.Element("Treść").Value,
                            DateTime.Parse(wpisXml.Element("Data").Value),
                            wpisXml.Element("AdresIP").Value);

                wpisy.Clear();
                wpisy.AddRange(odczytaneWpisy);

                return true;
            }
            catch(Exception exc)
            {
                System.IO.File.AppendAllText(
                    nazwaPlikuLog, "Błąd przy odczycie (" + DateTime.Now.ToString() + "): " + exc.Message);
                return false;
            }
        }
        */

        public void Dodaj(Wpis wpis)
        {
            wpisy.Add(wpis);
            if (ZapiszDoPlikuPoKażdejZmianie) ZapiszDoPlikuXml();
        }
        public int Liczba
        {
            get
            {
                return wpisy.Count;
            }
        }
        public Wpis Pobierz(int indeks)
        {
            return wpisy[indeks];
        }        
        public Wpisy(string nazwaPlikuXml)
        {            
            //this.nazwaPlikuXml = nazwaPlikuXml;
            //czytajZPlikuXml();
            czytajWpisyZUsługiRest();
        }
    }
}