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

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

        private bool _isTracking;
        public bool IsTracking
        {
            get { return _isTracking; }
        }

        private string _playerId;
        public string PlayerId
        {
            get { return _playerId; }
        }

        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;
            }
        }
    }
}
