using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Windows.Forms;

namespace PuzzlePlayer_Namespace
{
    // struct for saving settings
    internal struct Settings(Theme t, string fName, int fSize)
    {
        public Theme theme = t;
        public string fontName = fName;
        public int fontSize = fSize;

        public override string ToString()
        {
            return $"SETTINGS|{fontName}|{fontSize}|{theme.ToString()}";
        }

        public static Settings FromString(string s)
        {
            string[] split = s.Split('|');
            if (split[0] != "SETTINGS")
                throw new Exception("Invallid input string in FromString methode from Settings struct");

            string themeString = "";
            for (int i = 3; i < split.Length; i++) // add everything after the fontsize to the themestring
            {
                themeString += split[i];
            }

            return new Settings(Theme.FromString(themeString), split[1], int.Parse(split[2]));
        }
    }

    // struct for saving themes
    internal struct Theme(string s, Color col1, Color col2, Color col3)
    {
        public string name = s;
        public Color primaryColor = col1;
        public Color secondaryColor = col2;
        public Color tertiaryColor = col3;

        public override string ToString()
        {
            return $"THEME|{name}|{primaryColor.ToArgb()}|{secondaryColor.ToArgb()}|{tertiaryColor.ToArgb()}|";
        }

        public static Theme FromString(string s)
        {
            string[] split = s.Split('|');
            if (split[0] != "THEME")
                throw new Exception("Invallid input string in FromString methode from Theme struct");

            Color c1 = Color.FromArgb(int.Parse(split[2]));
            Color c2 = Color.FromArgb(int.Parse(split[3]));
            Color c3 = Color.FromArgb(int.Parse(split[4]));

            return new Theme(split[1],c1,c2,c3);
        }
    }

    internal class SettingForm : Form
    {
        // Public variables for all settings
        // Currently they are set to their default values
        public static Color primaryColor = Color.FromArgb(66, 69, 73);
        public static Color secondaryColor = Color.FromArgb(54, 57, 62);
        public static Color tertiaryColor = Color.FromArgb(0, 0, 0);
        public static int fontSize = 16;
        public static string mainFontName = "Gotham";
        public static Font mainFont = new Font(mainFontName, fontSize);
        public static FlowLayoutPanel settingsPanel;

        // For storing user settings
        private Settings settings;
        private static string filePath = "Settings.txt";

        public SettingForm()
        {
            settings = GetUserSettings();

            SetUpUi();

            this.BackColor = primaryColor;

            foreach (Control control in Controls)
            {
                UpdateSettings(control);
            }
            Invalidate();
        }

        private Settings GetUserSettings()
        {
            StreamReader reader = new StreamReader(System.IO.File.OpenRead(filePath));
            Settings? newSettings = null;
            string s = "";
            while ((s = reader.ReadLine()) != null)
            {
                if(s.StartsWith("SETTINGS"))
                {
                    newSettings = Settings.FromString(s);
                    break;
                }   
            }
            reader.Dispose();

            if (newSettings != null)
                return (Settings)newSettings;
            else
                MakeNewSettingsFile();          // if the settings could not be read then a new file must be made

            return GetUserSettings();           // after the new file is made it is save to call getUserSettings again
        }

        private void MakeNewSettingsFile()
        {
            FileStream fs = File.Create(filePath);
            StreamReader reader = new StreamReader(fs);
            throw new NotImplementedException();
        }

