using System;
using System.Collections.Generic;
using System.Linq;
using TMPro;
using UnityEngine;
using Random = UnityEngine.Random;

namespace Bow
{
    public class ArcheryRange : MonoBehaviour
    {
        public TMP_Text highScoreText;
        public TMP_Text timeLeftText;
        public TMP_Text scoreText;

        public Transform targetStartPosition;
        public Transform targetEndPosition;
        public GameObject targetPrefab;
        public StartTarget startTarget;

        public Vector3 minRandomOffset = new Vector3(0f, -2f, -5f);
        public Vector3 maxRandomOffset = new Vector3(0f, 2f, 5f);
        public float roundLength = 60f;
        public float targetSpawnTime = 3f;


        private List<ArcheryTarget> _targets;
        private float _score;
        private float _maxScore;
        private float _roundEndTime;
        private float _nextTargetTime;
        private float _startEndDistance;
        private bool _roundActive;

        // Start is called before the first frame update
        void Start()
        {
            highScoreText.text = "High Score: 0";
            _roundActive = false;
            _targets = new List<ArcheryTarget>();
            _score = 0;
            _maxScore = 0;
            _roundEndTime = 0f;
            _startEndDistance = Vector3.Distance(targetStartPosition.position, targetEndPosition.position);
        }

        // Update is called once per frame
        void Update()
        {
            if (!_roundActive) return;

            if (Time.time >= _roundEndTime)
            {
                Reset();
            }
            else
            {
                timeLeftText.text = $"Time Left: {Math.Ceiling((_roundEndTime - Time.time) % 60)}";
                if (Time.time >= _nextTargetTime)
                {
                    _nextTargetTime = Time.time + targetSpawnTime;
                    SpawnTarget();
                }
            }
        }

        private void SpawnTarget()
        {
            var randomPos = targetStartPosition.position + new Vector3(
                Random.Range(minRandomOffset.x, maxRandomOffset.x),
                (float) Math.Round(Random.Range(minRandomOffset.y, maxRandomOffset.y)),
                Random.Range(minRandomOffset.z, maxRandomOffset.z));

            var prefab = Instantiate(targetPrefab, randomPos, Quaternion.identity, null);

            ArcheryTarget target = prefab.GetComponent<ArcheryTarget>();

            target.endPosition = targetEndPosition.position;
            target.minRandomOffset = minRandomOffset;
            target.maxRandomOffset = maxRandomOffset;
            target.archeryRange = this;

            _targets.Add(target);
        }


        public void Reset()
        {
            foreach (var target in _targets.Where(target => target != null))
            {
                Destroy(target.gameObject);
            }


            _targets = new List<ArcheryTarget>();
            if (_maxScore < _score) _maxScore = _score;
            _score = 0;
            highScoreText.text = $"High Score: {_maxScore}";
            startTarget.ShowTarget();
            _roundActive = false;
            timeLeftText.text = "";
        }

        public void StartRound()
        {
            _roundEndTime = Time.time + roundLength;
            _nextTargetTime = Time.time;
            _roundActive = true;
        }

        public void AddScore(float distance)
        {
            _score += distance;
            scoreText.text = $"Score: {_score}";
        }
    }
}