using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Resources;
using System.Threading;
using AR;
using System.Security.Principal;
using System.Diagnostics;

namespace Project
{
    static class Program
    {
        /// <summary>
        /// 해당 응용 프로그램의 주 진입점입니다.
        /// </summary>
        [STAThread]
        static void Main()
        {


            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            if (CheckSingleInstance() == false) return;
            Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
            Application.Run(new FMain());
        }

        static bool IsAdmin()
        {
            var identy = WindowsIdentity.GetCurrent();
            if (identy != null)
            {
                var princ = new WindowsPrincipal(identy);
                return princ.IsInRole(WindowsBuiltInRole.Administrator);
            }
            return false;
        }

        /// <summary>
        /// 중복실행 방지 체크
        /// </summary>
        /// <returns>단일 인스턴스인 경우 true, 중복실행인 경우 false</returns>
        static bool CheckSingleInstance()
        {
            string processName = Process.GetCurrentProcess().ProcessName;
            Process[] processes = Process.GetProcessesByName(processName);

            if (processes.Length > 1)
            {
                // 중복실행 감지
                string message = $"⚠️ {Application.ProductName} 프로그램이 이미 실행 중입니다!\n\n" +
                                "동시에 여러 개의 프로그램을 실행할 수 없습니다.\n\n" +
                                "해결방법을 선택하세요:";

                var result = MessageBox.Show(message + "\n\n예(Y): 기존 프로그램을 종료하고 새로 시작\n아니오(N): 현재 실행을 취소",
                                           "중복실행 감지",
                                           MessageBoxButtons.YesNo,
                                           MessageBoxIcon.Warning);

                if (result == DialogResult.Yes)
                {
                    // 기존 프로세스들을 종료
                    try
                    {
                        int currentProcessId = Process.GetCurrentProcess().Id;
                        foreach (Process process in processes)
                        {
                            if (process.Id != currentProcessId)
                            {
                                process.Kill();
                                process.WaitForExit(3000); // 3초 대기
                            }
                        }

                        // 잠시 대기 후 계속 진행
                        Thread.Sleep(1000);
                        return true;
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show($"기존 프로그램 종료 중 오류가 발생했습니다:\n{ex.Message}\n\n" +
                                       "작업관리자에서 수동으로 종료해주세요.",
                                       "오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return false;
                    }
                }
                else
                {
                    // 현재 실행을 취소
                    return false;
                }
            }

            return true; // 단일 인스턴스
        }


        static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {

            string emsg = "Fatal Error(UHE)\n\n" + e.ExceptionObject.ToString();
            if (PUB.log != null)
            {             
                PUB.log.AddE(emsg);
                PUB.log.Flush();
            }

            
            UTIL.SaveBugReport(emsg);
            Shutdown();

            using (var f = new AR.Dialog.fErrorException(emsg))
                f.ShowDialog();
            Application.ExitThread();
        }

        static void Shutdown()
        {
            PUB.dio.SetOutput(false); //모두끄기
            PUB.sm.SetNewStep(eSMStep.IDLE, true);
            PUB.flag.set(eVarBool.FG_USERSTEP, false, "shutdown");
            PUB.log.Add("Program Close");
            PUB.log.Flush();
            PUB.dio.StopMonitor();
            PUB.mot.StopMonitor();
            PUB.sm.Stop();

        }

        static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
        {

            string emsg = "Fatal Error(ATE)\n\n" + e.Exception.ToString();
            if(PUB.log != null)
            {
                PUB.log.AddE(emsg);
                PUB.log.Flush();
            }
            UTIL.SaveBugReport(emsg);
            Shutdown();
            using (var f = new AR.Dialog.fErrorException(emsg))
                f.ShowDialog();
            Application.ExitThread();
        }
    }
}
