void Update()
    {
        // TODO move this logic to fish manager
        if (mashMode)
        {
            _currentMashValue -= mashDecayRate * Time.deltaTime;
            _currentMashValue  = Mathf.Max(_currentMashValue, 0f);
            _mashTimer        -= Time.deltaTime;
            if (_mashTimer <= 0f)
            {
                FailCatch();
            }
        }

        if (_reelTimer > 0f)
        {
            _reelTimer -= Time.deltaTime;
            if (_reelTimer <= 0f)
            {
                DoReel();
            }
        }

        // pick spot
        if (Input.GetKeyDown(KeyCode.Z))
        {
            if (mashMode)
            {
                _currentMashValue += mashPressValue;
                SpawnHeartParticles();
                if (_currentMashValue > 1f)
                {
                    CompleteCatch();
                }
            }
            else if (rodBehaviour.currentState == RodState.Idle)
            {
                rodBehaviour.HandleInput(RodAction.Cast);
                reticleMover.gameObject.SetActive(false);
                bobberBehaviour.targetPosition = reticleMover.position;
                baitManager.Hide();
            }
            else if (rodBehaviour.currentState == RodState.WaitingForBite)
            {
                // OneShotManager.PlayOneShot(buttonPressClip);
                var biteResult = fishManager.TryGetBite();
                switch (biteResult)
                {
                case BiteResult.Invalid:
                    break;

                case BiteResult.SmallBiteSuccess:
                    buttonIndicatorAnimator.SetTrigger("GoodPress");
                    OneShotManager.PlayOneShot(goodPressOneShot);
                    SpawnHeartParticles();
                    rodBehaviour.HandleInput(RodAction.SmallBite);
                    break;

                case BiteResult.BiteFail:
                    buttonIndicatorAnimator.SetTrigger("BadPress");
                    OneShotManager.PlayOneShot(badPressOneShot);
                    rodBehaviour.HandleInput(RodAction.SmallBite);
                    break;

                case BiteResult.BigBiteSuccess:
                    mashMode          = true;
                    _currentMashValue = 0f;
                    _mashTimer        = mashMaxDuration;
                    buttonIndicatorAnimator.SetTrigger("MashTime");
                    rodBehaviour.HandleInput(RodAction.BigBite);
                    break;
                }
            }
        }

        if (Input.GetKeyDown(KeyCode.X))
        {
            buttonIndicatorAnimator.SetTrigger("Reset");
            if (rodBehaviour.currentState == RodState.WaitingForBite)
            {
                DoReel();
                fishManager.HandleReel();
            }
            reticleMover.gameObject.SetActive(true);
        }
    }