﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;
using TMPro;

public class Launcher : MonoBehaviourPunCallbacks {

    public CloudRegion cloudRegion;

    string _gameVersion = "1";

	public GameObject testPlayer;
	public bool testPlay = false;

    public int maxPlayersPerRoom = 9;

    public TMP_InputField classIDField;
    public TMP_Text joinErrorMessage;

    public LobbyPanelHandler handler;
    public LobbyUI lobbyUI;

    public float matchStartTime = -1f;

    public GameGenerator gameGenerator;

    public enum CloudRegion {
        USEast, USWest, Europe, CanadaEast
    }


    public Dictionary<CloudRegion, string> cloudRegionTokens = new Dictionary<CloudRegion, string>() {
        { CloudRegion.USEast, "us" },
        { CloudRegion.USWest, "usw" },
        { CloudRegion.Europe, "eu" },
        { CloudRegion.CanadaEast, "cae" },
    };

    void Awake() {
        PhotonNetwork.AutomaticallySyncScene = true;
        LootRandomizer.chestIndex = 0;

        string token = "us";
        if(cloudRegionTokens.TryGetValue(cloudRegion, out token))
            ((ServerSettings)Resources.Load("PhotonServerSettings", typeof(ServerSettings))).AppSettings.FixedRegion = token;

    }

    public void Connect() {
        if (PhotonNetwork.IsConnected) {
            PhotonNetwork.JoinRandomRoom();
        }
        else {
            ((ServerSettings)Resources.Load("PhotonServerSettings", typeof(ServerSettings))).AppSettings.AppVersion = _gameVersion;
            //PhotonNetwork.GameVersion = _gameVersion;
            PhotonNetwork.ConnectUsingSettings();
        }
    }

    public override void OnConnectedToMaster() {
        Debug.Log("OnConnectedToMaster() was called by PUN");
        PhotonNetwork.JoinRandomRoom();
    }


    public override void OnDisconnected(DisconnectCause cause) {
        Debug.LogWarningFormat("OnDisconnected() was called by PUN with reason {0}", cause);
        ErrorLogger.WriteToLog("OnDisconnected() was called by PUN with reason " + cause);
    }

    public override void OnJoinRandomFailed(short returnCode, string message) {
        Debug.Log("OnJoinRandomFailed() was called by PUN. No random room available, so we create one.\nCalling: PhotonNetwork.CreateRoom");
        ErrorLogger.WriteToLog("OnJoinRandomFailed() was called by PUN. No random room available, so we create one.\nCalling: PhotonNetwork.CreateRoom");
        // #Critical: we failed to join a random room, maybe none exists or they are all full. No worries, we create a new room.
        PhotonNetwork.CreateRoom(null, new RoomOptions { MaxPlayers = (byte)maxPlayersPerRoom });
    }

    public override void OnJoinedRoom() {
        Debug.Log("Region: " + PhotonNetwork.CloudRegion);
        Debug.Log("OnJoinedRoom() called by PUN. Now this client is in a room.");
		if (testPlay && testPlayer != null) {
			GameObject myPlayer = GameObject.Instantiate (testPlayer, new Vector3 (0, 200, 0), Quaternion.identity);
		} else {
            if (PhotonNetwork.IsMasterClient) {
                int randomSeed = gameGenerator.GenerateSeed();
                gameGenerator.SendRandomSeed(randomSeed);
            }
			PhotonNetwork.Instantiate ("player", new Vector3(0, 200, 0), Quaternion.identity);
            PhotonNetwork.SendRate = 7;
        }
    }

    public void Submit() {
		_gameVersion = classIDField.text.ToUpper();
		print (_gameVersion);
        if(_gameVersion.Length < 7) {
            joinErrorMessage.gameObject.SetActive(true);
            return;
        }
        joinErrorMessage.gameObject.SetActive(false);
        ((ServerSettings)Resources.Load("PhotonServerSettings", typeof(ServerSettings))).AppSettings.AppVersion = _gameVersion;
        //PhotonNetwork.GameVersion = _gameVersion;
        Connect();
        handler.SetInLobbyPanelActive();
    }

    public float GetMatchStartTime() {
        return matchStartTime;
    }

    public void StartMatch() {
		if (PhotonNetwork.IsMasterClient) {
			PhotonNetwork.LoadLevel ("GameIsland");
		}
    }

    public void ResetMatchStartTime() {
        matchStartTime = -1f;
        PhotonDebugger.IncrementNumberOfMessages("match start time");
        photonView.RPC("SetMatchStartTime", RpcTarget.OthersBuffered, -1f);
    }

    [PunRPC]
    public void SetMatchStartTime(float startTime) {
        LootRandomizer.chestIndex = 0; // just reset the chest index again to make it a little easier to debug 
        matchStartTime = startTime;
        if (startTime == -1f)
            lobbyUI.cancelCountdown = true;
        else if(PhotonNetwork.Time < startTime)
            StartCoroutine(lobbyUI.CountdownToStart());
    }
}
