﻿using System;
using BeardedManStudios.Network;
using UnityEngine;

namespace Dissonance.Integrations.ForgeNetworking
{
    public class ForgePlayer
         : NetworkedMonoBehavior, IDissonancePlayer
    {
        private DissonanceComms _comms;

        public bool IsTracking { get; private set; }

        public string PlayerId { get; private set; }

        public Vector3 Position
        {
            get { return transform.position; }
        }

        public Quaternion Rotation
        {
            get { return transform.rotation; }
        }

        public NetworkPlayerType Type
        {
            get
            {
                return IsOwner ? NetworkPlayerType.Local : NetworkPlayerType.Remote;
            }
        }

        public void Awake()
        {
            PlayerId = "";
            AddNetworkVariable(() => PlayerId, n => SetPlayerName((string)n));
        }

        public void OnEnable()
        {
            _comms = FindObjectOfType<DissonanceComms>();
            StartTracking();
        }

        public void OnDisable()
        {
            StopTracking();
        }

        protected override void OnDestroy()
        {
            base.OnDestroy();

            if (_comms != null)
                _comms.LocalPlayerNameChanged -= SetPlayerName;
        }

        protected override void NetworkStart()
        {
            base.NetworkStart();

            var comms = FindObjectOfType<DissonanceComms>();
            if (comms == null)
                throw new Exception("Cannot find Dissonance Voice Comms in the scene.");

            SetPlayerName(comms.LocalPlayerName);
            comms.LocalPlayerNameChanged += SetPlayerName;
        }

        private void SetPlayerName(string playerName)
        {
            //We need to stop and restart tracking to handle the name change
            if (IsTracking)
                StopTracking();

            //Perform the actual work
            PlayerId = playerName;
            StartTracking();
        }

        private void StartTracking()
        {
            if (string.IsNullOrEmpty(PlayerId) && _comms != null)
            {
                _comms.TrackPlayerPosition(this);
                IsTracking = true;
            }
        }

        private void StopTracking()
        {
            if (_comms != null)
            {
                _comms.StopTracking(this);
                IsTracking = false;
            }
        }
    }
}
