﻿using System;
using DarkRift;
using DarkRift.Client.Unity;
using UnityEngine;

namespace Dissonance.Integrations.DarkRift2.Demo
{
    // ReSharper disable once InconsistentNaming
    public class DR2PlayerController
        : MonoBehaviour
    {
        private Vector3 _lastSentPosition = new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity);
        private float _lastSentRotation = 0;
        private DateTime _lastTimeSent = DateTime.MinValue;

        private void OnEnable()
        {
            //Spawn in a random position
            var rand = new System.Random();
            transform.position = new Vector3(rand.Next(-15, 15), 0, rand.Next(-15, 15));
            _lastSentPosition = new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity);
            _lastTimeSent = DateTime.MinValue;
            _lastSentRotation = 0;

            //Set up tracking for self
            var comms = FindObjectOfType<DissonanceComms>();
            var player = GetComponent<DarkRift2Player>();
            if (comms.LocalPlayerName != null)
                player.SetPlayerId(NetworkPlayerType.Local, comms.LocalPlayerName);
            comms.LocalPlayerNameChanged += n => player.SetPlayerId(NetworkPlayerType.Local, n);;
        }

        private void Update()
        {
            UpdatePlayerInput();
            UpdateNetwork();
        }

        private void UpdatePlayerInput()
        {
            var controller = GetComponent<CharacterController>();
            
            var rotation = Input.GetAxis("Horizontal") * Time.deltaTime * 150.0f;
            var speed = Input.GetAxis("Vertical") * 3.0f;
            
            transform.Rotate(0, rotation, 0);
            var forward = transform.TransformDirection(Vector3.forward);
            controller.SimpleMove(forward * speed);

            if (transform.position.y < -3)
            {
                transform.position = Vector3.zero;
                transform.rotation = Quaternion.identity;
            }
        }

        private void UpdateNetwork()
        {
            //Send an update if it's been a while or the player has moved/turned a long way
            if (DateTime.UtcNow - _lastTimeSent > TimeSpan.FromMilliseconds(250)
                || Vector3.Distance(_lastSentPosition, transform.position) > 0.1f
                || Mathf.DeltaAngle(_lastSentRotation, transform.eulerAngles.y) > 5)
            {
                var client = FindObjectOfType<UnityClient>();
                if (client)
                {
                    using (var writer = DarkRiftWriter.Create())
                    {
                        writer.Write(client.ID);
                        writer.Write(FindObjectOfType<DissonanceComms>().LocalPlayerName);
                        writer.Write(transform.position.x);
                        writer.Write(transform.position.y);
                        writer.Write(transform.position.z);
                        writer.Write(transform.eulerAngles.y);

                        using (var msg = Message.Create(Tags.PositionUpdateTag, writer))
                            client.SendMessage(msg, SendMode.Unreliable);

                        _lastTimeSent = DateTime.UtcNow;
                        _lastSentPosition = transform.position;
                        _lastSentRotation = transform.eulerAngles.y;
                    }
                }
            }
        }
    }
}
