using System;
using System.Collections;
using UnityEngine;

/// <summary>
/// Implements live tracking of streamed OptiTrack rigid body data onto an object using Rigid Body Name instead of ID,
/// and periodically rechecks the ID.
/// </summary>
public class OptitrackRigidBody : MonoBehaviour
{
    [Tooltip("The object containing the OptiTrackStreamingClient script.")]
    public OptitrackStreamingClient StreamingClient;

    [Tooltip("The name of the rigid body in Motive.")]
    public string RigidBodyName;

    private float updateInterval = 0.1f;

    private int RigidBodyId = -1;
    private string lastCheckedName; // 마지막으로 확인한 이름을 저장
    
    [HideInInspector]
    public bool isRigidBodyFound = false;

    void Start()
    {
        // StreamingClient를 찾습니다.
        if (this.StreamingClient == null)
        {
            this.StreamingClient = OptitrackStreamingClient.FindDefaultClient();

            if (this.StreamingClient == null)
            {
                Debug.LogError(GetType().FullName + ": Streaming client not set, and no " + typeof(OptitrackStreamingClient).FullName + " components found in scene; disabling this component.", this);
                this.enabled = false;
                return;
            }
        }

        // 주기적으로 RigidBody를 찾는 코루틴 시작
        StartCoroutine(CheckRigidBodyIdPeriodically());
    }

    void Update()
    {
        UpdatePose();
    }

    void UpdatePose()
    {
        if (!isRigidBodyFound) return;

        OptitrackRigidBodyState rbState = StreamingClient.GetLatestRigidBodyState(RigidBodyId);
        if (rbState != null)
        {
            this.transform.localPosition = rbState.Pose.Position;
            this.transform.localRotation = rbState.Pose.Orientation;
        }
    }

    private IEnumerator CheckRigidBodyIdPeriodically()
    {
        while (true)
        {
            // 현재 이름이 마지막으로 확인한 이름과 다르거나, RigidBody를 찾지 못한 상태라면 검색 수행
            if (lastCheckedName != RigidBodyName || !isRigidBodyFound)
            {
                int newRigidBodyId = StreamingClient.GetRigidBodyIdByName(RigidBodyName);

                if (newRigidBodyId != -1)
                {
                    if (newRigidBodyId != RigidBodyId)
                    {
                        // 새로운 RigidBody 발견
                        RigidBodyId = newRigidBodyId;
                        this.StreamingClient.RegisterRigidBody(this, RigidBodyId);
                        Debug.Log($"RigidBody 재연결 성공: {RigidBodyName} (ID: {RigidBodyId})");
                    }
                    isRigidBodyFound = true;
                    lastCheckedName = RigidBodyName;
                }   
                else
                {
                    // RigidBody를 찾지 못함
                    isRigidBodyFound = false;
                    //Debug.LogWarning($"RigidBody를 찾을 수 없음: {RigidBodyName}");
                }
            }

            yield return new WaitForSeconds(updateInterval);
        }
    }
}
