// See https://aka.ms/new-console-template for more information
using System;
using System.Globalization;

/// <summary>
/// Aplikacja konsolowa prezentująca działanie klasy Kosc.
/// </summary>
internal static class Program
{
    private static int Main(string[] args)
    {
        if (args.Length > 0 && args[0] == "--test")
        {
            return KoscTests.Run();
        }

        int wartoscUzytkownika = PobierzWartosc();

        Kosc pierwszaKosc = new Kosc(wartoscUzytkownika);
        WyswietlInformacje(pierwszaKosc, 1);

        Kosc drugaKosc = new Kosc();
        WyswietlInformacje(drugaKosc, 2);

        return 0;
    }

    private static void WyswietlInformacje(Kosc kosc, int numerKosci)
    {
        string dostepnosc = kosc.Dostepna ? "tak" : "nie";

        Console.WriteLine($"\nKość nr {numerKosci}");
        Console.WriteLine($"Liczba utworzonych instancji klasy Kosc: {Kosc.LiczbaInstancji}");
        Console.WriteLine($"Liczba oczek: {kosc.LiczbaOczek} ({kosc.WartoscSlownie()})");
        Console.WriteLine($"Nazwa pliku graficznego: {kosc.NazwaPliku}");
        Console.WriteLine($"Kość jest dostępna: {dostepnosc}");
    }

    private static int PobierzWartosc()
    {
        Console.Write("Podaj wartość pierwszej kości (1-6): ");
        string? tekst = Console.ReadLine();

        if (int.TryParse(tekst, NumberStyles.Integer, CultureInfo.InvariantCulture, out int wartosc))
        {
            return wartosc;
        }

        Console.WriteLine("Podana wartość nie jest liczbą całkowitą. Przyjęto wartość 0.");
        return 0;
    }
}

/// <summary>
/// Reprezentuje pojedynczą sześcienną kość do gry.
/// </summary>
internal sealed class Kosc
{
    private static readonly Random GeneratorLosowy = new Random();

    private static readonly string[] NazwyPlikow =
    {
        "kosc0.png",
        "kosc1.png",
        "kosc2.png",
        "kosc3.png",
        "kosc4.png",
        "kosc5.png",
        "kosc6.png"
    };

    private static readonly string[] WartosciSlownie =
    {
        "zero",
        "jeden",
        "dwa",
        "trzy",
        "cztery",
        "pięć",
        "sześć"
    };

    public static int LiczbaInstancji { get; private set; }

    public int LiczbaOczek { get; private set; }
    public int IdentyfikatorPliku { get; private set; }
    public bool Dostepna { get; private set; }

    public string NazwaPliku => NazwyPlikow[IdentyfikatorPliku];

    public Kosc() : this(LosujWartosc())
    {
    }

    public Kosc(int wartosc)
    {
        int poprawionaWartosc = CzyPoprawnaWartosc(wartosc) ? wartosc : 0;

        LiczbaOczek = poprawionaWartosc;
        IdentyfikatorPliku = poprawionaWartosc;
        Dostepna = true;

        LiczbaInstancji++;
    }

    public void Rzut()
    {
        if (!Dostepna)
        {
            return;
        }

        int wylosowanaWartosc = LosujWartosc();
        LiczbaOczek = wylosowanaWartosc;
        IdentyfikatorPliku = wylosowanaWartosc;
    }

    public void Blokuj()
    {
        Dostepna = false;
    }

    public string WartoscSlownie()
    {
        return WartosciSlownie[LiczbaOczek];
    }

    private static int LosujWartosc()
    {
        return GeneratorLosowy.Next(1, 7);
    }

    private static bool CzyPoprawnaWartosc(int wartosc)
    {
        return wartosc >= 1 && wartosc <= 6;
    }
}
