using System;
using System.Collections.Generic;

namespace Project.StateMachine
{
    public class AGVStateManager
    {
        public enum AGVState
        {
            Idle,
            Moving,
            Loading,
            Unloading,
            Error
        }

        public enum AGVCommand
        {
            MoveToTops1,
            MoveToSstron1,
            MoveToSstron2,
            PickupCart,
            DropoffCart,
            EmergencyStop
        }

        private AGVState currentState;
        private static AGVStateManager instance;
        private AGVPosition positionManager;

        private AGVStateManager()
        {
            currentState = AGVState.Idle;
            positionManager = AGVPosition.Instance;
        }

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

        public AGVState CurrentState
        {
            get { return currentState; }
        }

        public bool ProcessCommand(AGVCommand command)
        {
            switch (command)
            {
                case AGVCommand.MoveToTops1:
                    return HandleMoveCommand(100); // Tops 1 RFID
                case AGVCommand.MoveToSstron1:
                    return HandleMoveCommand(200); // Sstron 1 RFID
                case AGVCommand.MoveToSstron2:
                    return HandleMoveCommand(300); // Sstron 2 RFID
                case AGVCommand.PickupCart:
                    return HandlePickupCommand();
                case AGVCommand.DropoffCart:
                    return HandleDropoffCommand();
                case AGVCommand.EmergencyStop:
                    return HandleEmergencyStop();
                default:
                    return false;
            }
        }

        private bool HandleMoveCommand(int targetRfid)
        {
            if (currentState != AGVState.Idle && currentState != AGVState.Moving)
            {
                return false;
            }

            // 현재 위치에서 목표 위치까지의 경로를 찾음
            var currentRfid = GetCurrentRfid(); // 실제 구현에서는 현재 RFID 값을 가져와야 함
            var path = positionManager.FindPath(currentRfid, targetRfid);

            if (path == null)
            {
                return false;
            }

            currentState = AGVState.Moving;
            // 경로를 따라 이동하는 로직 구현
            return true;
        }

        private bool HandlePickupCommand()
        {
            if (currentState != AGVState.Moving)
            {
                return false;
            }

            // 현재 위치가 Tops 1인지 확인
            var currentRfid = GetCurrentRfid();
            var position = positionManager.GetPosition(currentRfid);
            
            if (position == null || position.Type != AGVPosition.PositionType.Tops1)
            {
                return false;
            }

            currentState = AGVState.Loading;
            // 카트 적재 로직 구현
            return true;
        }

        private bool HandleDropoffCommand()
        {
            if (currentState != AGVState.Moving)
            {
                return false;
            }

            // 현재 위치가 Sstron 1 또는 Sstron 2인지 확인
            var currentRfid = GetCurrentRfid();
            var position = positionManager.GetPosition(currentRfid);
            
            if (position == null || 
                (position.Type != AGVPosition.PositionType.Sstron1 && 
                 position.Type != AGVPosition.PositionType.Sstron2))
            {
                return false;
            }

            currentState = AGVState.Unloading;
            // 카트 하역 로직 구현
            return true;
        }

        private bool HandleEmergencyStop()
        {
            currentState = AGVState.Error;
            // 비상 정지 로직 구현
            return true;
        }

        private int GetCurrentRfid()
        {
            // 실제 구현에서는 AGV의 현재 RFID 값을 반환해야 함
            // 예시로 100(Tops 1)을 반환
            return 100;
        }

        public void UpdateState(AGVState newState)
        {
            currentState = newState;
        }
    }
} 