using UnityEngine;
using System.Collections.Generic;

public class ControlsController : MonoBehaviour
{
    public static ControlsController Instance { get; private set; }

    private GameObject _controlledObject; // Объект под управлением (обычно id=1)
    private CharacterController _characterController;

    [Header("Movement Settings")]
    public float moveSpeed = 300f;
    public float rotationSpeed = 90f;

    [Header("Camera Settings")]
    public float cameraRotationAngle = 45f;
    public float cameraChangeSpeed = 5f;

    private void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject);
        }
    }

    public void SetControlledObject(GameObject obj)
    {
        _controlledObject = obj;
        _characterController = obj?.GetComponent<CharacterController>();
        cameraRotationAngle = App.CameraController.currentCameraRotation;

        if (_controlledObject != null)
        {
            Debug.Log($"Controlled object set: {_controlledObject.name}");
            UpdateCameraPosition();
        }
    }

    private void Update()
    {
        if (_controlledObject == null || App.GameState.IsPlayerControlLocked)
            return;

        HandleMovement();
        HandleCameraRotation();
        HandleInteraction();
    }

    private void HandleMovement()
    {
        float horizontal = Input.GetAxis("Horizontal");
        float vertical = Input.GetAxis("Vertical");

        if (horizontal != 0 || vertical != 0)
        {
            Vector3 movement = new Vector3(horizontal, 0, vertical) * moveSpeed * Time.deltaTime;

            // Преобразуем движение относительно камеры
            Vector3 cameraForward = App.CameraController.transform.forward;
            cameraForward.y = 0;
            cameraForward.Normalize();

            Vector3 cameraRight = App.CameraController.transform.right;
            cameraRight.y = 0;
            cameraRight.Normalize();

            Vector3 moveDirection = (cameraForward * vertical + cameraRight * horizontal).normalized;
            _controlledObject.transform.position += moveDirection * moveSpeed * Time.deltaTime;

            // Поворачиваем персонажа в направлении движения
            if (moveDirection != Vector3.zero)
            {
                Quaternion targetRotation = Quaternion.LookRotation(moveDirection);
                _controlledObject.transform.rotation = Quaternion.Slerp(
                    _controlledObject.transform.rotation,
                    targetRotation,
                    rotationSpeed * Time.deltaTime
                );
            }

            // Обновляем камеру
            UpdateCameraPosition();
        }
    }

    private void HandleCameraRotation()
    {
        if (Input.GetKeyDown(KeyCode.Q))
        {
            RotateCamera(-1);
        }
        else if (Input.GetKeyDown(KeyCode.E))
        {
            RotateCamera(1);
        }
    }

    private void RotateCamera(float angle)
    {
        int newRotation = App.CameraController.currentCameraRotation + (int)angle;
        cameraRotationAngle = newRotation;

        //int newRotation = (currentRotation + (int)(angle / 45f)) % 8;
        //if (newRotation < 0) newRotation += 8;

        App.CameraController.RotateCameraSmoothly(newRotation);
    }

    private void HandleInteraction()
    {
        if (Input.GetButtonDown("Submit"))
        {
            CheckNearbyInteractions();
        }
    }

    private void CheckNearbyInteractions()
    {
        Collider[] hitColliders = Physics.OverlapSphere(_controlledObject.transform.position, 100f);
        foreach (var hitCollider in hitColliders)
        {
            CharacterController otherController = hitCollider.GetComponent<CharacterController>();
            if (otherController != null && otherController != _characterController)
            {
                if (otherController.blockSubroutine != 0)
                {
                    StartSubroutine((ushort)otherController.blockSubroutine);
                    break;
                }
            }
        }
    }

    public void UpdateCameraPosition()
    {
        if (_controlledObject != null)
        {
            Vector3 position = _controlledObject.transform.position;
            App.CameraController.SetCamTargetXY(
                (uint)App.CameraController.currentCameraRotation,
                (uint)position.x,
                (uint)position.y,
                (uint)position.z
            );
        }
    }

    private void StartSubroutine(ushort subId)
    {
        if (App.VM != null)
        {
            App.VM.StartSubroutine(subId);
        }
    }
}