using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.Characters.FirstPerson;

public class VasePiece : MonoBehaviour
{
    public AudioClip glassClink;
    public static Transform grabbedTarget;
    public static List<string> placedPieces = new List<string>();
    public AnimationCurve curve;
    private AudioSource glassSource;
    private Transform parent;
    private Transform player;
    private Rigidbody rbody;
    private float throwForce = 100f;
    private float rotateSpeed = 200f;
    private float distanceBeforeGrab = 2f;
    private bool isHeld;
    private bool rotating;
    private Vector3 snapPosition;
    private Quaternion snapRotation;
    private Transform originalDaddy;
    private Outline outline;

    private void Awake()
    {
        outline = GetComponent<Outline>();
        glassSource = GetComponent<AudioSource>();
        originalDaddy = transform.parent;
        snapPosition = transform.position;
        snapRotation = transform.rotation;
        player = GameObject.FindGameObjectWithTag("Player").transform;
        parent = player.GetChild(0).GetChild(0);
        rbody = GetComponent<Rigidbody>();
    }

    private void Start()
    {
        rbody.isKinematic = false;
        rbody.useGravity = true;
    }

    private void StartGrab()
    {
        if (GetDistanceToPlayer() < distanceBeforeGrab)
        {
            SetGrab(true);
        }
    }

    public void LerpToOriginalPosOverTime(float time)
    {
        Destroy(rbody);
        isHeld = false;
        StartCoroutine(MoveRoutine(time));
    }

    private IEnumerator MoveRoutine(float moveTime)
    {
        float currentTime = 0f;
        Vector3 brokenPos = transform.position;
        Vector3 brokenRot = transform.rotation.eulerAngles;

        while (currentTime < moveTime)
        {
            float t = currentTime / moveTime;

            transform.position = Vector3.Lerp(brokenPos, snapPosition, curve.Evaluate(t));
            transform.rotation = Quaternion.Euler(Vector3.Lerp(brokenRot, snapRotation.eulerAngles, curve.Evaluate(t)));

            currentTime += Time.deltaTime;
            yield return null;
        }

        transform.position = snapPosition;
        transform.rotation = snapRotation;
    }

    private void Update()
    {
        if (isHeld)
        {
            if (GetDistanceToPlayer() > distanceBeforeGrab)
            {
                SetGrab(false);
                return;
            }

            rotating = Input.GetMouseButton(1);
            FirstPersonController.freezeRotation = rotating;
            rbody.velocity = Vector3.zero;

            if (rotating)
            {
                float x = Input.GetAxis("Mouse X");
                float y = Input.GetAxis("Mouse Y");
                transform.Rotate(new Vector3(x, y, 0) * Time.deltaTime * rotateSpeed, Space.World);
            }
            else
                rbody.angularVelocity = Vector3.zero;
        }
    }

    private void OnMouseUp()
    {
        if (enabled && rbody != null)
            SetGrab(false);
    }

    private void OnMouseDown()
    {
        if (!GrabManager.heldItem && enabled)
            StartGrab();
    }

    private void OnMouseEnter()
    {
        if (!GrabManager.heldItem && enabled)
            outline.enabled = true;
    }

    private void OnMouseExit()
    {
        outline.enabled = false;
    }

    public void SetGrab(bool isGrabbing)
    {
        GrabManager.heldItem = isGrabbing;
        grabbedTarget = isGrabbing ? transform : grabbedTarget;
        isHeld = isGrabbing;
        FirstPersonController.freezeRotation = false;

        if (!isGrabbing && GridHighlighter.instance.CanHighlightPiece(transform))
        {
            outline.enabled = false;
            glassSource.Stop();
            glassSource.pitch = Random.Range(0.9f, 1.1f);
            glassSource.clip = glassClink;
            glassSource.Play();
            placedPieces.Add(transform.name);

            if (placedPieces.Count >= 11)
            {
                print("Done!");
                Shatter.instance.CountdownToShatter();
            }

            rbody.isKinematic = true;
            transform.SetParent(originalDaddy);
            transform.position = snapPosition;
            transform.rotation = snapRotation;
            grabbedTarget = null;
            enabled = false;
            return;
        }

        if (rbody == null)
            return;

        rbody.useGravity = !isGrabbing;

        Transform daddy = isGrabbing ? parent : originalDaddy;
        transform.SetParent(daddy);

        if (isGrabbing)
        {
            transform.localPosition = Vector3.zero;
            GridHighlighter.grabbedObjectName = transform.name;
        }

        if (!isGrabbing)
        {
            rotating = false;
            FirstPersonController.freezeRotation = rotating;
        }
    }

    private float GetDistanceToPlayer()
    {
        return Vector3.Distance(parent.position, transform.position);
    }
}