using System.Runtime.Serialization.Formatters.Binary;
using System.Text.Json;

namespace PiattaformaStreaming;

public class Libreria
{
    private List<Media> lib;

    public Libreria()
    {
        lib = new List<Media>();
    }

    public void Aggiungi(string titolo, int durata, int anno, int valutazione)
    {
        try 
        {
            lib.Add(new Film(titolo, durata, anno, valutazione));
        }
        catch (Exception ex)
        {
            throw;
        }
    }
    /*
    public void Aggiungi(string titolo, int durata, int anno, int valutazione)
    {
        lib.Add(new Documentario(titolo, durata, anno, valutazione));
    }
    */
    public void Aggiungi(string titolo, int anno, int valutazione, params Episodio[] episodio)
    {
        try
        {
            lib.Add(new SerieTv(titolo, anno, valutazione, episodio));
        }
        catch (Exception ex)
        {
            throw;
        }
    }

    public int NumeroFilm()
    {
        return lib.OfType<Film>().Count();
    }
    public int NumeroSerieTv()
    {
        return lib.OfType<SerieTv>().Count();
    }

    private Media Trova(int codice)
    {
        return lib.Find(x => x.Codice == codice);
    }

    public string Riproduci(int codice)
    {
        Media riproducibile = Trova(codice);
        
        if (riproducibile == null)
            throw new Exception("Nessun media trovato");
        
        return riproducibile.Riproduci();
    }

    public bool Uguali(int cod1, int cod2)
    {
        return Trova(cod1).Equals(Trova(cod2));
    }

    private string Visualizza(List<Media> m)
    {
        string s = string.Empty;
        foreach (Media media in m)
        {
            s += media.Info();
        }
        return s;
    }

    public string OrdinaPerDurata()
    {
        List<Media> sup = lib.FindAll(x => true);
        sup.Sort();
        return Visualizza(sup);
    }

    public double MediaValutazioni()
    {
        if (lib.Count == 0)
            throw new DivideByZeroException();
        
        double s = 0;
        foreach (Media m in lib)
        {
            s += m.Valutazione;
        }
        return s/lib.Count;
    }
    
    #region File testo

    public void SalvaFileTesto(string dir)
    {
        try
        {
            StreamWriter scrittura = new StreamWriter(dir + "libreria.txt");
            foreach (Media m in lib)
            {
                scrittura.WriteLine(m.ToString());
            }
            scrittura.Close();
        }
        catch (Exception ex)
        {
            throw;
        }
    }

    public void LeggiFileTesto(string dir)
    {
        try
        {
            string s;

            StreamReader lettura = new StreamReader(dir + "libreria.txt");

            while ((s = lettura.ReadLine()) != null)
            {
                switch (s.Split("|")[0])
                {
                    case "Film":
                        lib.Add(new Film(s));
                        break;
                    case "Documentario":
                        lib.Add(new Documentario(s));
                        break;
                    case "SerieTv":
                        lib.Add(new SerieTv(s));
                        break;
                }
            }
        }
        catch (Exception ex)
        {
            throw;
        }
    }
    
    #endregion
    
    #region File Binario
    
    /*
     * [Obsolete] Per zittire l'IDE che dice che è obsoleto e da errore.
     * Salvare tramite BinaryFormatter non funziona da .NET 9 in avanti
     * Perchè è stato rimosso. Vedi https://aka.ms/binaryformatter
    */
    [Obsolete("Obsolete")] 
    public void SalvaFileBinario(string dir)
    {
        try
        {
            FileStream file = new FileStream(dir + "libreria.bin", FileMode.Create);
            BinaryFormatter x = new BinaryFormatter();
            x.Serialize(file, lib);
            file.Close();
        }
        catch (Exception ex)
        {
            throw;
        }
    }
    
    [Obsolete("Obsolete")]
    public void LeggiFileBinario(string dir)
    {
        try
        {
            FileStream file = new FileStream(dir + "libreria.bin", FileMode.Open);
            BinaryFormatter x = new BinaryFormatter();
            lib = (List<Media>)x.Deserialize(file);
            file.Close();
        }
        catch (Exception ex)
        {
            throw;
        }
    }
    
    #endregion
    
    #region File JSON

    public void SalvaFileJson(string dir)
    {
        try
        {
            StreamWriter scrittura = new StreamWriter(dir + "libreria.json");
            scrittura.Write(JsonSerializer.Serialize(lib));
            scrittura.Close();
        }
        catch (Exception ex)
        {
            throw;
        }
    }

    public void LeggiFileJson(string dir)
    {
        try
        {
            StreamReader lettura = new StreamReader(dir + "libreria.json");
            string json = lettura.ReadToEnd();
            lib = JsonSerializer.Deserialize<List<Media>>(json);
            lettura.Close();
        }
        catch (Exception ex)
        {
            throw;
        }
    }
    
    #endregion
}