using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using Photon.Pun;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Hashtable = ExitGames.Client.Photon.Hashtable;
using Random = UnityEngine.Random;

public class GameManager : MonoBehaviourPunCallbacks
{
    public TextMeshProUGUI text;
    public GameObject readyPanel;
    public GameObject restartButton;
    public GameObject destroyRoomButton;
    public GameObject map;

    private Image _image;
    private float _fillAmount = 1f;

    public static Dictionary<int, Sprite> AvatarCache = new Dictionary<int, Sprite>();

    private void Start()
    {
        if (restartButton != null) restartButton.SetActive(false);
        if (destroyRoomButton != null) destroyRoomButton.SetActive(false); // [추가]
        _image = map.GetComponent<Image>();
        // 씬 시작 시, 모두의 아바타를 다운로드하는 코루틴 시작
        StartCoroutine(DownloadAllAvatarsAndReady());
    }

    private IEnumerator DownloadAllAvatarsAndReady()
    {
        AvatarCache.Clear(); // 게임 시작 전 딕셔너리 초기화

        // 방에 있는 모든 플레이어를 한 명씩 확인
        foreach (var player in PhotonNetwork.PlayerList)
        {
            // 그 플레이어의 정보에 "AvatarUrl"이 있는지 확인
            if (player.CustomProperties.TryGetValue("AvatarUrl", out object urlObject))
            {
                string url = (string)urlObject;

                // 해당 URL에서 이미지를 다운로드 (비동기 대기)
                yield return StartCoroutine(DownloadImage(player.ActorNumber, url));
            }
        }

        // --- 다운로드가 모두 끝났음! ---

        // 서버에 "나 이미지 다운로드 다 했고 준비 끝났어!" 라고 알림
        Hashtable props = new Hashtable() { { "IsLoaded", true } };
        PhotonNetwork.LocalPlayer.SetCustomProperties(props);
    }

    private IEnumerator DownloadImage(int actorNumber, string url)
    {
        // 빈 URL이면 무시
        if (string.IsNullOrEmpty(url)) yield break;

        using UnityWebRequest request = UnityWebRequestTexture.GetTexture(url);
        yield return request.SendWebRequest(); // 다운로드 끝날 때까지 대기

        if (request.result != UnityWebRequest.Result.Success)
        {
            Debug.LogError($"[다운로드 실패] 유저 번호: {actorNumber}, 에러: {request.error}\nwhile Downloading {url}");
        }
        else
        {
            // 성공적으로 받아왔다면 Texture를 추출
            Texture2D texture = DownloadHandlerTexture.GetContent(request);

            // UI(Image 컴포넌트)에 넣기 편하게 Sprite 형식으로 변환
            Sprite avatarSprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height),
                new Vector2(0.5f, 0.5f));

            // 딕셔너리에 저장! (나중에 꺼내 쓸 목적)
            AvatarCache[actorNumber] = avatarSprite;

