using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Project.StateMachine;
using COMM;
using AR;
using AGVNavigationCore.Models;

namespace Project.ViewForm
{
    public partial class fAuto : Form
    {

        public fAuto()
        {
            InitializeComponent();
            this.FormClosed += FAuto_FormClosed;
            PUB.sm.StepChanged += Sm_StepChanged;
            this.ctlAuto1.ButtonClick += CtlAuto1_ButtonClick;
            if (PUB.sm.Step == eSMStep.INIT || PUB.sm.Step == eSMStep.SYNC)
                this.ctlAuto1.Scean = CtlAuto.eScean.Progress;
            else
                this.ctlAuto1.Scean = CtlAuto.eScean.Normal;

            InitializeMapCanvas();

            //PUB.mapctl = new AGVControl.MapControl();
            //PUB.mapctl.Dock = DockStyle.Fill;
            //PUB.mapctl.Visible = true;
            //PUB.mapctl.Font = this.panel1.Font;
            //PUB.mapctl.BackColor = Color.FromArgb(32, 32, 32);
            //this.panel1.Controls.Add(PUB.mapctl);
        }

        private void InitializeMapCanvas()
        {
            PUB._mapCanvas = new AGVNavigationCore.Controls.UnifiedAGVCanvas();
            PUB._mapCanvas.Dock = DockStyle.Fill;
            PUB._mapCanvas.ShowGrid = false;
            PUB._mapCanvas.BackColor = Color.FromArgb(32, 32, 32);
            PUB._mapCanvas.ForeColor = Color.White;
            // RfidMappings 제거 - MapNode에 통합됨

            // 이벤트 연결
            //PUB._mapCanvas.NodeAdded += OnNodeAdded;
            //PUB._mapCanvas.NodeSelected += OnNodeSelected;
            //PUB._mapCanvas.NodeMoved += OnNodeMoved;
            //PUB._mapCanvas.NodeDeleted += OnNodeDeleted;
            //PUB._mapCanvas.ConnectionDeleted += OnConnectionDeleted;
            //PUB._mapCanvas.ImageNodeDoubleClicked += OnImageNodeDoubleClicked;
            //PUB._mapCanvas.MapChanged += OnMapChanged;

            // 스플리터 패널에 맵 캔버스 추가
            panel1.Controls.Add(PUB._mapCanvas);

            // 툴바 버튼 이벤트 연결
            //WireToolbarButtonEvents();



        }


