namespace BasicCoding;

internal static class Patterns
{
    internal static void DeclarationPatterns(object o)
    {
        switch (o)
        {
        case string s:
            Console.WriteLine($"Łańcuch ma długość {s.Length} znaków.");
            break;
         case int i:
            Console.WriteLine($"To jest liczba! {i}");
            break;
        }
    }

    internal static void TypePatterns(object o)
    {
        switch (o)
        {
        case string s:
            Console.WriteLine($"Łańcuch ma długość {s.Length} znaków.");
            break;

        case int:
            Console.WriteLine("To jest liczba!");
            break;
        }
    }

    internal static void PositionalPatterns(object o)
    {
        switch (o)
        {
        case (0, int y):
            Console.WriteLine($"To jest na osi X, na wysokości {y}");
            break;

        case (int x, int y):
            Console.WriteLine($"Znam to miejsce: {x}, {y}");
            break;

        case (int x, _):
            Console.WriteLine($"Na osi X: {x}. A jeśli chodzi o oś Y, to kto wie?");
            break;

        case (var x, var y):
            Console.WriteLine($"Znam to miejsce: {x}, {y}");
            break;
        }
    }

    internal static void PositionalPatternsWithConstantValues ((int x, int y) p)
    {
        switch (p)
        {
        case (0, 0):
            Console.WriteLine("Jak oryginalnie...");
            break;

        case (0, 1):
        case (1, 0):
            Console.WriteLine("Cóż za symetria...");
            break;

        case (1, 1):
            Console.WriteLine("Po równo...");
            break;
        }
    }

    internal static void PropertyPatterns(object o)
    {
        switch (o)
        {
        case string { Length: 0 }:
            Console.WriteLine("Jaką długość ma łańcuch? Niewielką!");
            break;
        }

        switch (o)
        {
        case string { Length: 0 } s:
            Console.WriteLine($"Jaką długość ma łańcuch? Ten liczy {s.Length} znaków.");
            break;
        }

        switch (o)
        {
        case string { Length: int length }:
            Console.WriteLine($"Jaką długość ma łańcuch? Ten liczy {length} znaków.");
            break;
        }

        switch (Environment.OSVersion)
        {
        case { Version: { Major: 10 } }:
            Console.WriteLine("Windows 10, 11, lub nowszy");
            break;
        }

        switch (Environment.OSVersion)
        {
        case { Version.Major: 10 }:
            Console.WriteLine("Windows 10 lub nowszy");
            break;
        }
    }

    internal static void CombinationAndNegation(string middleName)
    {
        switch (middleName)
        {
        case not null:
            Console.WriteLine($"Drugie imię użytkownika to: {middleName}");
            break;
        }

        switch (middleName)
        {
        case not null and not "David":
            Console.WriteLine($"Drugie imię użytkownika to: {middleName}");
            break;
        }    
    }

    internal static void Relational(int value)
    {
        switch (value)
        {
        case > 0: Console.WriteLine("Dodania"); break;
        case < 0: Console.WriteLine("Ujemna"); break;
        default: Console.WriteLine("Ani dodatnia, ani ujemna"); break;
        };

        switch (value)
        {
        case >= 168 and <= 189:
            Console.WriteLine("Mieści się w 90 percentylach.");
            break;
        }
    }

    internal static void PatternsWithWhen(object o)
    {
        switch (o)
        {
        case (int w, int h) when w > h:
            Console.WriteLine("Tryb poziomy");
            break;
        }
    }

    internal static string NonExpressionPatterns(object shape)
    {
        switch (shape)
        {
        case (int w, int h) when w < h: return "Pionowy";
        case (int w, int h) when w > h: return "Poziomy";
        case (int _, int _): return "Kwadrat";
        default: return "Nieznany";
        }
    }

    internal static string ExpressionPatterns(object shape)
    {
        return shape switch
        {
            (int w, int h) when w < h => "Pionowy",
            (int w, int h) when w > h => "Poziomy",
            (int _, int _) => "SquKwadratare",
            _ => "Nieznany"
        };
    }

    internal static void IsExpression(object value)
    {
        bool isPoint = value is (int, int);
    }

    internal static void MoreIsExpressions(object value)
    {
        if (value is (int x, int y))
        {
            Console.WriteLine($"X: {x}, Y: {y}");
        }

        if (value is (int w, int h) && w < h)
        {
            Console.WriteLine($"(Tryb poziomy) szerokość: {w}, wysokość: {h}");
        }
    }

    internal static void NotNullTest(string s)
    {
        if (s is not null)
        {
            Console.WriteLine(s.Length);
        }
    }
}
