using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Reflection.Emit;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Game : Form
    {

        public static class Invemtory
        { 
            public static bool key { get; set; }
        }
        public static class Stats
        {
            public static string character_name { get; set; }
            public static int points { get; set; }
            public static int health { get; set; }
            public static int strength { get; set; }
            public static int agility { get; set; }
            public static int luck { get; set; }
        }
        public static class Holder
        {
            public static int previous_page { get; set; }
            public static int current_page { get; set; }

            public static List<Choise> stored = new List<Choise>() { new Choise { }, new Choise { }, new Choise { } };
        }
        public class Choise
        {
            public string text { get; set; }
            public List<int> next_pages { get; set; }
            public int next_event { get; set; }
        }
        public class Page
        {
            public string page_text { get; set; }
            public List<int> enemie { get; set; }
            public int event_on_the_page { get; set; }
            public int event_page { get; set; }
            public List<Choise> choices { get; set; }
        }
        public Game()
        {
            InitializeComponent();
        }

        private void to_begin() 
        {
            Stats.health = 3;
            List<PictureBox> pics = new List<PictureBox>() { pictureBox1, pictureBox2, pictureBox3 };
            foreach (var pic in pics)
            {
                pic.Image = Properties.Resources.heart;
            }
            Get_page(0);
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            panel4.BringToFront();
            panel5.BringToFront();
            Holder.current_page = 0;
            Stats.points = 15;
            Stats.health = 3;
            Stats.strength = 0;
            Stats.agility = 0;
            Stats.luck = 0;
            label6.Text = "Доступные очки: " + Stats.points.ToString();
            label3.Text = "Сила: " + Stats.strength.ToString();
            label4.Text = "Ловкость: " + Stats.agility.ToString();
            label5.Text = "Удача: " + Stats.luck.ToString();
            List<PictureBox> pics = new List<PictureBox>() { pictureBox1, pictureBox2, pictureBox3 };
            foreach (var pic in pics)
            {
                pic.Image = Properties.Resources.heart;
            }
        }

        private void start(object sender, EventArgs e)
        {
            label2.Text = "Сила: " + Stats.strength.ToString() + " Ловкость: " + Stats.agility.ToString() + " Удача: " + Stats.luck.ToString();
            if (Stats.luck <= 4)
            {
                if (Stats.agility > 5)
                {
                    Holder.current_page = 0;
                }
                else
                {
                    Holder.current_page = 1;
                }
            }
            else
            {
                if (Stats.agility > 5)
                {
                    Holder.current_page = 2;
                }
                else
                {
                    Holder.current_page = 3;
                }
            }

            //
            //Holder.current_page = 1000;
            //


            Get_page(Holder.current_page);
            panel1.SendToBack();
        }

                
        private void Get_page(int page_id)
        {
            string path = "";
            label13.Text = page_id.ToString();
            Holder.previous_page = Holder.current_page;
            Holder.current_page = page_id;
            Button[] buttons = new[] { button1, button2, button3 };

            for (int i = 0; i < buttons.Length; i++)
            {
                buttons[i].Hide();
            }

           
            path = Environment.CurrentDirectory + "/Resources/pages/" + Holder.current_page.ToString() + ".json";

            if (!File.Exists(path))
            {
                path = Environment.CurrentDirectory + "/Resources/pages/404.json";
            }

            using (StreamReader jsonStream = File.OpenText(path))
            {
                var json = jsonStream.ReadToEnd();
                Page page_data = JsonConvert.DeserializeObject<Page>(json);
                string formated_text = page_data.page_text.Replace("%name%", Stats.character_name);
                
                int event_result = 0;

                if (page_data.event_on_the_page > 0)
                {
                    event_result = Event_handler(page_data.event_on_the_page);
                }

                if (event_result == 1)
                {
                    Get_page(page_data.event_page);
                    return;
                }

                richTextBox1.Text = formated_text;

                for (int i = 0; i < page_data.choices.Count; i++)
                {
                    Holder.stored[i] = page_data.choices[i];
                    buttons[i].Text = page_data.choices[i].text;
                    if (page_data.choices[i].next_pages.Count > 1)
                    {
                        buttons[i].Image = Properties.Resources.dice_ico;
                    }
                    else 
                    {
                        buttons[i].Image = null;
                    }
                    buttons[i].Show();
                }

                richTextBox1.Text += "\n\n";

                List<string> stats_list = new List<string>() { "Сила противника: ", "Ловковсть противника: ", "Удача противника: "};

                if (page_data.enemie != null) 
                {
                    for (int i = 0; i < 3; i++) 
                    {
                        richTextBox1.Text += stats_list[i] + page_data.enemie[i] + "\n";
                    }
                }
            }
        }
        private int Event_handler(int id)
        {
            int response = 0;
            switch (id)
            {
                case 1:
                    response = Change_health(-1);
                    break;
                case 2:
                    response = Change_health(1);
                    break;
                case 3:
                    Restart();
                    break;
                case 4:
                    response = Test_stat(0);
                    break;
                case 5:
                    response = Test_stat(1);
                    break;
                case 6:
                    response = Test_stat(2);
                    break;
                case 7:
                    Get_key();
                    break;
                case 8:
                    Use_key();
                    break;
            }

            return response;
        }
        private int Test_stat(int stat)
        {
            Random rnd = new Random();
            int dice1 = rnd.Next(0, 4);
            int dice2 = rnd.Next(0, 4);
            int dice3 = rnd.Next(0, 4);

            label10.Text = dice1.ToString();
            label11.Text = dice2.ToString();
            label12.Text = dice3.ToString();

            int sum = dice1 + dice2 + dice3;

            List<int> stats_values = new List<int>() { Stats.strength, Stats.agility, Stats.luck};

            if (sum < stats_values[stat])
            {                        
                return 0;                
            }
            else 
            {
                return 1;
            }            
        }

        private void Get_key()
        {
            Invemtory.key = true;
            pictureBox7.Image = Properties.Resources.key;
        }

        private void Use_key()
        {
            Invemtory.key = false;
            pictureBox7.Image = null;
        }

        private int Change_health(int modifier)
        {
            Stats.health += modifier;
            Stats.health = Math.Min(3, Stats.health);
            Stats.health = Math.Max(-1, Stats.health);
            List<PictureBox> pics = new List<PictureBox>() { pictureBox1, pictureBox2, pictureBox3 };

            foreach (var pic in pics)
            {
                if (Convert.ToInt32(pic.Tag) >= Stats.health)
                {
                    pic.Image = Properties.Resources.disabled_heart;
                }
                else
                {
                    pic.Image = Properties.Resources.heart;
                }
            }

            if (Stats.health > 0)
            {
                return 0;
            }
            
            else
            {
                return 1;                
            }        
        }
             
        private void Change_strength(int modifier)
        {
            Stats.strength += modifier;
            Stats.strength = Math.Min(100, Stats.strength);
            Stats.strength = Math.Max(10, Stats.strength);
            label2.Text = "Сила: " + Stats.strength.ToString() + " Ловкость: " + Stats.agility.ToString() + " Удача: " + Stats.luck.ToString();
        }

        private void Restart() 
        {
            
            panel4.BringToFront();
            
            Holder.current_page = 0;
            Stats.points = 15;
            Stats.health = 3;
            label6.Text = "Доступные очки: " + Stats.points.ToString();
            label3.Text = "Сила: " + Stats.strength.ToString();
            label4.Text = "Ловкость: " + Stats.agility.ToString();
            label5.Text = "Удача: " + Stats.luck.ToString();
            List<PictureBox> pics = new List<PictureBox>() { pictureBox1, pictureBox2, pictureBox3 };
            foreach (var pic in pics)
            {
                pic.Image = Properties.Resources.heart;
            }
        }

        private void Button_click(object sender, EventArgs e)
        {
            if (sender is Button btn)
            {
                label10.Text = "0";
                label11.Text = "0";
                label12.Text = "0";

                List<int> page_id = Holder.stored[Convert.ToInt32(btn.Tag)].next_pages;
                int event_id = Holder.stored[Convert.ToInt32(btn.Tag)].next_event;
                int result = 0;

                if (event_id > 0)
                {
                    result = Event_handler(event_id);
                }

                if (page_id[result] == -1)
                {
                    Get_page(Holder.previous_page);
                }
                else if (page_id[result] == -2) 
                {
                    Restart();
                }
                else if (page_id[result] == -3)
                {
                    to_begin();
                }
                else
                {
                    Get_page(page_id[result]);
                }              
            }
        }

        private void strength_ValueChanged(object sender, EventArgs e)
        {
            if (sender is Button btn)
            {
                int dir = Convert.ToInt32(btn.Tag);

                if (Stats.points > 0)
                {
                    if (dir > 0 & Stats.strength < 9)
                    {
                        Stats.strength += dir;
                        Stats.points -= dir;
                    }
                    else if (dir < 0 & Stats.strength > 0)
                    {
                        Stats.strength += dir;
                        Stats.points -= dir;
                    }
                }

                else if (Stats.points == 0)
                {
                    if (dir < 0)
                    {
                        Stats.strength += dir;
                        Stats.points -= dir;

                    }
                }
                label3.Text = "Сила: " + Stats.strength.ToString();
                label6.Text = "Доступные очки: " + Stats.points.ToString();
            }                        
        }

        private void agility_ValueChanged(object sender, EventArgs e)
        {
            if (sender is Button btn)
            {
                int dir = Convert.ToInt32(btn.Tag);

                if (Stats.points > 0)
                {
                    if (dir > 0 & Stats.agility < 9)
                    {
                        Stats.agility += dir;
                        Stats.points -= dir;
                    }
                    else if (dir < 0 & Stats.agility > 0)
                    {
                        Stats.agility += dir;
                        Stats.points -= dir;
                    }
                }

                else if (Stats.points == 0)
                {
                    if (dir < 0)
                    {
                        Stats.agility += dir;
                        Stats.points -= dir;

                    }
                }
                label4.Text = "Ловкость: " + Stats.agility.ToString();
                label6.Text = "Доступные очки: " + Stats.points.ToString();
            }
        }

        private void luck_ValueChanged(object sender, EventArgs e)
        {
            if (sender is Button btn)
            {
                int dir = Convert.ToInt32(btn.Tag);

                if (Stats.points > 0)
                {
                    if (dir > 0 & Stats.luck < 9)
                    {
                        Stats.luck += dir;
                        Stats.points -= dir;
                    }
                    else if (dir < 0 & Stats.luck > 0)
                    {
                        Stats.luck += dir;
                        Stats.points -= dir;
                    }
                }

                else if (Stats.points == 0)
                {
                    if (dir < 0)
                    {
                        Stats.luck += dir;
                        Stats.points -= dir;

                    }
                }
                label5.Text = "Удача: " + Stats.luck.ToString();
                label6.Text = "Доступные очки: " + Stats.points.ToString();
            }
        }

        private void button11_Click(object sender, EventArgs e)
        {
            panel3.BringToFront();
        }

        private void button13_Click(object sender, EventArgs e)
        {
            panel3.SendToBack();
        }

        private void button12_Click(object sender, EventArgs e)
        {
            panel3.SendToBack();
            Restart();            
        }

        private void button14_Click(object sender, EventArgs e)
        {
            if (textBox1.Text == "")
            {
                Stats.character_name = "Славик";
            }
            else 
            {
                Stats.character_name = textBox1.Text;
            }
            panel4.SendToBack();
            panel1.BringToFront();
        }

        private void button15_Click(object sender, EventArgs e)
        {
            panel5.SendToBack();
        }
    }
}
