using laba3.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace laba3.Subprograms
{
    /// <summary>
    /// CLI math game "Gusess the answer";
    /// Player need to guess result of math function;
    /// </summary>
    internal static class GuessAnswerMath
    {
        /// <summary>
        /// Runs game;
        /// Console will be clean!;
        /// </summary>
        public static void RunGame()
        {
            const int attempts = 3;
            Console.WriteLine("Введите аргументы функции, а затем попытайтесь угадать её значение. Количество попыток ограничено!");
            bool isValid;
            do
            {
                MathFunc.setArgs(Utils.ReadDouble("аргумент a"), Utils.ReadDouble("аргумент b"));
                isValid = MathFunc.CheckArgs();
                if (!isValid)
                {
                    Console.Clear();
                    Console.WriteLine("Функция не определена при данных аргументах!");
                }
            } while (!isValid);
            MathFunc.ComputeResult();
            if (GameLogic(MathFunc.GetResult(), attempts))
            {
                Console.WriteLine("Ответ верный! Победа!");
            } else
            {
                Console.WriteLine(String.Format("Попытки кончились! Правильный ответ: {0:0.00}", MathFunc.GetResult()));
            }
        }

        private static bool GameLogic(double correctAnswer, int attempts)
        {
            bool win = false;
            for (int i = attempts; i > 0; i--)
            {
                Console.Clear();
                Console.WriteLine($"Количество попыток: {i}");
                double answer = Utils.ReadDouble("ваш ответ");
                win = Math.Abs(correctAnswer - answer) < 0.01;
                if (win)
                {
                    i = 0;
                }
            }
            return win;
        }
        private static class MathFunc
        {
            private const double PI = Math.PI;
            private const double E = Math.E;
            private static double a;
            private static double b;
            private static double result;

            public static void setArgs(double a, double b)
            {
                MathFunc.a = a;
                MathFunc.b = b;
            }

            public static void ComputeResult()
            {
                MathFunc.result = Math.Sin((Math.Pow(a, 3) + Math.Pow(b, 5)) / (2 * PI)) + Math.Pow(Math.Cos(a + b), (1.0 / 3.0));
            }

            public static bool CheckArgs()
            {
                return Math.Cos(a + b) >= 0;
            }

            public static double GetResult()
            {
                return result;
            }
        }
    }
}