        private void fAuto_Load(object sender, EventArgs e)
        {
            ctlAuto1.dev_agv = PUB.AGV;
            //     ctlAuto1.dev_plc = PUB.PLC;
            ctlAuto1.dev_bms = PUB.BMS;
            ctlAuto1.dev_xbe = PUB.XBE;

            PUB.AGV.DataReceive += AGV_DataReceive;


            //auto load 
            var mapPath = new System.IO.DirectoryInfo("route");
            if (mapPath.Exists == false) mapPath.Create();


            //맵파일로딩
            if (PUB.setting.LastMapFile.isEmpty()) PUB.setting.LastMapFile = System.IO.Path.Combine(mapPath.FullName, "default.agvmap");
            System.IO.FileInfo filePath = new System.IO.FileInfo(PUB.setting.LastMapFile);
            if (filePath.Exists == false) filePath = new System.IO.FileInfo(System.IO.Path.Combine(mapPath.FullName,"default.agvmap"));
            if(filePath.Exists==false)  //그래도없다면 맵폴더에서 파일을 찾아본다.
            {
                var files = mapPath.GetFiles("*.agvmap");
                if (files.Any()) filePath = files[0];
            }

            if (filePath.Exists)
            {
                var result = MapLoader.LoadMapFromFile(filePath.FullName);

                if (result.Success)
                {
                    if (PUB._mapNodes == null) PUB._mapNodes = new List<MapNode>();
                    else PUB._mapNodes.Clear();
                    PUB._mapNodes.AddRange(result.Nodes);

                    // 맵 캔버스에 데이터 설정
                    PUB._mapCanvas.Nodes = PUB._mapNodes;
                    PUB._mapCanvas.MapFileName = filePath.FullName;
                    
                    // 🔥 맵 설정 적용 (배경색, 그리드 표시)
                    if (result.Settings != null)
                    {
                        PUB._mapCanvas.BackColor = System.Drawing.Color.FromArgb(result.Settings.BackgroundColorArgb);
                        PUB._mapCanvas.ShowGrid = result.Settings.ShowGrid;
                    }

                    // 🔥 가상 AGV 초기화 (첫 노드 위치에 생성)
                    if (PUB._virtualAGV == null && PUB._mapNodes.Count > 0)
                    {
                        var startNode = PUB._mapNodes.FirstOrDefault(n => n.IsNavigationNode());
                        if (startNode != null)
                        {
                            PUB._virtualAGV = new VirtualAGV(PUB.setting.MCID, startNode.Position, AgvDirection.Forward);
                            PUB._virtualAGV.SetPosition(startNode, AgvDirection.Forward);

                            // 캔버스에 AGV 리스트 설정
                            var agvList = new System.Collections.Generic.List<AGVNavigationCore.Controls.IAGV> { PUB._virtualAGV };
                            PUB._mapCanvas.AGVList = agvList;

                            PUB.log.Add($"가상 AGV 생성: {startNode.NodeId} 위치");
                        }
                    }
                    else if (PUB._virtualAGV != null)
                    {
                        // 기존 AGV가 있으면 캔버스에 다시 연결
                        var agvList = new System.Collections.Generic.List<AGVNavigationCore.Controls.IAGV> { PUB._virtualAGV };
                        PUB._mapCanvas.AGVList = agvList;
                    }

                    // 맵 로드 후 자동으로 맵에 맞춤
                    PUB._mapCanvas.FitToNodes();

                    PUB.log.Add($"맵 파일 로드 완료: {filePath.Name}, 노드 수: {result.Nodes.Count}");
                }
                else
                {
                    PUB.log.Add($"맵 파일 로딩 실패: {result.ErrorMessage}");
                    MessageBox.Show($"맵 파일 로딩 실패: {result.ErrorMessage}", "오류",
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                PUB.log.Add($"맵 파일을 찾을 수 없습니다: {filePath.FullName}");
            }

            //var fn = string.Empty;
            //if (files.Any() == false)
            //{
            //    fn = AR.UTIL.MakePath("sample.route");
            //}
            //else if (files.Count() == 1)
            //{
            //    fn = files.First().FullName;
            //}
            //if (fn.isEmpty() == false)
            //{
            //    var fi = new System.IO.FileInfo(AR.UTIL.CurrentPath + "\\sample.route");
            //    if (fi.Exists)
            //    {
            //        PUB.log.Add($"autoload : {fi.FullName}");
            //        var rlt = PUB.mapctl.LoadFromFile(fi.FullName, out string errmsg);
            //        if (rlt == false) AR.UTIL.MsgE(errmsg);
            //    }
            //}

            this.timer1.Start();
        }
        private void AGV_DataReceive(object sender, arDev.Narumi.DataEventArgs e)
        {
            switch (e.DataType)
            {
                case arDev.Narumi.DataType.TAG:
                    //_AGV 파일에서 위치조정을 함
                    //var tagno = PUB.AGV.data.TagNo;                    
                    //PUB.mapctl.SetCurrentPosition(tagno);
                    break;
            }
        }

        private void CtlAuto1_ButtonClick(CtlAuto.UIButton idx)
        {
            if (idx.cmd.Equals("EMG"))
            {
                PUB.log.Add("ui reset click");
                PUB.AGV.AGVErrorReset();
            }
        }

        private void Sm_StepChanged(object sender, StateMachine.StateMachine.StepChangeEventArgs e)
        {
            if (e.New == eSMStep.INIT || e.New == eSMStep.SYNC)
                this.ctlAuto1.Scean = CtlAuto.eScean.Progress;
            else
                this.ctlAuto1.Scean = CtlAuto.eScean.Normal;
        }

        private void FAuto_FormClosed(object sender, FormClosedEventArgs e)
        {
            timer1.Stop();
            PUB.sm.StepChanged -= Sm_StepChanged;
            this.ctlAuto1.ButtonClick -= CtlAuto1_ButtonClick;
            PUB.AGV.DataReceive -= AGV_DataReceive;
        }

        bool tmrun = false;

        private void fAuto_VisibleChanged(object sender, EventArgs e)
        {
            this.timer1.Enabled = this.Visible;
            if (timer1.Enabled) timer1.Start();
            else timer1.Stop();
        }

        private void timer1_Tick_1(object sender, EventArgs e)
        {
            //if (this.Visible == false) return;
            //if (tmrun == true) return;
            //tmrun = true;

            //this.ctlAuto1.OnUpdateMode = true;

            //if (this.ctlAuto1.Scean == CtlAuto.eScean.Progress)
            //{
            //    ctlAuto1.ProgressVal = PUB.Result.SMSG_ProgressValue;
            //    ctlAuto1.ProgressMax = PUB.Result.SMSG_ProgressMax;
            //    ctlAuto1.StatusMessage = VAR.STR?.Get(eVarString.StatusMessage) ?? string.Empty;
            //}
            //this.ctlAuto1.StopMessage = string.Empty;

            //if (PUB.sm.Step == StateMachine.eSMStep.RUN)
            //{
            //    this.ctlAuto1.runStep = PUB.sm.RunStep;
            //}
            //else
            //{
            //    this.ctlAuto1.runStep = ERunStep.READY;
            //}
            //this.ctlAuto1.OnUpdateMode = false;
            //this.ctlAuto1.Invalidate();

            //PUB.mapctl.PredictNextAction();

            //tmrun = false;
        }
    }
}
