using System;
using System.Collections.Generic;

namespace Project.StateMachine
{
    public class AGVPosition
    {
        public enum PositionType
        {
            None,
            Tops1,
            Sstron1,
            Sstron2,
            Path
        }

        public class Position
        {
            public int RFID { get; set; }
            public PositionType Type { get; set; }
            public string Name { get; set; }
            public string Direction { get; set; }
            public List<int> ConnectedPositions { get; set; }

            public Position(int rfid, PositionType type, string name, string direction)
            {
                RFID = rfid;
                Type = type;
                Name = name;
                Direction = direction;
                ConnectedPositions = new List<int>();
            }
        }

        private Dictionary<int, Position> positionMap;
        private static AGVPosition instance;

        private AGVPosition()
        {
            positionMap = new Dictionary<int, Position>();
            InitializePositions();
        }

        public static AGVPosition Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new AGVPosition();
                }
                return instance;
            }
        }

        private void InitializePositions()
        {
            // Tops 1 관련 위치
            AddPosition(100, PositionType.Tops1, "Tops 1", "0");
            AddPosition(101, PositionType.Path, "Tops1-Sstron1 Path 1", "0");
            AddPosition(102, PositionType.Path, "Tops1-Sstron1 Path 2", "0");

            // Sstron 1 관련 위치
            AddPosition(200, PositionType.Sstron1, "Sstron 1", "0");
            AddPosition(201, PositionType.Path, "Sstron1-Sstron2 Path 1", "0");
            AddPosition(202, PositionType.Path, "Sstron1-Sstron2 Path 2", "0");

            // Sstron 2 관련 위치
            AddPosition(300, PositionType.Sstron2, "Sstron 2", "0");

            // 경로 연결 설정
            ConnectPositions(100, 101);
            ConnectPositions(101, 102);
            ConnectPositions(102, 200);
            ConnectPositions(200, 201);
            ConnectPositions(201, 202);
            ConnectPositions(202, 300);
        }

        private void AddPosition(int rfid, PositionType type, string name, string direction)
        {
            positionMap[rfid] = new Position(rfid, type, name, direction);
        }

        private void ConnectPositions(int pos1, int pos2)
        {
            if (positionMap.ContainsKey(pos1) && positionMap.ContainsKey(pos2))
            {
                positionMap[pos1].ConnectedPositions.Add(pos2);
                positionMap[pos2].ConnectedPositions.Add(pos1);
            }
        }

        public Position GetPosition(int rfid)
        {
            if (positionMap.ContainsKey(rfid))
            {
                return positionMap[rfid];
            }
            return null;
        }

        public List<int> FindPath(int startRfid, int endRfid)
        {
            if (!positionMap.ContainsKey(startRfid) || !positionMap.ContainsKey(endRfid))
            {
                return null;
            }

            var visited = new HashSet<int>();
            var path = new List<int>();
            if (FindPathDFS(startRfid, endRfid, visited, path))
            {
                return path;
            }
            return null;
        }

        private bool FindPathDFS(int current, int end, HashSet<int> visited, List<int> path)
        {
            if (current == end)
            {
                path.Add(current);
                return true;
            }

            visited.Add(current);
            path.Add(current);

            foreach (var next in positionMap[current].ConnectedPositions)
            {
                if (!visited.Contains(next))
                {
                    if (FindPathDFS(next, end, visited, path))
                    {
                        return true;
                    }
                }
            }

            path.RemoveAt(path.Count - 1);
            return false;
        }
    }
} 