        private void SetUpUi()
        {
            this.ClientSize = new Size(1115, 755);
            this.BackColor = SettingForm.primaryColor;
            this.Text = "PuzzlePlayer";

            MenuStrip menuStrip = new MenuStrip
            {
                BackColor = secondaryColor,
                ForeColor = secondaryColor,
                Name = "Main menu",
                Text = "Main Menu",
                Dock = DockStyle.Top
            };

            ToolStripMenuItem menuBack = new ToolStripMenuItem
            {
                BackColor = secondaryColor,
                ForeColor = Color.Black,
                Text = "Back",
                TextAlign = ContentAlignment.BottomRight
            };

            menuBack.Click += (object o, EventArgs e) =>
            {
                this.Close();
            };

            //
            ComboBox themeSelector = new ComboBox
            {
                Text = "Theme",
                Name = "Theme",
                Height = 25,
                Width = 250,
                BackColor = SettingForm.secondaryColor,
                ForeColor = Color.Black,
                Margin = new Padding(20)
            };
            themeSelector.Items.Add("Dark");
            themeSelector.Items.Add("Light");
            themeSelector.Items.Add("Pink");

            themeSelector.SelectedIndexChanged += (object o, EventArgs e) =>
            {
                switch (themeSelector.Text)
                {
                    case "Dark":
                        SettingForm.primaryColor = Color.FromArgb(66, 69, 73);
                        SettingForm.secondaryColor = Color.FromArgb(54, 57, 62);
                        SettingForm.tertiaryColor = Color.FromArgb(0, 0, 0);
                        break;
                    case "Light":
                        SettingForm.primaryColor = Color.FromArgb(228, 229, 241);
                        SettingForm.secondaryColor = Color.FromArgb(210, 211, 219);
                        SettingForm.tertiaryColor = Color.FromArgb(72, 75, 106);
                        break;
                    case "Pink":
                        SettingForm.primaryColor = Color.FromArgb(255, 209, 220);
                        SettingForm.secondaryColor = Color.FromArgb(252, 178, 197);
                        SettingForm.tertiaryColor = Color.FromArgb(251, 199, 255);
                        break;
                }
            };

            ComboBox sizeSelector = new ComboBox
            {
                Text = "Size",
                Name = "Size",
                Height = 25,
                Width = 250,
                BackColor = SettingForm.secondaryColor,
                ForeColor = Color.Black,
                Margin = new Padding(20),
            };
            sizeSelector.Items.Add("Small");
            sizeSelector.Items.Add("Medium");
            sizeSelector.Items.Add("Large");

            sizeSelector.SelectedIndexChanged += (object o, EventArgs e) =>
            {
                switch (sizeSelector.Text)
                {
                    case "Small":
                        fontSize = 8;
                        break;
                    case "Medium":
                        fontSize = 16;
                        break;
                    case "Large":
                        fontSize = 24;
                        break;
                }
                mainFont = new Font("Gotham", fontSize);
                settingsPanel.PerformLayout();
            };

            settingsPanel = new FlowLayoutPanel
            {
                Location = new Point(0, menuStrip.Height),
                Size = new Size(ClientSize.Width, ClientSize.Height - menuStrip.Height - 100),
                Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom,
                FlowDirection = FlowDirection.TopDown,
                WrapContents = true,
                AutoScroll = true,
                Padding = new Padding(20),
            };

            //
            RoundedButton saveButton = new RoundedButton
            {
                Text = "Save",
                Name = "Save",
                Height = 100,
                Width = 350,
                BackColor = SettingForm.secondaryColor,
                ForeColor = Color.Black,
                Location = new Point(10, ClientSize.Height - 110),
                Anchor = AnchorStyles.Left | AnchorStyles.Bottom,
                FlatStyle = FlatStyle.Flat,
                Margin = new Padding(10)
            };

            saveButton.Click += (object o, EventArgs e) =>
            {
                this.BackColor = primaryColor;

                foreach (Control control in Controls)
                {
                    UpdateSettings(control);
                }

                settingsPanel.BackColor = primaryColor;
                Invalidate();
            };

            //
            this.Controls.Add(menuStrip);
            this.Controls.Add(settingsPanel);
            this.Controls.Add(saveButton);

            settingsPanel.Controls.Add(themeSelector);
            settingsPanel.Controls.Add(sizeSelector);

            menuStrip.Items.Add(menuBack);
            
            menuStrip.BringToFront();
            themeSelector.BringToFront();
            saveButton.BringToFront();
        }

        public static void UpdateSettings(Control control)
        {
            if (control is not FlowLayoutPanel)
            {
                control.BackColor = secondaryColor;
                control.ForeColor = tertiaryColor;
            }
            else
            {
                control.BackColor = primaryColor;
            }

            control.Font = mainFont;

            foreach (Control childControl in control.Controls)
            {
                UpdateSettings(childControl);
            }

            if (control is MenuStrip menuStrip)
            {
                foreach (ToolStripItem item in menuStrip.Items)
                {
                    UpdateToolStripSettings(item);
                }
            }
        }

        public static void UpdateToolStripSettings(ToolStripItem item)
        {
            item.BackColor = secondaryColor;
            item.ForeColor = tertiaryColor;
            item.Font = mainFont;

            if (item is ToolStripMenuItem menuItem)
            {
                foreach (ToolStripItem subItem in menuItem.DropDownItems)
                {
                    UpdateToolStripSettings(subItem);
                }
            }
        }

        public static Image GetEmbeddedImage(string imageWithExtention)
        {
            string imagePath = "PuzzlePlayer_Namespace.Resources." + imageWithExtention;
            Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(imagePath);
            Image img = Image.FromStream(stream);
            stream.Dispose();
            return img;
        }
    }
}