using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;


[RequireComponent(typeof(Rigidbody))]
public class PlayerPhysicsController : MonoBehaviour
{
    public GameObject OrbitObject;
    public float Acceleration = 0.05f;
    public float Break = 0.1f;
    public float Torque = 100.0f;
    public float MaxSpeed = 6.0f;

    private SphereCollider _orbitCollider;
    private Rigidbody _rigidBody;

    private const float TOLERANCE = 0.01f;
    private float _speed = 0.0f;
    private float _rotation = 0.0f;
    private SatControl currentSelection;

    public AudioSource audioSource1;
    public AudioSource audioSource2;
    public AudioSource audioSource3;
    public AudioClip repairSound;
    public AudioClip[] shieldSounds;
    public AudioClip shieldStaticBackground;

    private SatControl[] satControls;

    void Start()
    {
        _rigidBody = GetComponent<Rigidbody>();
        _orbitCollider = OrbitObject.GetComponent<SphereCollider>();
        Vector3 up = transform.position - OrbitObject.transform.position;
        transform.position = _orbitCollider.radius * up.normalized;

        satControls = GameObject.FindObjectsOfType<SatControl>();
        AdjustBackgroundShieldNoise();

        audioSource3.clip = shieldStaticBackground;
        audioSource3.loop = true;
        audioSource3.Play();
    }

    // Update is called once per frame
    void Update()
    {
        Collider sat = GetNearestSat();
        SatControl satC = null;

        if(sat != null)
        {
            satC = sat.GetComponentInParent<SatControl>();
        }

        if (Input.GetButtonDown("Jump") || Input.GetButtonDown("Fire1"))
        {
            if (satC != null)
            {
                satC.Activate(true);
                int index = Random.Range(0, shieldSounds.Length);
                AudioClip shieldSound = shieldSounds[index];

                audioSource1.PlayOneShot(repairSound, 0.2f);
                audioSource2.clip = shieldSound;
                audioSource2.PlayDelayed(0.4f);

                AdjustBackgroundShieldNoise();
            }
        }

        if (currentSelection != null)
            currentSelection.Select(false);

        currentSelection = satC;
        if (currentSelection != null)
            currentSelection.Select(true);
    }

    private Collider GetNearestSat()
    {
        Collider[] sats = Physics.OverlapSphere(this.transform.position, 1, LayerMask.GetMask("Sat"));

        float distance = float.MaxValue;
        Collider sat = null;

        foreach (var s in sats)
        {
            var dist = Vector3.Distance(s.transform.position, transform.position);
            if (dist < distance)
            {
                distance = dist;

                sat = s;
            }
        }

        return sat;
    }

    void FixedUpdate()
    {
        FixToOrbit();
        UpdateInput();        
    }

    private void FixToOrbit()
    {
        float distance = Vector3.Distance(_rigidBody.transform.position, OrbitObject.transform.position);
        if (distance + TOLERANCE < _orbitCollider.radius || distance - TOLERANCE > _orbitCollider.radius)
        {
            Vector3 up = _rigidBody.transform.position - OrbitObject.transform.position;
            Vector3 fixedTransform = OrbitObject.transform.position + _orbitCollider.radius * up.normalized;
            _rigidBody.transform.position = Vector3.Lerp(_rigidBody.transform.position, fixedTransform, 0.9f);
        }
    }

    private void UpdateInput()
    {
        float vertical = Input.GetAxis("Vertical");
        if (vertical < 0.0f)
        {
            _speed += Input.GetAxis("Vertical") * Break;
        }
        else
        {
            float speedFactor = 1.0f - (_speed / MaxSpeed);
            _speed += Input.GetAxis("Vertical") * Acceleration * speedFactor;
        }
        _rotation = Input.GetAxis("Horizontal") * Torque;
        if (_speed > MaxSpeed)
        {
            _speed = MaxSpeed;
        }
        if (_speed < 0.0f)
        {
            _speed = 0.0f;
        }
        _rigidBody.MovePosition(_rigidBody.position + this.transform.forward * _speed * Time.fixedDeltaTime);
        _rigidBody.MoveRotation(Quaternion.Slerp(_rigidBody.rotation, _rigidBody.rotation * Quaternion.Euler(Vector3.up * _rotation * Time.fixedDeltaTime), 50f * Time.deltaTime));
    }

    private void OnDrawGizmos()
    {
        Gizmos.color = Color.white;
        Gizmos.DrawLine(transform.position, transform.position + transform.right * 10.0f);
        Gizmos.color = Color.blue;
        Gizmos.DrawLine(transform.position, transform.position + transform.forward * 1.0f);
    }

    private void AdjustBackgroundShieldNoise()
    {
        int satActiveCount = satControls.Count(x => x.Shield.activeSelf);
        float percentShieldsActive = satActiveCount / (float)satControls.Length;
        float shieldStaticVolume = 0.07f * percentShieldsActive;
         audioSource3.volume = shieldStaticVolume;
    }

    /*private void UpdateTransform()
    {w
        //local rotation
        

        //setup height to initial distance
        Vector3 up = transform.position - GravityObject.transform.position;
        transform.position = _initialDistance * up.normalized;

        //setup orientation to planet
        transform.up = up.normalized;
        transform.Rotate(Vector3.up, _rotation, Space.Self);


        transform.position = transform.position + transform.forward * _move;
    }*/


}

