using System;
using System.Collections.Generic;
using System.Text;

namespace WriteADeck
{
    /* 
     * UWAGA: jeśli wykonałeś wersję projektu TwoDecks dla platformy Blazor, klasa
     * Deck będzie dziedziczyć po klasie List<Card>, a nie po ObservableCollection<Card>.
     */

    using System.Collections.ObjectModel;
    using System.IO;

    class Deck : ObservableCollection<Card> 
    {
        private static Random random = new Random();

        public Deck()
        {
            Reset();
        }

        public Deck(string filename)
        {
            using (var reader = new StreamReader(filename))
            {
                while (!reader.EndOfStream)
                {
                    var nextCard = reader.ReadLine();
                    var cardParts = nextCard.Split(new char[] { ' ' });
                    var value = cardParts[0] switch
                    {
                        "As" => Values.As,
                        "Dwójka" => Values.Dwójka,
                        "Trójka" => Values.Trójka,
                        "Czwórka" => Values.Czwórka,
                        "Piątka" => Values.Piątka,
                        "Szóstka" => Values.Szóstka,
                        "Siódemka" => Values.Siódemka,
                        "Ósemka" => Values.Ósemka,
                        "Dziewiątka" => Values.Dziewiątka,
                        "Dziesiątka" => Values.Dziesiątka,
                        "Walet" => Values.Walet,
                        "Dama" => Values.Dama,
                        "Król" => Values.Król,
                        _ => throw new InvalidDataException($"Nieznana wartość karty: {cardParts[0]}")
                    };
                    var suit = cardParts[1] switch
                    {
                        "pik" => Suits.pik,
                        "trefl" => Suits.trefl,
                        "kier" => Suits.kier,
                        "karo" => Suits.karo,
                        _ => throw new InvalidDataException($"Nieznany kolor karty: {cardParts[2]}"),
                    };
                    Add(new Card(value, suit));
                }
            }
        }

        public void WriteCards(string filename)
        {
            using (var writer = new StreamWriter(filename))
            {
                for (int i = 0; i < Count; i++)
                {
                    writer.WriteLine(this[i].Name);
                }
            }
        }


        public Card Deal(int index)
        {
            Card cardToDeal = base[index];
            RemoveAt(index);
            return cardToDeal;
        }

        public void Reset()
        {
            Clear();
            for (int suit = 0; suit <= 3; suit++)
                for (int value = 1; value <= 13; value++)
                    Add(new Card((Values)value, (Suits)suit));
        }

        public Deck Shuffle()
        {
            List<Card> copy = new List<Card>(this);
            Clear();
            while (copy.Count > 0)
            {
                int index = random.Next(copy.Count);
                Card card = copy[index];
                copy.RemoveAt(index);
                Add(card);
            }

            return this;
        }

        public void Sort()
        {
            List<Card> sortedCards = new List<Card>(this);
            sortedCards.Sort(new CardComparerByValue());
            Clear();
            foreach (Card card in sortedCards)
            {
                Add(card);
            }
        }
    }
}
