using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;
using ExitGames.Client.Photon;
using Cinemachine;
using TMPro;

public class Movement : MonoBehaviourPunCallbacks
{
    [SerializeField] private Camera cam;
    [SerializeField] private CinemachineVirtualCamera cCam;
    [SerializeField] private float _speed;
    [SerializeField] private float _rotationSpeed;
    [SerializeField] private float _heightRotationSpeed;
    private float _hRotationValue = 0;
    private float _vRotationValue = 0;

    private float _break;
    private float _bonusSpeed = 1;

    private Rigidbody _rb;

    [SerializeField] private Transform lookObject;
    [SerializeField] private Transform followObject;
    [SerializeField] private GameObject lines;
    [SerializeField] private Vector3 lookPosition = new Vector3(0, 1, 1);

    [SerializeField] private Animator _playerAnim;

    PhotonView view;
    private bool _isMyMover = false;
    [HideInInspector] public bool Won;
    private bool _triggeredWin;
    private bool _hitFlower;
    [SerializeField] private bool _enoughPlayers;
    [SerializeField] private bool _debug = false;

    [SerializeField] private ParticleSystem _speedLines;
    [SerializeField] private ParticleSystem _powerLines;
    [SerializeField] private GameObject _powerBurst;
    [SerializeField] private AudioSource _flap;
    [SerializeField] private AudioSource _wind;
    [SerializeField] private AudioSource _soundtrack;
    [SerializeField] private AudioSource _wallHit;
    [SerializeField] private AudioSource _shotSound;
    private bool _fadeOutMusic = false;

    [SerializeField] private GameObject _shot;
    [SerializeField] private Transform _shotPos;
    private float _shotTimer = 0.5f;

    private const byte WON_EVENT = 0;



    // Start is called before the first frame update
    void Start()
    {
        _rb = GetComponent<Rigidbody>();
        view = GetComponent<PhotonView>();

        if (!_debug)
        {
            {
                _isMyMover = true;
            }
        }
    }

    // Update is called once per frame
    void Update()
    {
        if (PhotonNetwork.CurrentRoom.PlayerCount == PhotonNetwork.CurrentRoom.MaxPlayers)
        {
            _enoughPlayers = true;
        }
        #region basic movement
        if (view.IsMine)
        {
            if (_enoughPlayers)
            {
                cCam.LookAt = lookObject;
                cCam.Follow = followObject;

                if (Input.GetKey(KeyCode.LeftShift))
                {
                    var t = _break - Time.deltaTime * 0.5f;
                    _break = Mathf.Clamp(t, 0, 1);
                    _speedLines.Stop();

                }
                else if (_break < 1)
                {
                    var t = _break + Time.deltaTime * 0.5f;
                    _break = Mathf.Clamp(t, 0, 1);
                    _speedLines.Play();
                }

                Vector3 movement = transform.rotation * Vector3.forward;
                // transform.localPosition += _speed * Time.deltaTime * movement;
                //_rb.position += _speed * Time.deltaTime * movement;
                _rb.AddForce(_speed * Time.deltaTime * movement * 100 * _break * _bonusSpeed);

                if (Input.GetKey(KeyCode.W))
                {
                    // Transform downwards
                    _vRotationValue += _heightRotationSpeed * Time.deltaTime;
                    _playerAnim.SetBool("SteeringDownwards", true);
                    _wind.volume += Time.deltaTime * 10;
                }
                else
                {
                    _playerAnim.SetBool("SteeringDownwards", false);
                    _wind.volume -= Time.deltaTime * 10;
                }
                if (Input.GetKey(KeyCode.S))
                {
                    // Rotate upwards
                    _vRotationValue -= _heightRotationSpeed * Time.deltaTime;
                    _playerAnim.SetBool("SteeringUpwards", true);
                    _flap.volume += Time.deltaTime * 10;
                }
                else
                {
                    _playerAnim.SetBool("SteeringUpwards", false);
                    _flap.volume -= Time.deltaTime * 10;
                }
                if (Input.GetKey(KeyCode.A))
                {
                    _hRotationValue -= _rotationSpeed * Time.deltaTime;
                }
                if (Input.GetKey(KeyCode.D))
                {
                    _hRotationValue += _rotationSpeed * Time.deltaTime;
                }

                if (_vRotationValue < 0)
                {
                    _vRotationValue = 360;
                }
                else if (_vRotationValue > 360)
                {
                    _vRotationValue = 0;
                }
                if (_hRotationValue < 0)
                {
                    _hRotationValue = 360;
                }
                else if (_hRotationValue > 360)
                {
                    _hRotationValue = 0;
                }

                transform.localRotation = Quaternion.Euler(_vRotationValue, _hRotationValue, 0);

                #endregion

                if (_fadeOutMusic)
                {
                    _soundtrack.volume -= Time.deltaTime * 0.5f;
                }

                lookObject.transform.position = transform.position + lookPosition;

                _shotTimer -= Time.deltaTime;
                if (Input.GetKeyDown(KeyCode.Space))
                {
                    if (_shotTimer < 0)
                    {
                        var newShot = PhotonNetwork.Instantiate(_shot.name, _shotPos.position, _shotPos.rotation);
                        Destroy(newShot, 10);
                        _shotSound.pitch = Random.Range(1.5f, 1.8f);
                        _shotSound.Play();
                        _shotTimer = 0.5f;
                    }
                }

                if (_bonusSpeed > 1)
                {
                    _bonusSpeed -= Time.deltaTime * 0.5f;
                }
                else if (_bonusSpeed < 1)
                {
                    _bonusSpeed = 1;
                    _powerLines.Stop();
                }
                else
                {
                    _powerLines.Stop();
                }
            }
        }
        else
        {
            cam.enabled = false;
            cCam.enabled = false;
            lines.SetActive(false);
            _soundtrack.transform.gameObject.SetActive(false);
        }
    }

