using System.Collections.Generic;
using System.Linq;
using Unity.VisualScripting;
using UnityEngine;
using static UnityEngine.GraphicsBuffer;

public class CameraController : MonoBehaviour
{
    public float camTargetRotation { get; private set; } = 0;
    public CameraControlMode CamControlMode { get; private set; } = CameraControlMode.SnapRotate;
    public Camera MainCamera;

    private bool isCamRotating = false;

    [Header("Free Cam Settings")]
    public float mouseSensitivity = 200f;
    public float minPitch = -30f;
    public float maxPitch = 60f;
    public float distance = 6f;
    public float heightOffset = -0.5f;
    public float followSpeed = 10f;
    public float maxZoom = 6f;
    public float minZoom = 1f;
    private float zoom = 2.3f;
    private float yaw;
    private float pitch;

    public Transform playerCamHome;
    Transform dougBody;

    private void Update()
    {
        if (Input.GetMouseButton(1))
        {
            HandleFreeCamRotation();
        }
    }

    void Start()
    {
        Vector3 angles = transform.eulerAngles;

        yaw = angles.y;
        pitch = angles.x;
    }

    /// <summary>
    /// Trigger cam rotation
    /// </summary>
    public void RotateCam()
    {
        if (!isCamRotating)
        {
            float currentY = playerCamHome.transform.rotation.eulerAngles.y;
            camTargetRotation = currentY + 90f;
            isCamRotating = true;
        }
    }

    /// <summary>
    /// Set cam rotation immediately
    /// </summary>
    void SnapToRotation(float rotation)
    {
        if (CamControlMode == CameraControlMode.SnapRotate)
        {
            playerCamHome.RotateAround(
                transform.position,
                Vector3.up,
                rotation
            );

            camTargetRotation = rotation;
        }
    }

    /// <summary>
    /// Move cam to desired rotation (every frame)
    /// </summary>
    void HandleSnapCamRotation()
    {
        float currentY = playerCamHome.transform.rotation.eulerAngles.y;
        float step = 200 * Time.deltaTime;
        float newY = Mathf.MoveTowardsAngle(currentY, camTargetRotation, step);

        playerCamHome.RotateAround(
            transform.position,
            Vector3.up,
            newY - currentY
        );

        if (Mathf.Abs(Mathf.DeltaAngle(newY, camTargetRotation)) < 0.01f)
        {
            isCamRotating = false;
        }
    }

    /// <summary>
    /// Move cam to desired free rotation (every frame)
    /// </summary>
    void HandleFreeCamRotation()
    {
        if (dougBody == null)
        {
            dougBody = GameManager.Instance.PlayerController.DougBody.transform;
        }

        Vector3 target = new Vector3(dougBody.position.x, dougBody.position.y + heightOffset, dougBody.position.z);

        // Mouse Input
        float mouseX = Input.GetAxis("Mouse X");
        float mouseY = Input.GetAxis("Mouse Y");

        yaw += mouseX * mouseSensitivity * Time.deltaTime;
        pitch -= mouseY * mouseSensitivity * Time.deltaTime;

        pitch = Mathf.Clamp(pitch, minPitch, maxPitch);

        // Zoom
        float scroll = Input.GetAxis("Mouse ScrollWheel");

        zoom -= scroll * 2f;
        zoom = Mathf.Clamp(zoom, minZoom, maxZoom);
        MainCamera.orthographicSize = zoom;

        // Rotation
        Quaternion rotation = Quaternion.Euler(pitch, yaw, 0);

        // Desired Position
        Vector3 offset = rotation * Vector3.forward * -distance;
        Vector3 desiredPosition = target + offset;

        // Smooth Follow
        playerCamHome.transform.position = Vector3.Lerp(
            playerCamHome.transform.position,
            desiredPosition,
            followSpeed * Time.deltaTime
        );

        // Look at player
        playerCamHome.transform.LookAt(target + Vector3.up);
    }
}

public enum CameraControlMode
{
    SnapRotate,
    FreeRotate
}
