﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;

public class LeaderboardButton : MonoBehaviour
{
    [Header("Components")]
    [SerializeField] TextMeshProUGUI m_nameText;
    [SerializeField] TextMeshProUGUI m_placeText;

    [Header("Target")]
    [SerializeField] RacerCore m_racer;

    [Header("Button Settings")]
    [SerializeField] [Min(0)] float m_translateSpeed;

    [Header("Debug")]
    [SerializeField] DebugChannelSO m_debugChannel;

    LeaderboardDisplay m_leaderboardDisplay;
    SpectatorController m_spectatorController;
    IEnumerator co_waitToDestroyIfNoTarget, co_smoothMoveToPosition;

    void Start()
    {
        m_leaderboardDisplay = transform.parent.GetComponent<LeaderboardDisplay>();

        if (!m_leaderboardDisplay)
        {
            Destroy(gameObject);

            return;
        }

        co_waitToDestroyIfNoTarget = WaitToDestroyIfNoTarget();
        StartCoroutine(co_waitToDestroyIfNoTarget);
    }
    IEnumerator WaitToDestroyIfNoTarget()
    {
        yield return new WaitForSecondsRealtime(1);

        while (m_racer != null)
            yield return null;

        Destroy(gameObject);
    }


    public void SetTarget(RacerCore _racer)
    {
        if (_racer == null)
        {
            Destroy(gameObject);
            return;
        }

        m_racer = _racer;

        m_racer.OnPlacementChanged += MoveToPlacement;
        m_racer.OnRaceCompleted += HandleRacerFinish;

        m_nameText.text = "Mystery Racer";

        if (m_racer.photonView)
        {
            object prop;

            m_racer.photonView.Owner.CustomProperties.TryGetValue("DisplayName", out prop);

            if (prop != null)
                m_nameText.text = prop as string;
        }

        Button _button = GetComponent<Button>();

        if (!_button)
            _button = gameObject.AddComponent<Button>();

        _button.onClick.RemoveAllListeners();
        _button.onClick.AddListener(() => ButtonClick());

        MoveToPlacement(FindObjectsOfType<RacerCore>().Length);
    }
    void ButtonClick()
    {
        if (!m_spectatorController)
        {
            m_spectatorController = FindObjectOfType<SpectatorController>();

            if (!m_spectatorController)
            {
                if (m_debugChannel)
                    m_debugChannel.Raise(this, "Clicked on a button, but can't find the spectator controller!", DebugChannelSO.Severity.Error);

                return;
            }
        }

        m_spectatorController.SetCurrentTarget(m_racer.transform, m_nameText.text);
    }

    // MOVE TO TARGET POSITION //
    void MoveToPlacement(int _place)
    {
        m_placeText.text = _place.ToString();

        if (co_smoothMoveToPosition != null)
        {
            StopCoroutine(co_smoothMoveToPosition);
            co_smoothMoveToPosition = null;
        }

        co_smoothMoveToPosition = SmoothMoveTowardPosition(_place);
        StartCoroutine(co_smoothMoveToPosition);
    }
    IEnumerator SmoothMoveTowardPosition(int _place)
    {
        if (!m_leaderboardDisplay)
            yield break;

        Vector3 _targetPosition = new Vector3(m_leaderboardDisplay.ScreenOffset.x, 471 - m_leaderboardDisplay.ScreenOffset.y - (_place * m_leaderboardDisplay.ButtonSpacing));

        if (m_debugChannel)
            m_debugChannel.Raise(this, "Moving to " + _place + " at " + _targetPosition);

        while (transform.position != _targetPosition)
        {
            Vector3 _moveThisFrame = Vector3.ClampMagnitude(_targetPosition - transform.position, m_translateSpeed * Time.deltaTime);

            //if (m_debugChannel)
            //{
            //    m_debugChannel.Raise(this, "Moving from " + transform.position + " to " + _targetPosition + " at a speed of " + (m_translateSpeed * Time.deltaTime));
            //    m_debugChannel.Raise(this, "Button of " + m_nameText.text + " is moving " + _moveThisFrame + " this frame.");
            //}

            transform.Translate(_moveThisFrame);

            yield return null;
        }

        co_smoothMoveToPosition = null;

        yield break;
    }

    // ON TARGET FINISH //
    void HandleRacerFinish()
    {
        m_racer.OnPlacementChanged -= MoveToPlacement;

        StopCoroutine(co_waitToDestroyIfNoTarget);
    }
}