            Debug.Log($"[다운로드 성공] 유저 번호 {actorNumber}의 아바타 저장 완료!");
        }
    }

    // 누군가의 상태가 바뀔 때마다 실행됨
    public override void OnPlayerPropertiesUpdate(Photon.Realtime.Player targetPlayer, Hashtable changedProps)
    {
        // 내가 방장일 때만 모든 사람이 로딩을 마쳤는지 검사합니다.
        if (!PhotonNetwork.IsMasterClient || !changedProps.ContainsKey("IsLoaded")) return;
        if (CheckAllPlayersLoaded())
        {
            // 모두가 로딩을 마쳤다면, 방장이 모든 클라이언트에게 신호를 보냅니다!
            photonView.RPC("RpcStartCountdown", RpcTarget.All);
        }
    }

    private void Update()
    {
        if (!Gazuaa.isGameActive) return;
        _fillAmount -= Time.deltaTime;
        _image.fillAmount = _fillAmount / 15f; // 15초 동안 서서히 줄어들도록 설정
    }

    private bool CheckAllPlayersLoaded()
    {
        // 방에 있는 모든 플레이어의 "IsLoaded"가 true인지 확인
        foreach (var player in PhotonNetwork.PlayerList)
        {
            if (player.CustomProperties.TryGetValue("IsLoaded", out object isLoaded))
            {
                if (!(bool)isLoaded) return false;
            }
            else
            {
                return false; // 아직 로딩 안 된 사람이 있음
            }
        }

        return true; // 전원 로딩 완료!
    }

    // RPC: 방장이 호출하지만, 이 방에 있는 모든 사람의 컴퓨터에서 실행되는 마법의 함수!
    [PunRPC]
    private void RpcStartCountdown()
    {
        // 방장의 신호를 받고 다 같이 동시에 코루틴을 시작합니다.
        StartCoroutine(GameSet());
    }

    private IEnumerator GameSet()
    {
        _fillAmount = 15;
        // 1. 카운트다운
        text.text = "3";
        yield return new WaitForSeconds(1f);
        text.text = "2";
        yield return new WaitForSeconds(1f);
        text.text = "1";
        yield return new WaitForSeconds(1f);
        text.text = "GO!";

        readyPanel.SetActive(false);

        // --- 게임 시작 ---
        Gazuaa.isGameActive = true; // 스페이스바 입력 활성화!
        // 2. 15초 동안 게임 진행 (대기)
        yield return new WaitForSeconds(15f);

        // --- 게임 종료 ---
        Gazuaa.isGameActive = false; // 스페이스바 입력 차단!

        readyPanel.SetActive(true);
        text.text = "STOP!";

        yield return new WaitForSeconds(2f); // 결과 발표 전 약간의 뜸 들이기

        // 3. 방장만 대표로 가챠를 돌려서 결과를 뽑습니다.
        if (PhotonNetwork.IsMasterClient)
        {
            DetermineWinner();
        }
    }

    private void DetermineWinner()
    {
        Dictionary<int, int> finalCounts = new Dictionary<int, int>();
        int totalAvatars = 0;

        // 방에 있는 모든 사람의 최종 아바타 개수를 수집합니다.
        foreach (var player in PhotonNetwork.PlayerList)
        {
            if (player.CustomProperties.TryGetValue("AvatarCount", out object countObj))
            {
                int count = (int)countObj;
                finalCounts[player.ActorNumber] = count;
                totalAvatars += count;
            }
        }

        // 아무도 스페이스바를 누르지 않았다면?
        if (totalAvatars == 0)
        {
            photonView.RPC("RpcShowWinner", RpcTarget.All, -1);
            return;
        }

        // 가챠 뽑기 로직 (1 ~ 총 아바타 개수)
        int randomPick = Random.Range(1, totalAvatars + 1);
        int currentSum = 0;
        int winnerActorNumber = -1;

        foreach (var kvp in finalCounts)
        {
            currentSum += kvp.Value;
            if (randomPick <= currentSum)
            {
                winnerActorNumber = kvp.Key; // 당첨자 식별 번호!
                break;
            }
        }

        // 모두에게 "이 사람이 당첨됐다!" 라고 쏩니다.
        photonView.RPC("RpcShowWinner", RpcTarget.All, winnerActorNumber);
    }

    [PunRPC]
    private void RpcShowWinner(int winnerActorNumber)
    {
        if (winnerActorNumber == -1)
        {
            text.text = "아무도 참여하지 않았습니다.";
            ShowRestartButtonIfMaster(); // 아무도 안 했을 때도 다시하기 버튼 띄우기
            return;
        }

        // 우승자 닉네임 찾기
        string winnerName = "알 수 없음";
        foreach (var player in PhotonNetwork.PlayerList)
        {
            if (player.ActorNumber == winnerActorNumber)
            {
                winnerName = player.NickName;
                break;
            }
        }

        // 텍스트를 바로 바꾸지 않고 "추첨 중"으로 변경! (스포일러 방지)
        text.text = "추첨 중...";

        // Gazuaa 스크립트를 찾아서 룰렛 연출 시작 (이름도 같이 넘겨줍니다)
        FindObjectOfType<Gazuaa>().HighlightWinner(winnerActorNumber, winnerName);
    }

    // Gazuaa.cs의 코루틴이 끝난 후(룰렛이 멈춘 후) 호출할 함수
    public void ShowRestartButtonIfMaster()
    {
        // 내가 방장일 때만 버튼을 활성화합니다.
        if (PhotonNetwork.IsMasterClient )
        {
            if (restartButton != null) restartButton.SetActive(true);
            if (destroyRoomButton != null) destroyRoomButton.SetActive(true); // [추가]
        }
        
        
    } // '다시 하기' 버튼의 OnClick() 이벤트에 연결할 함수

    public void ClickRestart()
    {
        // 방장이 씬을 다시 로드합니다. (모두가 자동으로 따라옵니다!)
        // "GameScene" 부분은 실제 사용 중인 게임 씬의 이름으로 적어주세요.
        PhotonNetwork.LoadLevel("GameScene");
    }
    
    // [추가] '방 삭제' 버튼의 OnClick() 이벤트에 연결할 함수
    public void ClickDestroyRoom()
    {
        // 방장이 모든 클라이언트에게 "방에서 나가!" 라고 명령을 내립니다.
        photonView.RPC("RpcLeaveRoom", RpcTarget.All);
    }
    
    // [추가] 모두의 컴퓨터에서 실행될 방 나가기 함수
    [PunRPC]
    private void RpcLeaveRoom()
    {
        // 포톤 서버에 이 방에서 나가겠다고 요청합니다.
        PhotonNetwork.LeaveRoom();
    }

    // [추가] 방에서 완전히 빠져나왔을 때 포톤이 자동으로 호출해 주는 함수
    public override void OnLeftRoom()
    {
        // 방에서 성공적으로 나갔다면, 최초 로비 화면으로 씬을 이동시킵니다.
        // "LobbyScene" 부분을 실제 로비 씬의 이름으로 꼭 바꿔주세요!!!
        SceneManager.LoadScene("LobbyScene"); 
    }
}