using System;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
using AR;
using COMM;

namespace Project.Dialog
{
    public partial class fStateMachineDebug : Form
    {
        private System.Windows.Forms.Timer updateTimer;
        private TextBox txtDebugInfo;
        private Button btnRefresh;
        private Button btnForceRestart;
        
        public fStateMachineDebug()
        {
            InitializeComponent();
            InitializeCustomComponents();
            
            updateTimer = new System.Windows.Forms.Timer();
            updateTimer.Interval = 500; // 0.5초마다 업데이트
            updateTimer.Tick += UpdateTimer_Tick;
            updateTimer.Start();
        }

        private void InitializeCustomComponents()
        {
            this.Text = "상태머신 디버그 모니터";
            this.Size = new Size(800, 600);
            this.StartPosition = FormStartPosition.CenterScreen;
            this.FormBorderStyle = FormBorderStyle.Sizable;
            
            // TextBox 생성
            txtDebugInfo = new TextBox
            {
                Multiline = true,
                ScrollBars = ScrollBars.Both,
                Dock = DockStyle.Fill,
                Font = new Font("Consolas", 9),
                ReadOnly = true,
                BackColor = Color.Black,
                ForeColor = Color.LimeGreen
            };
            
            // 버튼 패널
            var buttonPanel = new Panel
            {
                Dock = DockStyle.Bottom,
                Height = 50
            };
            
            btnRefresh = new Button
            {
                Text = "새로고침",
                Location = new Point(10, 10),
                Size = new Size(100, 30)
            };
            btnRefresh.Click += (s, e) => UpdateDebugInfo();
            
            btnForceRestart = new Button
            {
                Text = "상태머신 재시작",
                Location = new Point(120, 10),
                Size = new Size(120, 30),
                BackColor = Color.IndianRed
            };
            btnForceRestart.Click += BtnForceRestart_Click;
            
            var btnBreakNow = new Button
            {
                Text = "즉시 중단",
                Location = new Point(250, 10),
                Size = new Size(100, 30),
                BackColor = Color.Orange
            };
            btnBreakNow.Click += (s, ev) => {
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    System.Diagnostics.Debugger.Break();
                }
                else
                {
                    MessageBox.Show("디버거가 연결되지 않았습니다.", "알림");
                }
            };
            
            buttonPanel.Controls.Add(btnRefresh);
            buttonPanel.Controls.Add(btnForceRestart);
            buttonPanel.Controls.Add(btnBreakNow);
            
            this.Controls.Add(txtDebugInfo);
            this.Controls.Add(buttonPanel);
        }

        private void UpdateTimer_Tick(object sender, EventArgs e)
        {
            UpdateDebugInfo();
        }

