using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

[System.Serializable]
public class LiftableEvent : UnityEvent<Liftable> { }

public class Liftable : MonoBehaviour
{
    [SerializeField] protected float _dropForce = 10f;
    [SerializeField] protected float _maxPlaceSlopeAngle = 360f;
    [SerializeField] protected bool _sticksOnPlace = true;
    [SerializeField] protected bool _alignsToSurface = true;
    protected bool _isBeignLifted;
    private Rigidbody _body;

    [SerializeField] private LiftableEvent onLift;
    [SerializeField] private LiftableEvent onDrop;
    [SerializeField] private LiftableEvent onPlace;

    private void Awake()
    {
        _body = GetComponent<Rigidbody>();
    }

    public bool isBeignLifted
    {
        get
        {
            return _isBeignLifted;
        }
    }

    public Rigidbody body
    {
        get
        {
            return _body;
        }
    }

    virtual public bool CanBeLifted (Lifter lifter)
    {
            return !_isBeignLifted;
    }

    virtual public bool Lift(Lifter lifter)
    {
        if (!CanBeLifted(lifter))
            return false;
        _body.isKinematic = true;
        _isBeignLifted = true;
        onLift?.Invoke(this);
        return true;
    }

    virtual public void Drop(Lifter lifter, Vector3 dir)
    {
        _body.isKinematic = false;
        _isBeignLifted = false;
        _body.velocity = dir * _dropForce;
    }

    virtual public bool Place(Lifter lifter, Vector3 atpoint, Vector3 atnormal, Quaternion atRot)
    {
        if (Vector3.Angle(Vector3.up, atnormal) > _maxPlaceSlopeAngle)
            return false;
        _isBeignLifted = false;
        onPlace?.Invoke(this);
        _body.isKinematic = _sticksOnPlace;
        transform.position = atpoint;
        if (_alignsToSurface)
            transform.rotation = Quaternion.LookRotation(atnormal);
        else
            transform.rotation = atRot;
        return true;
    }
}