using DBMigration.Models;
using DBMigration.Services;
using Microsoft.Data.SqlClient;

namespace DBMigration.Forms
{
    public partial class ProgressForm : Form
    {
        private readonly List<DatabaseObject> _objects;
        private readonly ConnectionInfo _source;
        private readonly ConnectionInfo _target;
        private readonly MigrationService _migrationService;

        public ProgressForm(List<DatabaseObject> objects, ConnectionInfo source, ConnectionInfo target)
        {
            InitializeComponent();
            _objects = objects;
            _source = source;
            _target = target;
            _migrationService = new MigrationService();

            progressBar.Maximum = _objects.Count;
        }

        private async void ProgressForm_Load(object sender, EventArgs e)
        {
            await Task.Run(() => MigrateObjects());
        }

        private void MigrateObjects()
        {
            foreach (var obj in _objects)
            {
                try
                {
                    UpdateProgress($"마이그레이션 시작: {obj.Type} {obj.Schema}.{obj.Name}");

                    if (obj.Type == "TABLE")
                    {
                        _migrationService.MigrateTable(obj, _source, _target);
                    }
                    else
                    {
                        // 뷰나 프로시저의 경우 스크립트만 실행
                        ExecuteScript(obj.Definition, _target);
                    }

                    UpdateProgress($"완료: {obj.Type} {obj.Schema}.{obj.Name}");
                    UpdateProgressBar();
                }
                catch (Exception ex)
                {
                    UpdateProgress($"오류 발생: {obj.Type} {obj.Schema}.{obj.Name}");
                    UpdateProgress($"에러 메시지: {ex.Message}");

                    if (MessageBox.Show(
                        $"{obj.Type} {obj.Schema}.{obj.Name} 마이그레이션 중 오류가 발생했습니다.\n계속 진행하시겠습니까?",
                        "오류",
                        MessageBoxButtons.YesNo,
                        MessageBoxIcon.Error) == DialogResult.No)
                    {
                        break;
                    }
                }
            }

            MessageBox.Show("마이그레이션이 완료되었습니다.", "완료", MessageBoxButtons.OK, MessageBoxIcon.Information);
            DialogResult = DialogResult.OK;
        }

        private void UpdateProgress(string message)
        {
            if (InvokeRequired)
            {
                Invoke(new Action<string>(UpdateProgress), message);
                return;
            }

            logTextBox.AppendText(message + Environment.NewLine);
            logTextBox.SelectionStart = logTextBox.TextLength;
            logTextBox.ScrollToCaret();
        }

        private void UpdateProgressBar()
        {
            if (InvokeRequired)
            {
                Invoke(new Action(UpdateProgressBar));
                return;
            }

            progressBar.Value++;
        }

        private void ExecuteScript(string script, ConnectionInfo connection)
        {
            using (var conn = new SqlConnection(connection.GetConnectionString()))
            {
                conn.Open();
                using (var cmd = new SqlCommand(script, conn))
                {
                    cmd.ExecuteNonQuery();
                }
            }
        }
    }
}
