using System;
using Assets.Source.Misc;
using Assets.Source.Patterns;
using DG.Tweening;
using UnityEngine;

namespace Assets.Source.Core.Gameplay.Topdown
{
    public class CameraTopdown : Singleton<CameraTopdown>
    {
        public Camera Camera;
        public Transform Target;
        public float LerpSpeed = 5;
        public float MovementExtraFov = 2;
        public float FovLerpSpeed = 1;

        private float _defaultHeight;
        private float _defaultFov;
        private float _lerpingFov;
        private GameObject _shakeDummy;
        private Vector3 _currentNormalPos;

        protected override void Awake()
        {
            base.Awake();
            _defaultHeight = transform.position.z;
            _defaultFov = Camera.orthographicSize;
            _lerpingFov = _defaultFov;
            _shakeDummy = new GameObject("CamShakeDummy");
            _currentNormalPos = transform.position;
        }

        void FixedUpdate()
        {
            if (Target == null)
                return;
            var targetPos = Target.position;
            var bounds = GameManagerTopdown.Instance.Bounds;
            if (!bounds.bounds.Contains(targetPos))
            {
                targetPos = bounds.bounds.ClosestPoint(targetPos);
                //var closest = bounds.bounds.ClosestPoint(targetPos);
            }
            _currentNormalPos = Vector3.Lerp(_currentNormalPos, targetPos, Time.fixedDeltaTime * LerpSpeed);
            _currentNormalPos.z = _defaultHeight;
            transform.position = _currentNormalPos + _shakeDummy.transform.position;
            var input = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
            input = Vector2.ClampMagnitude(input, 1);
            _lerpingFov = Mathf.Lerp(_lerpingFov, _defaultFov + MovementExtraFov * input.magnitude,
                Time.fixedDeltaTime * FovLerpSpeed);
            Camera.orthographicSize = _lerpingFov;
        }

        public void ShakePos(CamShakeArgs args)
        {
            _shakeDummy.transform.DOShakePosition(args.Duration, args.Strength, args.Vibrato, args.Randomness);
        }
    }
}