using GCGame.Table;
using UnityEngine;

public class WuChangLinkController : MonoBehaviour, IParticleCleaner
{
    private float _breakLinkSpeed;
    private Vector3[] _breakPoints;
    private float _breakTime;
    private bool _isBreak;
    private ParticleSystem _linkParticle;
    private float _baseRateOverTime;
    private float _baseRateOverDistance;
    private LinkFxController _mainLink;
    private bool _started;
    private LinkFxController[] _subLinks;

    public float DelayRecoveryTime
    {
        get { return 0; }
    }

    public void StartDelayRecovery()
    {
        if (_mainLink != null)
        {
            _mainLink.gameObject.SetActive(false);
            for (var i = 0; i < _subLinks.Length; i++)
                _subLinks[i].gameObject.SetActive(false);
        }
    }

    public void Init(Tab_Effect data)
    {
        _breakLinkSpeed = data.GetParamValuebyIndex(0) * 0.01f;
    }

    private void Start()
    {
        var linkExample = transform.Find("LinkExample").gameObject;
        _linkParticle = transform.Find("LinkParticle").GetComponent<ParticleSystem>();
        var emission = _linkParticle.emission;
        _baseRateOverTime = emission.rateOverTimeMultiplier;
        _baseRateOverDistance = emission.rateOverDistanceMultiplier;
        _subLinks = new LinkFxController[2];
        _breakPoints = new Vector3[2];
        for (var i = 0; i < _subLinks.Length; i++)
        {
            var linkObj = Instantiate(linkExample);
            linkObj.name = string.Format("SubLink_{0}", i);
            linkObj.transform.SetParent(linkExample.transform.parent);
            linkObj.transform.localPosition = linkExample.transform.localPosition;
            linkObj.transform.localRotation = linkExample.transform.localRotation;
            linkObj.transform.localScale = linkExample.transform.localScale;
            _subLinks[i] = linkObj.AddComponent<WuChangSubLinkController>();
        }

        // 注:使用linkExample作为mainLink
        _mainLink = linkExample.AddComponent<WuChangSubLinkController>();
        _linkParticle.transform.SetParent(_mainLink.transform);
        SetLinkBreak(false);
    }

    public bool SetLinkPosition(Vector3 source, Vector3 target, bool isBreak)
    {
        // 防止未初始化的情况
        if (_mainLink == null)
            return true;
        else
        {
            var result = true;
            if (isBreak != _isBreak)
            {
                SetLinkBreak(isBreak);
                var breakPoint = (source + target) * 0.5f;
                for (var i = 0; i < _breakPoints.Length; i++)
                    _breakPoints[i] = breakPoint;
            }

            if (_isBreak)
            {
                var delta = Time.deltaTime * _breakLinkSpeed;
                result = SetSubLink(0, source, delta) || SetSubLink(1, target, delta);
            }
            else
            {
                _mainLink.sourcePoint = source;
                _mainLink.targetPoint = target;
                _mainLink.TryUpdateLink();
                var emission = _linkParticle.emission;
                emission.rateOverTimeMultiplier = _mainLink.transform.localScale.x * _baseRateOverTime;
                emission.rateOverDistanceMultiplier = _mainLink.transform.localScale.x * _baseRateOverDistance;
            }

            return result;
        }
    }

    private bool SetSubLink(int i, Vector3 source, float delta)
    {
        var subLink = _subLinks[i];
        var result = (source - _breakPoints[i]).sqrMagnitude < delta.ToSquare();
        _breakPoints[i] = result ? source : Vector3.MoveTowards(_breakPoints[i], source, delta);
        subLink.sourcePoint = source;
        subLink.targetPoint = _breakPoints[i];
        subLink.TryUpdateLink();
        return result;
    }

    private void SetLinkBreak(bool isBreak)
    {
        _isBreak = isBreak;
        _mainLink.gameObject.SetActive(!_isBreak);
        var emission = _linkParticle.emission;
        emission.enabled = !_isBreak;
        for (var i = 0; i < _subLinks.Length; i++)
            _subLinks[i].gameObject.SetActive(_isBreak);
    }
}