    public void GameDone()
    {
        if (!_triggeredWin)
        {
            if (Won)
            {
                GameObject.FindGameObjectWithTag("Won").GetComponent<TMP_Text>().enabled = true;
                Destroy(GameObject.FindGameObjectWithTag("Lost"));
            }
            else
            {
                GameObject.FindGameObjectWithTag("Lost").GetComponent<TMP_Text>().enabled = true;
                // Destroy(GameObject.FindGameObjectWithTag("Won"));
            }
            _triggeredWin = true;
        }
    }

    public override void OnEnable()
    {
        base.OnEnable();
        PhotonNetwork.NetworkingClient.EventReceived += NetworkingClient_EventRecieved;
    }

    public override void OnDisable()
    {
        base.OnDisable();
        PhotonNetwork.NetworkingClient.EventReceived -= NetworkingClient_EventRecieved;
    }

    private void NetworkingClient_EventRecieved(EventData obj)
    {
        if (obj.Code == WON_EVENT)
        {
            if (_hitFlower)
            {
                Won = true;
            }
            GameDone();
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.tag == "Finish")
        {
            _hitFlower = true;
            PhotonNetwork.RaiseEvent(WON_EVENT, Won, RaiseEventOptions.Default, SendOptions.SendUnreliable);
        }
        else if (other.tag == "Power")
        {
            _bonusSpeed = 2f;
            _powerLines.Play();
            var burstPart = Instantiate(_powerBurst, other.transform.position, other.transform.rotation);
            foreach (Transform child in other.transform)
            {
                child.gameObject.SetActive(false);
            }
            other.gameObject.SetActive(false);
            Destroy(burstPart, 3f);
        }
        else if (other.tag == "GoalCube")
        {
            _fadeOutMusic = true;
        }
    }

    private void OnCollisionEnter(Collision collision)
    {
        if (collision.transform.tag == "Bullet")
        {
            _break = 0;
        }
        else if (collision.transform.tag == "Roots")
        {
            _wallHit.Play();
        }
    }
}
