using System.Collections.Generic;
using UnityEngine;

public class RoomRouteManager : MonoBehaviour
{
    public static RoomRouteManager Instance;

    [System.Serializable]
    public class RoomData
    {
        [Header("방 번호 입력")]
        public int roomNumber;

        [Header("이 방에 해당하는 Scene 이름 입력")]
        public string sceneName;
    }

    [Header("전체 방 정보 입력")]
    [SerializeField] private List<RoomData> rooms = new List<RoomData>();

    [Header("시작 방 번호 입력")]
    [SerializeField] private int startRoomNumber;

    [Header("랜덤 선택지 개수")]
    [SerializeField] private int randomChoiceCount = 2;

    [Header("모든 방 방문 후 이동할 마지막 Scene 이름")]
    [SerializeField] private string finalSceneName;

    private int _currentRoomNumber;
    private readonly HashSet<int> _visitedRooms = new HashSet<int>();

    public int CurrentRoomNumber => _currentRoomNumber;
    public int VisitedRoomCount => _visitedRooms.Count;
    public int TotalRoomCount => rooms.Count;

    private void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(gameObject);

            _currentRoomNumber = startRoomNumber;

            if (startRoomNumber != 0)
            {
                _visitedRooms.Add(startRoomNumber);
            }
        }
        else
        {
            Destroy(gameObject);
        }
    }

    // 방문하지 않은 방 전체 반환
    public List<RoomData> GetUnvisitedRooms()
    {
        List<RoomData> result = new List<RoomData>();

        foreach (RoomData room in rooms)
        {
            if (!_visitedRooms.Contains(room.roomNumber))
            {
                result.Add(room);
            }
        }

        return result;
    }

    // 대화 선택지에 보여줄 랜덤 방 목록 반환
    public List<RoomData> GetRandomNextRooms()
    {
        List<RoomData> unvisitedRooms = GetUnvisitedRooms();
        List<RoomData> randomRooms = new List<RoomData>();

        int count = Mathf.Min(randomChoiceCount, unvisitedRooms.Count);

        for (int i = 0; i < count; i++)
        {
            int randomIndex = Random.Range(0, unvisitedRooms.Count);

            randomRooms.Add(unvisitedRooms[randomIndex]);
            unvisitedRooms.RemoveAt(randomIndex);
        }

        return randomRooms;
    }

    // 버튼이나 대화 선택지에서 호출
    public void MoveToRoom(int roomNumber)
    {
        if (SceneLoadManager.Instance == null)
        {
            Debug.LogError("SceneLoadManager가 씬에 없습니다.");
            return;
        }

        if (SceneLoadManager.Instance.IsChangingScene)
        {
            Debug.Log("이미 씬 이동 중입니다.");
            return;
        }

        RoomData targetRoom = GetRoomData(roomNumber);

        if (targetRoom == null)
        {
            Debug.LogWarning($"방 정보를 찾을 수 없습니다. 방 번호: {roomNumber}");
            return;
        }

        if (_visitedRooms.Contains(roomNumber))
        {
            Debug.Log($"이미 방문한 방입니다. 방 번호: {roomNumber}");
            return;
        }

        if (string.IsNullOrEmpty(targetRoom.sceneName))
        {
            Debug.LogWarning($"방 {roomNumber}의 Scene 이름이 비어있습니다.");
            return;
        }

        _currentRoomNumber = roomNumber;
        _visitedRooms.Add(roomNumber);

        SceneLoadManager.Instance.RequestSceneChange(targetRoom.sceneName);
    }

    // 랜덤 방 하나로 바로 이동하고 싶을 때 사용
    public void MoveToRandomRoom()
    {
        List<RoomData> unvisitedRooms = GetUnvisitedRooms();

        if (unvisitedRooms.Count <= 0)
        {
            Debug.Log("방문하지 않은 방이 없습니다.");

            if (IsAllRoomsVisited())
            {
                MoveToFinalScene();
            }

            return;
        }

        int randomIndex = Random.Range(0, unvisitedRooms.Count);
        RoomData randomRoom = unvisitedRooms[randomIndex];

        MoveToRoom(randomRoom.roomNumber);
    }

    public bool IsAllRoomsVisited()
    {
        return rooms.Count > 0 && _visitedRooms.Count >= rooms.Count;
    }

    public void MoveToFinalScene()
    {
        if (!IsAllRoomsVisited())
        {
            Debug.Log("아직 모든 방을 방문하지 않았습니다.");
            return;
        }

        if (SceneLoadManager.Instance == null)
        {
            Debug.LogError("SceneLoadManager가 씬에 없습니다.");
            return;
        }

        if (SceneLoadManager.Instance.IsChangingScene)
        {
            Debug.Log("이미 씬 이동 중입니다.");
            return;
        }

        if (string.IsNullOrEmpty(finalSceneName))
        {
            Debug.LogWarning("마지막 Scene 이름이 비어있습니다.");
            return;
        }

        SceneLoadManager.Instance.RequestSceneChange(finalSceneName);
    }

    public bool IsVisitedRoom(int roomNumber)
    {
        return _visitedRooms.Contains(roomNumber);
    }

    public void ResetVisitedRooms()
    {
        _visitedRooms.Clear();

        _currentRoomNumber = startRoomNumber;

        if (startRoomNumber != 0)
        {
            _visitedRooms.Add(startRoomNumber);
        }
    }

    private RoomData GetRoomData(int roomNumber)
    {
        foreach (RoomData room in rooms)
        {
            if (room.roomNumber == roomNumber)
            {
                return room;
            }
        }

        return null;
    }
}