using System.ComponentModel;
using System.Diagnostics;
using PowerEasy.WebFuture.DataMigrations.Foundation.Log;
using PowerEasy.WebFuture.DataMigrations.Foundation.MigrationProgramme;

namespace PowerEasy.WebFuture.DataMigrations
{
    /// <summary>
    /// 迁移窗口。
    /// </summary>
    public partial class MigrationForm : Form
    {
        /// <summary>
        /// 迁移方案实例。
        /// </summary>
        private IMigrationProgramme migrationProgramme;

        /// <summary>
        /// 迁移开始时间。
        /// </summary>
        private DateTime migrationBeginTime;

        /// <summary>
        /// 迁移结束时间。
        /// </summary>
        private DateTime migrationEndTime;

        /// <summary>
        /// 迁移用时。
        /// </summary>
        private TimeSpan migrationTimeSpan;

        /// <summary>
        /// 后台工作者。
        /// </summary>
        private BackgroundWorker backgroundWorker = new BackgroundWorker();

        /// <summary>
        /// 迁移窗口构造函数。
        /// </summary>
        /// <param name="migrationProgrammeIdentifier">迁移方案标识符。</param>
        public MigrationForm(string migrationProgrammeIdentifier)
        {
            this.InitializeComponent();
            this.InitializeBackgroundWorker();
            this.InitMigrationActions(migrationProgrammeIdentifier);
        }

        /// <summary>
        /// 后台工作者。
        /// </summary>
        public BackgroundWorker BackgroundWorker
        {
            get { return this.backgroundWorker; }
            set { this.backgroundWorker = value; }
        }

        /// <summary>
        /// 上一步按钮点击事件。
        /// </summary>
        /// <param name="sender">sender。</param>
        /// <param name="e">e。</param>
        private void ButtonPreviousStep_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        /// <summary>
        /// 执行迁移点击事件。
        /// </summary>
        /// <param name="sender">sender。</param>
        /// <param name="e">e。</param>
        private void ButtonMigration_Click(object sender, EventArgs e)
        {
            if (this.BackgroundWorker.IsBusy)
            {
                return;
            }

            LogHelper.TextBox = this.textBoxProgress;
            LogHelper.BackgroundWorker = this.backgroundWorker;

            this.migrationBeginTime = DateTime.Now;

            string info = "【" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "开始迁移数据】";

            LogHelper.WriteLogAndFormLog(info);

            this.BackgroundWorker.RunWorkerAsync();
        }

        /// <summary>
        /// 初始化迁移操作按钮。
        /// </summary>
        /// <param name="migrationProgrammeIdentifier">迁移方案标识符。</param>
        private void InitMigrationActions(string migrationProgrammeIdentifier)
        {
            this.migrationProgramme = MigrationProgrammeHelper.GetMigrationProgrammeByIdentifier(migrationProgrammeIdentifier);

            var xPosition = 10;
            var yPosition = 25;
            var checkBoxHeight = 21;
            var xSpacing = 10;
            var ySpacing = 10;
            var rightMargin = 30;

            using (Graphics g = this.CreateGraphics())
            {
                foreach (var migrationItem in this.migrationProgramme.MigrationItems.OrderBy(x => x.Order))
                {
                    var textSize = g.MeasureString(migrationItem.MigrationItemName, this.Font);
                    int checkBoxWidth = (int)Math.Ceiling(textSize.Width) + 50;

                    if (xPosition + checkBoxWidth > this.ClientSize.Width - rightMargin)
                    {
                        xPosition = 10;
                        yPosition += checkBoxHeight + ySpacing;
                    }

                    var checkBox = new CheckBox
                    {
                        Text = migrationItem.MigrationItemName,
                        Size = new Size(checkBoxWidth, checkBoxHeight),
                        Location = new Point(xPosition, yPosition)
                    };

                    this.groupBoxMigrationAction.Controls.Add(checkBox);

                    xPosition += checkBoxWidth + xSpacing;
                }
            }
        }

