using Unity.BossRoom.Gameplay.Actions;
using Unity.BossRoom.Gameplay.GameplayObjects.Character;
using Unity.Netcode;
using UnityEngine;

[CreateAssetMenu(menuName = "BossRoom/Actions/Swap Action")]
public class SwapAction : Action
{
    private ServerCharacter m_TargetCharacter; // The character to swap with
    private Vector3 m_TargetOriginalPosition; // Target's original position
    private Vector3 m_ServerCharacterOriginalPosition; // Server character's original position
    private bool m_MovementStarted = false; // Ensures movement commands are sent only once

    public override bool OnStart(ServerCharacter serverCharacter)
    {
        // Validate the target
        if (Data.TargetIds == null || Data.TargetIds.Length == 0)
        {
            Debug.LogError("SwapAction failed: No target specified!");
            return false; // End the action immediately
        }

        // Retrieve the target character
        if (!NetworkManager.Singleton.SpawnManager.SpawnedObjects.TryGetValue(Data.TargetIds[0], out var targetObject) ||
            !targetObject.TryGetComponent(out m_TargetCharacter))
        {
            Debug.LogError("SwapAction failed: Target is invalid or missing!");
            return false; // End the action immediately
        }

        // Store original positions
        m_ServerCharacterOriginalPosition = serverCharacter.physicsWrapper.Transform.position;
        m_TargetOriginalPosition = m_TargetCharacter.physicsWrapper.Transform.position;

        // Command both characters to move to each other's original positions
        serverCharacter.ServerSendCharacterInputRpc(m_TargetOriginalPosition);
        m_TargetCharacter.ServerSendCharacterInputRpc(m_ServerCharacterOriginalPosition);

        Debug.Log("SwapAction: Movement commands sent to both players.");
        m_MovementStarted = true;
        return true; // Keep the action active
    }

    public override bool OnUpdate(ServerCharacter serverCharacter)
    {
        if (!m_MovementStarted)
        {
            Debug.LogError("SwapAction OnUpdate called without movement initialization!");
            return false; // Fail-safe: End the action
        }

        // Check if both characters have reached their destinations
        bool serverCharacterReached = Vector3.Distance(serverCharacter.physicsWrapper.Transform.position, m_TargetOriginalPosition) < 0.1f;
        bool targetCharacterReached = Vector3.Distance(m_TargetCharacter.physicsWrapper.Transform.position, m_ServerCharacterOriginalPosition) < 0.1f;

        if (serverCharacterReached && targetCharacterReached)
        {
            Debug.Log("SwapAction: Both players have swapped positions successfully.");
            return false; // End the action
        }

        return true; // Continue the action until both characters reach their destinations
    }

    public override void Reset()
    {
        base.Reset();
        m_TargetCharacter = null;
        m_TargetOriginalPosition = Vector3.zero;
        m_ServerCharacterOriginalPosition = Vector3.zero;
        m_MovementStarted = false;
    }
}