using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Management;
using System.Text;
using System.Windows.Forms;
using GitCommands;
using GitCommands.Git;
using GitCommands.Patches;
using GitExtUtils.GitUI;
using GitUIPluginInterfaces;
using Microsoft.WindowsAPICodePack.Dialogs;
using ResourceManager;
namespace GitUI.CommandsDialogs
{
    public sealed partial class FormStash : GitModuleForm
    {
        private readonly TranslationString _currentWorkingDirChanges = new("Current working directory changes");
        private readonly TranslationString _noStashes = new("There are no stashes.");
        private readonly TranslationString _stashUntrackedFilesNotSupportedCaption = new("Stash untracked files");
        private readonly TranslationString _stashUntrackedFilesNotSupported = new("Stash untracked files is not supported in the version of msysgit you are using. Please update msysgit to at least version 1.7.7 to use this option.");
        private readonly TranslationString _stashDropConfirmTitle = new("Drop Stash Confirmation");
        private readonly TranslationString _cannotBeUndone = new("This action cannot be undone.");
        private readonly TranslationString _areYouSure = new("Are you sure you want to drop the stash? This action cannot be undone.");
        private readonly TranslationString _dontShowAgain = new("Don't show me this message again.");
        private readonly AsyncLoader _asyncLoader = new();
        public bool ManageStashes { get; set; }
        private GitStash _currentWorkingDirStashItem;
        [Obsolete("For VS designer and translation test only. Do not remove.")]
        private FormStash()
        {
            InitializeComponent();
            CompleteTheInitialization();
        }
        public FormStash(GitUICommands commands)
            : base(commands)
        {
            InitializeComponent();
            View.ExtraDiffArgumentsChanged += delegate { StashedSelectedIndexChanged(null, null); };
            View.TopScrollReached += FileViewer_TopScrollReached;
            View.BottomScrollReached += FileViewer_BottomScrollReached;
            CompleteTheInitialization();
        }
        private void CompleteTheInitialization()
        {
            KeyPreview = true;
            View.EscapePressed += () => DialogResult = DialogResult.Cancel;
            splitContainer1.SplitterDistance = DpiUtil.Scale(280);
            InitializeComplete();
        }
        protected override void OnKeyDown(KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Escape && e.Modifiers == Keys.None)
            {
                var focusedControl = this.FindFocusedControl();
                var comboBox = focusedControl as ComboBox;
                if (comboBox is not null && comboBox.DroppedDown)
                {
                    comboBox.DroppedDown = false;
                }
                else
                {
                    var textBox = focusedControl as TextBoxBase;
                    if (textBox is not null && textBox.SelectionLength > 0)
                    {
                        textBox.SelectionLength = 0;
                    }
                    else
                    {
                        DialogResult = DialogResult.Cancel;
                    }
                }
                // do not let the modal form react itself on this preview of the Escape key press
                e.SuppressKeyPress = true;
                e.Handled = true;
            }
            base.OnKeyDown(e);
        }
        protected override void OnKeyUp(KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Escape && e.Modifiers == Keys.None)
            {
                // do not let the modal form react itself on this preview of the Escape key press
                e.SuppressKeyPress = true;
                e.Handled = true;
            }
            base.OnKeyUp(e);
        }
        private void FormStashFormClosing(object sender, FormClosingEventArgs e)
        {
            AppSettings.StashKeepIndex = StashKeepIndex.Checked;
            AppSettings.IncludeUntrackedFilesInManualStash = chkIncludeUntrackedFiles.Checked;
        }
        private void FormStashLoad(object sender, EventArgs e)
        {
            StashKeepIndex.Checked = AppSettings.StashKeepIndex;
            chkIncludeUntrackedFiles.Checked = AppSettings.IncludeUntrackedFilesInManualStash;
            ResizeStashesWidth();
        }
        private void Initialize()
        {
            var stashedItems = Module.GetStashes().ToList();
            _currentWorkingDirStashItem = new GitStash(-1, _currentWorkingDirChanges.Text);
            stashedItems.Insert(0, _currentWorkingDirStashItem);
            Stashes.Text = "";
            StashMessage.Text = "";
            Stashes.SelectedItem = null;
            Stashes.ComboBox.DisplayMember = nameof(GitStash.Message);
            Stashes.Items.Clear();
            foreach (GitStash stashedItem in stashedItems)
            {
                Stashes.Items.Add(stashedItem);
            }
            if (ManageStashes && Stashes.Items.Count > 1)
            {
                // more than just the default ("Current working directory changes")
                Stashes.SelectedIndex = 1; // -> auto-select first non-default
            }
            else if (Stashes.Items.Count > 0)
            {
                // (no stashes) -> select default ("Current working directory changes")
                Stashes.SelectedIndex = 0;
            }
        }
        private void InitializeSoft()
        {
            GitStash gitStash = Stashes.SelectedItem as GitStash;
            Stashed.GroupByRevision = false;
            Stashed.ClearDiffs();
            Loading.Visible = true;
            Loading.IsAnimating = true;
            Stashes.Enabled = false;
            refreshToolStripButton.Enabled = false;
            toolStripButton_customMessage.Enabled = false;
            if (gitStash == _currentWorkingDirStashItem)
            {
                toolStripButton_customMessage.Enabled = true;
                _asyncLoader.LoadAsync(() => Module.GetAllChangedFiles(), LoadGitItemStatuses);
                Clear.Enabled = false; // disallow Drop  (of current working directory)
                Apply.Enabled = false; // disallow Apply (of current working directory)
            }
            else if (gitStash is not null)
            {
                _asyncLoader.LoadAsync(() => Module.GetStashDiffFiles(gitStash.Name), LoadGitItemStatuses);
                Clear.Enabled = true; // allow Drop
                Apply.Enabled = true; // allow Apply
            }
        }
        private void FileViewer_TopScrollReached(object sender, EventArgs e)
        {
            Stashed.SelectPreviousVisibleItem();
            View.ScrollToBottom();
        }
        private void FileViewer_BottomScrollReached(object sender, EventArgs e)
        {
            Stashed.SelectNextVisibleItem();
            View.ScrollToTop();
        }
        private void LoadGitItemStatuses(IReadOnlyList<GitItemStatus> gitItemStatuses)
        {
            GitStash gitStash = Stashes.SelectedItem as GitStash;
            if (gitStash == _currentWorkingDirStashItem)
            {
                // FileStatusList has no interface for both worktree<-index, index<-HEAD at the same time
                // Must be handled when displaying
                var headId = Module.RevParse("HEAD");
                var headRev = new GitRevision(headId);
                var indexRev = new GitRevision(ObjectId.IndexId)
                {
                    ParentIds = new[] { headId }
                };
                var workTreeRev = new GitRevision(ObjectId.WorkTreeId)
                {
                    ParentIds = new[] { ObjectId.IndexId }
                };
                var indexItems = gitItemStatuses.Where(item => item.Staged == StagedStatus.Index).ToList();
                var workTreeItems = gitItemStatuses.Where(item => item.Staged != StagedStatus.Index).ToList();
                Stashed.SetStashDiffs(headRev, indexRev, ResourceManager.Strings.Index, indexItems, workTreeRev, ResourceManager.Strings.Workspace, workTreeItems);
            }
            else
            {


Answer:                 var firstId = Module.RevParse(gitStash.Name + "^");