using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using EzySlice;
using UnityEngine.InputSystem;
using UnityEngine.XR.Interaction.Toolkit;
using System;
#if FMOD_AVAILABLE
using FMOD;
using FMODUnity;
#endif

public class SliceObjectsVR : MonoBehaviour
{
    public Transform startSlicePoint;
    public Transform endSlicePoint;
    public LayerMask sliceableLayer;
    public Material crossSectionMaterial;
    public float cutForce = 0.1f;
    public float explosionRadius = 0.1f;

    private Vector3 lastSlicerPosition; // Letzte Position von SLICER
    private Vector3 slicerVelocity; // Berechnete Geschwindigkeit von SLICER

#if FMOD_AVAILABLE
    [SerializeField]
    EventReference onGrabSoundRef;

    [SerializeField]
    EventReference onCollideSoundRef;

    [SerializeField]
    EventReference sliceSoundRef;
#endif

    void Start()
    {
        lastSlicerPosition = transform.position; // Startposition speichern
    }

    void FixedUpdate()
    {
        // Berechnung der Geschwindigkeit von SLICER
        slicerVelocity = (transform.position - lastSlicerPosition) / Time.fixedDeltaTime;
        lastSlicerPosition = transform.position;

        // Pruefen, ob ein schneidbares Objekt getroffen wird
        bool hasHit = Physics.Linecast(startSlicePoint.position, endSlicePoint.position, out RaycastHit hit, sliceableLayer);
        if (hasHit)
        {
            GameObject target = hit.transform.gameObject;
            Slice(target);
        }
    }

    public void Slice(GameObject target)
    {
        // Normalenvektor fuer die Schnittebene berechnen
        Vector3 planeNormal = Vector3.Cross(endSlicePoint.position - startSlicePoint.position, slicerVelocity);
        planeNormal.Normalize();

        //Debug.Log($"Direction: {planeNormal}, Magnitude: {planeNormal.magnitude}");
        //Debug.Log($"Velocity: {slicerVelocity}, Magnitude: {slicerVelocity.magnitude}");

        // Pruefen, ob das Objekt geschnitten werden kann
        SlicedHull hull = target.Slice(endSlicePoint.position, planeNormal);

        if (hull != null)
        {
#if FMOD_AVAILABLE
            RuntimeManager.PlayOneShot(sliceSoundRef, transform.position);
#endif
            GameObject upperHull = hull.CreateUpperHull(target, crossSectionMaterial);
            SetupSlicedComponent(upperHull);

            GameObject lowerHull = hull.CreateLowerHull(target, crossSectionMaterial);
            SetupSlicedComponent(lowerHull);

            Destroy(target);
        }
    }

    public void SetupSlicedComponent(GameObject slicedObject)
    {
        Rigidbody rb = slicedObject.AddComponent<Rigidbody>(); //add Rigidbody
        rb.interpolation = RigidbodyInterpolation.Interpolate;

        MeshCollider collider = slicedObject.AddComponent<MeshCollider>();  //add Meshcolider
        collider.convex = true;  //make Collider convex

        rb.AddExplosionForce(cutForce, slicedObject.transform.position, explosionRadius); //add force for realistic behaviour

        slicedObject.layer = 6; // 6 = "sliceableLayer"

        XRGrabInteractable grabInteractable = slicedObject.AddComponent<XRGrabInteractable>(); //add grabbable Script
        grabInteractable.movementType = XRBaseInteractable.MovementType.VelocityTracking;
        grabInteractable.useDynamicAttach = true;

#if FMOD_AVAILABLE
        OnGrabSound onGrabSoundScript = slicedObject.AddComponent<OnGrabSound>(); //add grab sound
        onGrabSoundScript.soundRef = onGrabSoundRef;
        OnCollideSound onCollideSoundScript = slicedObject.AddComponent<OnCollideSound>(); //add collision sound
        onCollideSoundScript.soundRef = onCollideSoundRef;
#endif

        slicedObject.gameObject.tag = "SlicedZwiebel";
        string timeStamp = DateTime.Now.ToString("mmssffff");
        slicedObject.gameObject.name = $"SlicedZwiebel_{timeStamp}";
    }
}