using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UniRx;
using UniRx.Triggers;

[RequireComponent(typeof(Selectable))]
public class SyncButtonColor : MonoBehaviour {

    private Selectable selectable;
    private float fadeDuration;
    private Dictionary<Graphic, Color> graphicDefaultColorMap = new Dictionary<Graphic, Color>();
    private List<Coroutine> coroutineList = new List<Coroutine>();

    void Awake(){
        selectable = GetComponent<Selectable>();
        if(selectable.transition != Selectable.Transition.ColorTint) return ;

        fadeDuration = selectable.colors.fadeDuration;

        transform.FindAllChildrensComponent<Graphic>(graphic => graphicDefaultColorMap.Add(graphic, graphic.color));

        this.LateUpdateAsObservable()
        .Select(_ => selectable.interactable)
        .DistinctUntilChanged()
        .Skip(1)
        .Subscribe(ChangeInteractable);
    }

    void Start(){
        // OnEnableが他のAwakeより先に呼ばれる事がある為Startでも呼ぶ
        OnEnable();
    }

    void OnEnable(){
        if(selectable.transition != Selectable.Transition.ColorTint) return ;

        if(!selectable.interactable){
            ImmediateChangeDisabledColor();
        }
    }

    private void ChangeInteractable(bool interactable){
        foreach(var coroutine in coroutineList){
            this.SafeStopCoroutine(coroutine);
        }
        coroutineList.Clear();

        if(interactable){
            ChangeDefaultColor();
        }else{
            ChangeDisabledColor();
        }
    }

    private void ImmediateChangeDisabledColor(){
        Color syncedColor = selectable.colors.disabledColor;
        foreach(var kvp in graphicDefaultColorMap){
            kvp.Key.color = kvp.Value * syncedColor;
        }
    }
    private void ChangeDisabledColor(){
        Color syncedColor = selectable.colors.disabledColor;
        foreach(var kvp in graphicDefaultColorMap){
            Color fromColor = kvp.Key.color;
            Color targetColor = fromColor * syncedColor;
            var coroutine = this.CallLerpSmooth(fadeDuration, t => {
                kvp.Key.color = Color.Lerp(fromColor, targetColor, t);
            });
            coroutineList.Add(coroutine);
        }
    }
    private void ChangeDefaultColor(){
        if(coroutineList.Count > 0){
            coroutineList.ForEach(coroutine => StopCoroutine(coroutine));
            coroutineList.Clear();
        }
        foreach(var kvp in graphicDefaultColorMap){
            Color fromColor = kvp.Key.color;
            Color targetColor = kvp.Value;
            var coroutine = this.CallLerpSmooth(fadeDuration, t => {
                kvp.Key.color = Color.Lerp(fromColor, targetColor, t);
            });
            coroutineList.Add(coroutine);
        };
    }
}
