using System;
using System.Collections.Generic;
using System.Linq;

namespace ZadaniaWPF.Model
{
    public class Zadania
    {
        private List<Zadanie> listaZadań = new List<Zadanie>();
        MagazynZdarzeń magazynZdarzeń = new MagazynZdarzeń();
        SzynaZdarzeń szynaZdarzeń;

        private int wyznaczId()
        {
            int najwyższeZajęteId = 0;
            if(listaZadań.Count > 0)
                najwyższeZajęteId = listaZadań.Max(z => z.Id.Value); //nie zajmujemy dziur
            return najwyższeZajęteId + 1;
        }

        public void DodajZadanie(Zadanie zadanie, bool wyślijDoUsługi = true)
        {
            zadanie.Id = wyznaczId();
            listaZadań.Add(zadanie);
            if (wyślijDoUsługi)
                if (!UsługaRest.Dodaj(zadanie))
                    throw new Exception("Błąd podczas wysyłania zadania do usługi");
            ZdarzenieDodaniaZadania zdarzenie = new ZdarzenieDodaniaZadania(zadanie);
            magazynZdarzeń.ZachowajZdarzenie(zdarzenie);
            szynaZdarzeń.Send(zdarzenie);
            //OnZadaniaZmienione();
        }

        public bool UsuńZadanie(Zadanie zadanie)
        {
            bool wynik = listaZadań.Remove(zadanie);
            if(!UsługaRest.Usuń(zadanie))
                throw new Exception("Błąd podczas wysyłania do usługi żądania usunięcia zadania");
            ZdarzenieUsunięciaZadania zdarzenie = new ZdarzenieUsunięciaZadania(zadanie);
            magazynZdarzeń.ZachowajZdarzenie(zdarzenie);
            szynaZdarzeń.Send(zdarzenie);
            //OnZadaniaZmienione();
            return wynik;
        }

        public bool UsuńZadanie(int id)
        {
            Zadanie zadanie = listaZadań.First(z => z.Id == id);
            if (zadanie == null) return false;
            return UsuńZadanie(zadanie);
        }

        private Comparison<Zadanie> porównywaniePriorytetów = 
            new Comparison<Zadanie>(
                (Zadanie zadanie1, Zadanie zadanie2) =>
                {
                    int wynik = -zadanie1.Priorytet.CompareTo(zadanie2.Priorytet);
                    if (wynik == 0) wynik = zadanie1.PlanowanyTerminRealizacji.CompareTo(zadanie2.PlanowanyTerminRealizacji);
                    return wynik;
                });

        private Comparison<Zadanie> porównywaniePlanowanychTerminówRealizacji =
            new Comparison<Zadanie>(
                (Zadanie zadanie1, Zadanie zadanie2) =>
                {
                    int wynik = zadanie1.PlanowanyTerminRealizacji.CompareTo(zadanie2.PlanowanyTerminRealizacji);
                    if (wynik == 0) wynik = -zadanie1.Priorytet.CompareTo(zadanie2.Priorytet);
                    return wynik;
                });

        public void SortujZadania(bool porównywaniePriorytetówCzyPlanowanychTerminówRealizacji)
        {
            if (porównywaniePriorytetówCzyPlanowanychTerminówRealizacji)
                listaZadań.Sort(porównywaniePriorytetów);
            else
                listaZadań.Sort(porównywaniePlanowanychTerminówRealizacji);
            ZdarzenieSortowaniaZadań zdarzenie = new ZdarzenieSortowaniaZadań() { PorównywaniePriorytetówCzyPlanowanychTerminówRealizacji = porównywaniePriorytetówCzyPlanowanychTerminówRealizacji };
            magazynZdarzeń.ZachowajZdarzenie(zdarzenie);
            szynaZdarzeń.Send(zdarzenie);
            //OnZadaniaZmienione();
        }

        /*
        #region Zdarzenie
        private ZadaniaZmienioneEventHandler zadaniaZmienione;

        public event ZadaniaZmienioneEventHandler ZadaniaZmienione
        {
            add
            {
                zadaniaZmienione += value;
                OnZadaniaZmienione();
            }
            remove
            {
                zadaniaZmienione -= value;
            }
        }

        protected void OnZadaniaZmienione()
        {
            if (zadaniaZmienione != null)
            {
                Zadanie[] zadania = listaZadań.ToArray(); //czy powinno być klonowanie?
                zadaniaZmienione(this, new ZadaniaEventArgs() { Zadania = zadania });
            }
        }
        #endregion
        */

        #region Zapis do pliku
        /*
        private Action<string, IEnumerable<Zadanie>> funkcjaZapisu;

        public Zadania(Action<string, IEnumerable<Zadanie>> funkcjaZapisu, SzynaZdarzeń szynaZdarzeń)
        {
            this.funkcjaZapisu = funkcjaZapisu;
            this.szynaZdarzeń = szynaZdarzeń;
        }

        public bool Zapisz(string ścieżkaPliku)
        {
            try
            {
                funkcjaZapisu(ścieżkaPliku, listaZadań);
                return true;
            }
            catch
            {
                return false;
            }
        }
        */
        #endregion

        public Zadania(SzynaZdarzeń szynaZdarzeń)
        {
            this.szynaZdarzeń = szynaZdarzeń;
        }
    }
}