        /// <summary>
        /// 初始化BackgroundWorker。（异步控件）。
        /// </summary>
        private void InitializeBackgroundWorker()
        {
            this.BackgroundWorker.WorkerReportsProgress = true;
            this.BackgroundWorker.WorkerSupportsCancellation = true;
            this.BackgroundWorker.DoWork += new DoWorkEventHandler(this.BackgroundWorker_DoWork);
            this.BackgroundWorker.ProgressChanged += new ProgressChangedEventHandler(this.BackgroundWorker_ProgressChanged);
            this.BackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.BackgroundWorker_RunWorkerCompleted);
        }

        /// <summary>
        /// 后台进程开始工作（当执行BackgroundWorker.RunWorkerAsync方法时会触发该事件，并且传递DoWorkEventArgs参数;）。
        /// </summary>
        /// <param name="sender">sender。</param>
        /// <param name="e">e。</param>
        private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            var migrationActions = this.groupBoxMigrationAction.Controls;
            bool haveCheckedAction = false;
            foreach (var migrationAction in migrationActions)
            {
                if (this.BackgroundWorker.CancellationPending)
                {
                    e.Cancel = true;
                    break;
                }

                if (migrationAction is CheckBox)
                {
                    var checkBox = (CheckBox)migrationAction;
                    if (checkBox.Checked)
                    {
                        haveCheckedAction = true;
                        var migrationItem = this.migrationProgramme.MigrationItems.Where(x => x.MigrationItemName == checkBox.Text).FirstOrDefault();
                        if (migrationItem != null)
                        {
                            migrationItem.Enable = true;
                        }
                    }
                }
            }

            if (haveCheckedAction)
            {
                e.Result = this.migrationProgramme.StartMigration(this.radioButton2.Checked);
            }
            else
            {
                MessageBox.Show("需要至少勾选一个迁移项目！");
            }
        }

        /// <summary>
        /// 通过响应消息，来处理界面的显示工作(当调用ReportProgress方法时发生)。
        /// </summary>
        /// <param name="sender">sender。</param>
        /// <param name="e">e。</param>
        private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            var message = (string)e.UserState;
            LogHelper.WriteLogAndFormLog(message);

            // 结束时间。
            this.migrationEndTime = DateTime.Now;

            // 用时。
            this.migrationTimeSpan = this.migrationEndTime.Subtract(this.migrationBeginTime);

            // 已用时。
            int hours = (int)this.migrationTimeSpan.TotalHours;
            int minutes = this.migrationTimeSpan.Minutes;
            int seconds = this.migrationTimeSpan.Seconds;
            this.labelProgress.Text = string.Format("{0}时:{1}分:{2}秒", hours, minutes, seconds);
        }

        /// <summary>
        /// 后台工作完成后的消息处理（异步操作完成或中途终止会触发该事件）。
        /// </summary>
        /// <param name="sender">sender。</param>
        /// <param name="e">e。</param>
        private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var message = string.Empty;
            if (Convert.ToBoolean(e.Result) == false)
            {
                message = "迁移过程出错，请查看日志！";
                LogHelper.WriteLogAndFormLog(message);
                MessageBox.Show("迁移过程出错，请查看日志！", "迁移失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
            {
                message = "迁移操作成功!";
                LogHelper.WriteLogAndFormLog(message);
                MessageBox.Show("迁移操作成功!", "迁移成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        /// <summary>
        /// 点击打开迁移日志按钮事件。
        /// </summary>
        /// <param name="sender">sender。</param>
        /// <param name="e">e。</param>
        private void ButtonLog_Click(object sender, EventArgs e)
        {
            // 获取Logs目录的路径。
            string logsPath = AppDomain.CurrentDomain.BaseDirectory + "Logs";

            try
            {
                // 检查目录是否存在。
                if (!Directory.Exists(logsPath))
                {
                    MessageBox.Show("日志目录不存在。", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                // 启动文件资源管理器并打开Logs目录。
                Process.Start("explorer.exe", logsPath);
            }
            catch (Exception ex)
            {
                // 异常处理。
                MessageBox.Show($"无法打开日志目录: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }
}
