﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using Photon.Pun;

public class ForwardRocketScript : MonoBehaviourPunCallbacks {

	public RacerScript racer;
	public GameObject rocket;
	public GameObject explosion;
	public bool rocketActive = false;
	public bool called = false;
    //public float knockHeight = 10f;
	Vector3 velocity = Vector3.zero;
	public LayerMask hitMask, trackMask;
	private Vector3 checkPoint;

	// Start is called before the first frame update
	void Start() {
		if (!racer) {
			StartCoroutine (DestroySelf ());
		}
	}

	// Update is called once per frame
	void Update() {
		if (racer) {
			if (Input.GetKeyDown (KeyCode.LeftShift) || Input.GetKeyDown (KeyCode.RightShift)) {
				if (!called) {
					called = true;
					racer.itemCanvas.itemActivated = true;
					StartCoroutine (LaunchRocket ());
				}
			}
		}
	}

	void FixedUpdate() {
		
		if(!racer){

			RaycastHit wall;
			Physics.Raycast(transform.position, transform.forward, out wall, 1.5f, hitMask) ;



			if (wall.transform)
			{
				transform.forward = Vector3.Reflect(transform.forward, wall.normal);
			}

			RaycastHit floor;
			Physics.Raycast (new Vector3 (transform.position.x, transform.position.y + 1f, transform.position.z), -transform.up, out floor, Mathf.Infinity, trackMask);

			if (floor.transform) {
				transform.parent.up = floor.normal;
				transform.parent.position = floor.point + transform.parent.up;
			}

			transform.parent.position += transform.forward * 1.5f;
			checkPoint = transform.position + transform.forward;
			//Vector3.SmoothDamp (transform.parent.position, transform.parent.position += transform.forward * 1.5f, ref velocity, 0.3f);
		}
	}

	void OnTriggerEnter (Collider col) {
		if (rocketActive) {
			if (col.tag != "Player") { return; }
			if (col.transform.parent.GetChild (1).GetComponent<KartController> ()) {
				if(PhotonNetwork.IsConnected && !col.transform.parent.GetChild (1).GetComponent<KartController> ().photonView.IsMine){
					return;
				}
				if (explosion)
				{
					GameObject newExplosion = Instantiate(explosion, col.transform);
					newExplosion.transform.position = col.transform.position;
				}
				StartCoroutine (RocketHit (col.transform.parent.GetChild (1).GetComponent<KartController> ()));
			} else if (col.transform.GetComponent<ForwardRocketScript> () && (!col.transform.parent.GetComponentInChildren<KartController>() || !col.GetComponentInChildren<KartController>())) {
				Destroy (transform.parent.gameObject);
			}
		}

	}

	IEnumerator DestroySelf () {
		yield return new WaitForSeconds (0.5f);
		rocketActive = true;
		yield return new WaitForSeconds (7f);
		if (!rocketActive) {
			yield break;
		} else {
			Destroy (transform.parent.gameObject);
		}
	}

	IEnumerator LaunchRocket () {
		if (PhotonNetwork.IsConnected) {
			GameObject forwardRocket = PhotonNetwork.Instantiate ("Bounce Rocket", racer.kart.transform.position, Quaternion.identity);
			forwardRocket.transform.GetChild (0).rotation = racer.kart.transform.rotation;
			yield return new WaitForSeconds (0.5f);
			forwardRocket.GetComponentInChildren<ForwardRocketScript> ().rocketActive = true;
		} else {
			GameObject forwardRocket = GameObject.Instantiate (rocket, racer.kart.transform.position, Quaternion.identity);
			forwardRocket.transform.GetChild (0).rotation = racer.kart.transform.rotation;
			yield return new WaitForSeconds (0.5f);
			forwardRocket.GetComponentInChildren<ForwardRocketScript> ().rocketActive = true;
		}
		called = false;
		racer.SetActiveItem (-1);
	}

	IEnumerator RocketHit (KartController kart) {
		rocketActive = false;
		GetComponent<MeshRenderer> ().enabled = false;
		GetComponent<Collider> ().enabled = false;
		if (PhotonNetwork.IsConnected) {
			photonView.RPC ("RocketCall", RpcTarget.OthersBuffered);
		}

        // Increases the drag on the kart to slow it down
        Rigidbody rb = kart.transform.parent.Find("Collider").GetComponent<Rigidbody>();
        rb.drag = 5f;

        // Deactivates any active boosts
        BoostRocketScript boostRocket = kart.transform.parent.GetComponent<BoostRocketScript>();
        boostRocket.CullBoost();
        boostRocket.called = false;

        // Sets acceleration down to a crawl
        kart.acceleration = 10f;
        //kart.transform.GetChild(0).GetChild(0).DOPunchPosition(transform.up * .3f, .3f, 5, 1);

        GameObject kartModel = kart.transform.GetChild(0).GetChild(0).Find("PlaceHolder").GetChild(0).gameObject;
        float t = 0;
        Vector3 newEuler;

        //rb.AddForce(kartModel.transform.up * 10000f);

        while (t < 1.5f)
        {
            float offset = 720 * (t / 1.5f);

            newEuler = new Vector3(0f, -90 + offset, 0f);

            kartModel.transform.localRotation = Quaternion.Euler(newEuler);

            //kartModel.transform.localPosition = new Vector3(0f, -(knockHeight * (t * t)) + (1.5f * t), 0f);


            t += Time.deltaTime;
            yield return new WaitForEndOfFrame();
        }

        newEuler = new Vector3(0f, -90, 0f);
        kartModel.transform.localRotation = Quaternion.Euler(newEuler);

        //kart.transform.DOComplete();
        kart.acceleration = 120f;
        rb.drag = 2;

		Destroy (transform.parent.gameObject);
	}

	[PunRPC]	
	public void RocketCall () {
		GetComponent<MeshRenderer> ().enabled = false;
		GetComponent<Collider> ().enabled = false;
		StartCoroutine (WaitToDelete ());
	}

	IEnumerator WaitToDelete () {
		yield return new WaitForSeconds (1.5f);
		Destroy (gameObject);
	}

    private void OnDrawGizmos()
    {
		Gizmos.color = Color.blue;
		Gizmos.DrawLine(transform.position, transform.position + transform.forward);
	}
}