        private void UpdateDebugInfo()
        {
            try
            {
                var info = new System.Text.StringBuilder();
                info.AppendLine("=== 상태머신 디버그 정보 ===");
                info.AppendLine($"현재 시간: {DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}");
                info.AppendLine();
                
                if (PUB.sm != null)
                {
                    info.AppendLine($"상태머신 객체: 존재");
                    info.AppendLine($"IsThreadRun: {PUB.sm.IsThreadRun}");
                    info.AppendLine($"LoopCount: {PUB.sm.LoopCount}");
                    
                    var lastLoopElapsed = (DateTime.Now - PUB.sm.LastLoopTime).TotalSeconds;
                    var loopStatus = lastLoopElapsed < 1 ? "정상" : "경고!";
                    var loopColor = lastLoopElapsed < 1 ? "" : " <<<<<<";
                    info.AppendLine($"마지막 루프: {lastLoopElapsed:F2}초 전 [{loopStatus}]{loopColor}");
                    
                    info.AppendLine($"현재 Step: {PUB.sm.Step}");
                    info.AppendLine($"현재 RunStep: {PUB.sm.RunStep}");
                    info.AppendLine($"Pause 상태: {PUB.sm.bPause}");
                    info.AppendLine($"WaitFirstRun: {PUB.sm.WaitFirstRun}");
                    
                    // 스레드 정보
                    var smThread = GetStateMachineThread();
                    if (smThread != null)
                    {
                        info.AppendLine();
                        info.AppendLine($"스레드 이름: {smThread.Name ?? "N/A"}");
                        info.AppendLine($"스레드 ID: {smThread.ManagedThreadId}");
                        info.AppendLine($"스레드 상태: {smThread.ThreadState}");
                        info.AppendLine($"IsAlive: {smThread.IsAlive}");
                        info.AppendLine($"IsBackground: {smThread.IsBackground}");
                    }
                    else
                    {
                        info.AppendLine();
                        info.AppendLine("경고: 상태머신 스레드를 찾을 수 없음!");
                    }
                }
                else
                {
                    info.AppendLine("오류: 상태머신 객체가 NULL입니다!");
                }
                
                info.AppendLine();
                info.AppendLine("=== 변수 상태 ===");
                info.AppendLine($"FLAG_AUTORUN: {VAR.BOOL[eVarBool.FLAG_AUTORUN]}");
                info.AppendLine($"EMERGENCY: {VAR.BOOL[eVarBool.EMERGENCY]}");
                info.AppendLine($"FLAG_SYNC: {VAR.BOOL[eVarBool.FLAG_SYNC]}");
                
                info.AppendLine();
                info.AppendLine("=== 하드웨어 연결 상태 ===");
                info.AppendLine($"AGV: {(PUB.AGV?.IsOpen ?? false)} - {PUB.setting.Port_AGV}");
                info.AppendLine($"XBE: {(PUB.XBE?.IsOpen ?? false)} - {PUB.setting.Port_XBE}");
                info.AppendLine($"BMS: {(PUB.BMS?.IsOpen ?? false)} - {PUB.setting.Port_BAT}");
                
                info.AppendLine();
                info.AppendLine("=== 관리되는 스레드 목록 ===");
                var currentProcess = Process.GetCurrentProcess();
                info.AppendLine($"총 프로세스 스레드 수: {currentProcess.Threads.Count}");
                
                // 모든 관리되는 스레드 정보 출력
                foreach (ProcessThread thread in currentProcess.Threads)
                {
                    var state = thread.ThreadState;
                    var waitReason = thread.ThreadState == System.Diagnostics.ThreadState.Wait ? 
                        $", WaitReason: {thread.WaitReason}" : "";
                    info.AppendLine($"  Thread {thread.Id}: State={state}, Priority={thread.PriorityLevel}{waitReason}");
                }
                
                txtDebugInfo.Text = info.ToString();
            }
            catch (Exception ex)
            {
                txtDebugInfo.Text = $"오류 발생: {ex.Message}\r\n{ex.StackTrace}";
            }
        }

        private Thread GetStateMachineThread()
        {
            try
            {
                // Reflection을 사용하여 StateMachine의 private worker 필드 접근
                var smType = PUB.sm.GetType();
                var threadField = smType.GetField("worker", 
                    System.Reflection.BindingFlags.NonPublic | 
                    System.Reflection.BindingFlags.Instance);
                    
                if (threadField != null)
                {
                    return threadField.GetValue(PUB.sm) as Thread;
                }
            }
            catch { }
            return null;
        }

        private void BtnForceRestart_Click(object sender, EventArgs e)
        {
            var result = MessageBox.Show(
                "상태머신을 강제로 재시작하시겠습니까?\n이 작업은 위험할 수 있습니다.",
                "경고",
                MessageBoxButtons.YesNo,
                MessageBoxIcon.Warning);
                
            if (result == DialogResult.Yes)
            {
                try
                {
                    PUB.log.Add("StateMachine", "사용자가 강제 재시작 요청");
                    PUB.sm.Stop();
                    System.Threading.Thread.Sleep(1000);
                    PUB.sm.Start();
                    PUB.log.Add("StateMachine", "강제 재시작 완료");
                    MessageBox.Show("상태머신이 재시작되었습니다.", "완료");
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"재시작 실패: {ex.Message}", "오류");
                    PUB.log.AddE($"상태머신 재시작 실패: {ex.Message}");
                }
            }
        }

        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            updateTimer?.Stop();
            updateTimer?.Dispose();
            base.OnFormClosing(e);
        }
    }
}
