using Perfect11.Library;
using Perfect11.Properties;
using Perfect11.TweaksInterface;
using ReaLTaiizor.Enum.Poison;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Text.RegularExpressions;

namespace Perfect11
{
    public partial class Form1 : Form
    {
        private List<string> _listSystemApps = new List<string>();
        private List<IPlugin> _tweaks = new List<IPlugin>();
        private static string AppEdition = "Perfect11 Community Edition";
        public Form1()
        {
            InitializeComponent();
            InitializeDarkMode();
            GetUWPSystem();
            GetUWP();
            InitializeTweaks();
        }
        public void DarkMode(bool status)
        {
            if (status)
            {
                pages.Theme = ThemeStyle.Dark;
                welcomePage.Theme = ThemeStyle.Dark;
                debloatPage.Theme = ThemeStyle.Dark;
                poisonLabel1.Theme = ThemeStyle.Dark;
                poisonLabel2.Theme = ThemeStyle.Dark;
                LblInstalledCount.Theme = ThemeStyle.Dark;
                LblRemoveCount.Theme = ThemeStyle.Dark;
                LstUWP.Theme = ThemeStyle.Dark;
                LstUWPRemove.Theme = ThemeStyle.Dark;
                ChkShowUWPSystem.Theme = ThemeStyle.Dark;
                BtnRunUninstaller.Theme = ThemeStyle.Dark;
                addAllButton.Theme = ThemeStyle.Dark;
                addButton.Theme = ThemeStyle.Dark;
                removeAllButton.Theme = ThemeStyle.Dark;
                removeButton.Theme = ThemeStyle.Dark;
                welcomePage.BackgroundImage = Resources.win11wallpaperdark;
                tweaksPage.Theme = ThemeStyle.Dark;
                tweaksList.Theme = ThemeStyle.Dark;
                runTweaks.Theme = ThemeStyle.Dark;
                editionLabel.Theme = ThemeStyle.Dark;
                LstUWP.BackColor = Color.FromArgb(17, 17, 17);
                LstUWPRemove.BackColor = Color.FromArgb(17, 17, 17);
                tweaksList.BackColor = Color.FromArgb(17, 17, 17);
                poisonLabel1.ForeColor = Color.FromArgb(255, 255, 255);
                poisonLabel2.ForeColor = Color.FromArgb(255, 255, 255);
                githubLink.Theme = ThemeStyle.Dark;
                upgradePage.Theme = ThemeStyle.Dark;
                poisonLabel3.Theme = ThemeStyle.Dark;
                poisonLabel4.Theme = ThemeStyle.Dark;
                poisonLabel5.Theme = ThemeStyle.Dark;
                upgradeMethod.Theme = ThemeStyle.Dark;
                bypassWin11RequirementsCheck.Theme = ThemeStyle.Dark;
                automateOOBECheck.Theme = ThemeStyle.Dark;
            }
            else
            {
                pages.Theme = ThemeStyle.Light;
                welcomePage.Theme = ThemeStyle.Light;
                debloatPage.Theme = ThemeStyle.Light;
                poisonLabel1.Theme = ThemeStyle.Light;
                poisonLabel2.Theme = ThemeStyle.Light;
                LblInstalledCount.Theme = ThemeStyle.Light;
                LblRemoveCount.Theme = ThemeStyle.Light;
                LstUWP.Theme = ThemeStyle.Light;
                LstUWPRemove.Theme = ThemeStyle.Light;
                ChkShowUWPSystem.Theme = ThemeStyle.Light;
                BtnRunUninstaller.Theme = ThemeStyle.Light;
                addAllButton.Theme = ThemeStyle.Light;
                addButton.Theme = ThemeStyle.Light;
                removeAllButton.Theme = ThemeStyle.Light;
                removeButton.Theme = ThemeStyle.Light;
                welcomePage.BackgroundImage = Resources.win11wallpaperlight;
                tweaksPage.Theme = ThemeStyle.Light;
                tweaksList.Theme = ThemeStyle.Light;
                runTweaks.Theme = ThemeStyle.Light;
                editionLabel.Theme = ThemeStyle.Light;
                LstUWP.BackColor = Color.FromArgb(255,255,255);
                LstUWPRemove.BackColor = Color.FromArgb(255,255,255);
                tweaksList.BackColor = Color.FromArgb(255,255,255);
                githubLink.Theme = ThemeStyle.Light;
                upgradePage.Theme = ThemeStyle.Light;
                poisonLabel3.Theme = ThemeStyle.Light;
                poisonLabel4.Theme = ThemeStyle.Light;
                poisonLabel5.Theme = ThemeStyle.Light;
                upgradeMethod.Theme = ThemeStyle.Light;
                bypassWin11RequirementsCheck.Theme = ThemeStyle.Light;
                automateOOBECheck.Theme = ThemeStyle.Light;
            }
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            pages.SelectedTab = welcomePage; // Always start from the first tab
            editionLabel.Text = AppEdition;
            //theme.Text = AppEdition;
            LstUWP.View = View.Details;
            LstUWP.Columns.Clear();
            LstUWP.Columns.Add("App Name", -2, HorizontalAlignment.Left);
            LstUWPRemove.View = View.Details;
            LstUWPRemove.Columns.Clear();
            LstUWPRemove.Columns.Add("App Name", -2, HorizontalAlignment.Left);
            int totalWidth1 = LstUWP.ClientSize.Width;
            int totalWidth2 = LstUWPRemove.ClientSize.Width;
            LstUWP.Columns[0].Width = totalWidth1;
            LstUWPRemove.Columns[0].Width = totalWidth2;
        }
        private void GetUWP()
        {
            LstUWP.Items.Clear();
            string output = PowerShell.Execute("Get-AppxPackage -allusers | Select-Object -ExpandProperty Name");
            string[] lines = output.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string line in lines)
            {
                string current = line.Trim();
                if (_listSystemApps != null)
                {
                    if ((_listSystemApps.Any(current.Contains)) && !ChkShowUWPSystem.Checked)
                        continue;
                }
                if (!LstUWP.Items.Cast<ListViewItem>().Any(item => item.Text.Equals(current, StringComparison.OrdinalIgnoreCase)))
                {
                    LstUWP.Items.Add(new ListViewItem(current));
                }
            }
            var compare = LstUWP.Items.Cast<ListViewItem>().Select(item => item.Text).ToList();
            foreach (ListViewItem removeItem in LstUWPRemove.Items)
            {
                if (compare.Contains(removeItem.Text))
                {
                    var itemToRemove = LstUWP.Items
                        .Cast<ListViewItem>()
                        .FirstOrDefault(x => x.Text == removeItem.Text);
                    if (itemToRemove != null)
                        LstUWP.Items.Remove(itemToRemove);
                }
            }
            RefreshUWP();
        }
        private void RefreshUWP()
        {
            int installed = LstUWP.Items.Count;
            int remove = LstUWPRemove.Items.Count;
            LblInstalledCount.Text = "Installed (" + installed.ToString() + ")";
            LblRemoveCount.Text = "Removing (" + remove.ToString() + ")";

            if (installed == 0)
                addAllButton.Enabled =
                addButton.Enabled =
                false;
            else
                addAllButton.Enabled =
                addButton.Enabled =
                true;

            if (remove == 0)
                removeAllButton.Enabled =
                removeButton.Enabled =
                BtnRunUninstaller.Enabled =
                false;
            else
                removeAllButton.Enabled =
                removeButton.Enabled =
                BtnRunUninstaller.Enabled =
                true;
        }
        private void GetUWPSystem()
        {
            _listSystemApps.Clear();

            using (StringReader reader = new StringReader(Resources.UWPSystemAppList))
            {
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    if (!string.IsNullOrWhiteSpace(line))
                        _listSystemApps.Add(line.Trim());
                }
            }
        }
        private string RemoveUWP()
        {
            string success = "Successfully removed:" + "\n";
            string failed = "Failed to remove:" + "\n";

            foreach (ListViewItem item in LstUWPRemove.Items)
            {
                string appName = item.Text;
                string command = $"Get-AppxPackage -allusers -Name \"{appName}\" | Remove-AppxPackage -allusers";
                string command2 = $"Get-AppxProvisionedPackage -online | Where PackageName -like *\"{appName}\"* | Remove-AppxProvisionedPackage -online";
                try
                {
                    string output3 = Utilities.EolApp(appName);
                    string output2 = PowerShell.Execute(command2);
                    string output = PowerShell.Execute(command);
#if DEBUG
                    MessageBox.Show(output3);
                    MessageBox.Show(output2);
                    MessageBox.Show(output);
#endif
                    if (!output.ToLower().Contains("error") && !output2.ToLower().Contains("error") && !output3.ToLower().Contains("error"))
                    {
                        success += "\t" + appName + "\n";
                    }
                    else
                    {
                        failed += "\t" + appName + "\n";
                    }
                }
                catch (Exception ex)
                {
                    failed += $"\t{appName} ({ex.Message})\n";
                }
            }
            return success + (failed != "Failed to remove:" + "\n" ? "\n" + failed : "");
        }

        private void ChkShowUWPSystem_CheckedChanged(object sender, EventArgs e)
        {
            if (ChkShowUWPSystem.Checked) MessageBox.Show("You're about to show system UWP apps. Those apps if removed can break several things in your system. Proceed with caution.", "Perfect11", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            GetUWP();
        }

        private void addAllButton_Click(object sender, EventArgs e)
        {
            var itemsToMove = LstUWP.Items.Cast<ListViewItem>().ToList();
            foreach (var item in itemsToMove)
            {
                LstUWPRemove.Items.Add((ListViewItem)item.Clone());
            }
            LstUWP.Items.Clear();
            RefreshUWP();
        }

        private void addButton_Click(object sender, EventArgs e)
        {
            if (LstUWP.SelectedItems.Count == 0) return;
            foreach (ListViewItem selectedItem in LstUWP.SelectedItems.Cast<ListViewItem>().ToList())
            {
                LstUWPRemove.Items.Add((ListViewItem)selectedItem.Clone());
                LstUWP.Items.Remove(selectedItem);
            }
            RefreshUWP();
        }

        private void removeButton_Click(object sender, EventArgs e)
        {
            if (LstUWPRemove.SelectedItems.Count > 0)
            {
                List<ListViewItem> selectedItems = new List<ListViewItem>();

                foreach (ListViewItem selectedItem in LstUWPRemove.SelectedItems)
                {
                    selectedItems.Add(selectedItem);
                }

                // Move each selected item
                foreach (ListViewItem item in selectedItems)
                {
                    LstUWP.Items.Add((ListViewItem)item.Clone());
                    LstUWPRemove.Items.Remove(item);
                }

                RefreshUWP();
            }
        }

        private void removeAllButton_Click(object sender, EventArgs e)
        {
            List<ListViewItem> itemsToMove = new List<ListViewItem>();
            foreach (ListViewItem item in LstUWPRemove.Items)
            {
                itemsToMove.Add((ListViewItem)item.Clone());
            }
            LstUWP.Items.AddRange(itemsToMove.ToArray());
            LstUWPRemove.Items.Clear();
            RefreshUWP();
        }

        private void BtnRunUninstaller_Click(object sender, EventArgs e)
        {
            if (LstUWPRemove.Items.Count == 0) { MessageBox.Show("No items were selected for removal.","Perfect11", MessageBoxButtons.OK,MessageBoxIcon.Information); }
            else
            {
                Enabled = false;
                MessageBox.Show(RemoveUWP(),"Perfect11",MessageBoxButtons.OK,MessageBoxIcon.Information);
                LstUWPRemove.Items.Clear();
                GetUWP();
                Enabled = true;
            }
        }
        private void InitializeTweaks()
        {
            const string tweaksFolder = "Tweaks";
            const string interfaceDll = "Perfect11.TweaksInterface.dll";

            // Ensure folder exists and remove old interface DLL
            if (!Directory.Exists(tweaksFolder))
                Directory.CreateDirectory(tweaksFolder);

            string interfacePath = Path.Combine(tweaksFolder, interfaceDll);
            if (File.Exists(interfacePath))
                File.Delete(interfacePath);

            // Load categorized plugins
            var categorizedPlugins = Utilities.LoadTweaks(tweaksFolder);

            // Setup ListView
            tweaksList.View = View.Details;
            tweaksList.FullRowSelect = true;
            tweaksList.ShowGroups = true;
            tweaksList.Items.Clear();
            tweaksList.Groups.Clear();

            // Setup columns
            tweaksList.Columns.Clear();
            tweaksList.Columns.Add("Tweak");
            tweaksList.Columns.Add("Description");
            AdjustListViewColumns();

            // Add groups and items
            foreach (var category in categorizedPlugins.OrderBy(c => c.Key))
            {
                var group = new ListViewGroup(category.Key);
                tweaksList.Groups.Add(group);

                foreach (var plugin in category.Value.OrderBy(p => p.Name))
                {
                    var item = new ListViewItem(plugin.Name)
                    {
                        Group = group,
                        Tag = plugin
                    };
                    item.SubItems.Add(plugin.Description);
                    tweaksList.Items.Add(item);
                }
            }

            // Enable or disable run button
            runTweaks.Enabled = tweaksList.Items.Count > 0;
        }

        // Adjust column widths dynamically based on ListView client width
        private void AdjustListViewColumns()
        {
            if (tweaksList.Columns.Count < 2) return;

            int totalWidth = tweaksList.ClientSize.Width;
            tweaksList.Columns[0].Width = (int)(totalWidth * 0.3); // Tweak column
            tweaksList.Columns[1].Width = (int)(totalWidth * 0.7); // Description column
        }
        private void InitializeDarkMode()
        {
            if (Utilities.IsAppsDarkMode())
            {
                DarkMode(true);
            }
            else
            {
                DarkMode(false);
            }
        }

        private async void runTweaks_Click(object sender, EventArgs e)
        {
            if (tweaksList.SelectedItems.Count == 0)
            {
                MessageBox.Show("Select one or more plugins to run.","Perfect11",MessageBoxButtons.OK,MessageBoxIcon.Information);
                return;
            }

            Enabled = false; // prevent multiple clicks
            try
            {
                foreach (ListViewItem item in tweaksList.SelectedItems)
                {
                    if (item.Tag is IPlugin plugin)
                    {
                        string result = await Task.Run(() => plugin.Execute()); // run in background thread
                        MessageBox.Show(result,"Perfect11",MessageBoxButtons.OK,MessageBoxIcon.Information);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Error running plugin: {ex.Message}", "Perfect11", MessageBoxButtons.OK,MessageBoxIcon.Error);
            }
            finally
            {
                Enabled = true;
            }
        }

        private void tweaksList_Resize(object sender, EventArgs e)
        {
            AdjustListViewColumns();
        }

        private void githubLink_Click(object sender, EventArgs e)
        {
            try
            {
                Process.Start("https://github.com/theitaliandeveloper/Perfect11/");
            }
            catch
            {
                MessageBox.Show("Looks like your browser is not available, please copy the link below and paste it in your browser's address bar:\n\nhttps://github.com/theitaliandeveloper/Perfect11/","Perfect11",MessageBoxButtons.OK,MessageBoxIcon.Information);
            }
        }

        private void pages_SelectedIndexChanged(object sender, EventArgs e)
        {
#if !DEBUG // For UI Testing do not prevent using pages if not 11
            if ((pages.SelectedTab == debloatPage || pages.SelectedTab == tweaksPage) && !Utilities.IsWindows11())
            {
                MessageBox.Show("In order to use these features you need to upgrade to Windows 11.","Perfect11",MessageBoxButtons.OK,MessageBoxIcon.Information);
                pages.SelectedTab = upgradePage;
            }
            else if (pages.SelectedTab == upgradePage && Utilities.IsWindows11())
            {
                if (MessageBox.Show("You're already using Windows 11, there's no need to upgrade. However, this page might be useful as well for reinstallation. Are you sure to continue?", "Perfect11", MessageBoxButtons.YesNo, MessageBoxIcon.Information,MessageBoxDefaultButton.Button2) == DialogResult.No)
                {
                    pages.SelectedTab = welcomePage;
                }
            }
#endif
        }

        private void poisonComboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (upgradeMethod.SelectedIndex == 3 || upgradeMethod.SelectedIndex == 2) // Both Mini11 and custom ISO
            {
                automateOOBECheck.Enabled = false;
                bypassWin11RequirementsCheck.Enabled = false;
            }
            else if (upgradeMethod.SelectedIndex != 0) // if not normal installation
            {
                bypassWin11RequirementsCheck.Enabled = false;
            }
            else
            {
                automateOOBECheck.Enabled = true;
                bypassWin11RequirementsCheck.Enabled = true;
            }
        }
    }
}
