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

public class BrotherConversation : MonoBehaviour
{
    public static readonly string ScriptDataTag = "BrotherConversationScriptData";
    public static readonly string CallbackTag = "BrotherConversationCallback";
    private static readonly int OpenTrigger = Animator.StringToHash("OpenTrigger");
    private static readonly int CloseTrigger = Animator.StringToHash("CloseTrigger");
    
    [SerializeField] private Animator backgroundAnimator;
    [SerializeField] private Animator brotherBlueAnimator;
    [SerializeField] private Animator brotherPinkAnimator;
    [SerializeField] private Transform brotherBlueTarget;
    [SerializeField] private Transform brotherPinkTarget;
    [SerializeField] private Transform brotherBlueBothTarget;
    [SerializeField] private Transform brotherPinkBothTarget;
    [SerializeField] private GameObject blueNameObject;
    [SerializeField] private GameObject pinkNameObject;
    [SerializeField] private GameObject bothNameObject;
    [SerializeField] private Text brotherText;

    private void Start()
    {
        var targetScriptList = LocalCacheManager.Load<List<BrotherScriptData>>(ScriptDataTag);

        var clickCountStream = this.UpdateAsObservable()
            .Select(_ => Input.GetMouseButton(0))
            .DistinctUntilChanged()
            .Pairwise()
            .Where(pair => pair.Previous && !pair.Current)
            .ThrottleFirst(TimeSpan.FromSeconds(.1f))
            .Select(_ => 1)
            .Scan((i, i1) => i + i1);

        clickCountStream
            .TakeWhile(x => x < targetScriptList.Count)
            .Select(x => targetScriptList[x])
            .Subscribe(data =>
            {
                SoundManager.Instance.PlaySE("se_ButtonTap");
                SetData(data);
            }, () =>
            {
                transform.SetLocalScale(0);
                backgroundAnimator.SetTrigger(CloseTrigger);
                this.CallWaitForSeconds(.25f, () =>
                {
                    LocalCacheManager.Load<Action>(CallbackTag, null)?.Invoke();
                    LocalCacheManager.Remove(CallbackTag);
                    TransitionManager.Instance.UnloadScene(GameScenes.Conversation);
                });
            }).AddTo(this);

        SetData(targetScriptList[0]);
    }

    private void SetData(BrotherScriptData scriptData)
    {
        brotherText.text = scriptData.Text;
        switch (scriptData.Brother)
        {
            case BrotherType.Blue:
                brotherBlueAnimator.SetTrigger(scriptData.BlueFace.ToString());
                brotherPinkAnimator.SetTrigger(PinkFaceType.Normal.ToString());
                brotherBlueAnimator.transform.localPosition = brotherBlueTarget.localPosition;
                brotherBlueAnimator.transform.SetLocalScale(1f);
                brotherPinkAnimator.transform.SetLocalScale(0f);
                blueNameObject.SetActive(true);
                pinkNameObject.SetActive(false);
                bothNameObject.SetActive(false);
                break;
            case BrotherType.Pink:
                brotherBlueAnimator.SetTrigger(BlueFaceType.Normal.ToString());
                brotherPinkAnimator.SetTrigger(scriptData.PinkFace.ToString());
                brotherPinkAnimator.transform.localPosition = brotherPinkTarget.localPosition;
                brotherBlueAnimator.transform.SetLocalScale(0f);
                brotherPinkAnimator.transform.SetLocalScale(1f);
                blueNameObject.SetActive(false);
                pinkNameObject.SetActive(true);
                bothNameObject.SetActive(false);
                break;
            case BrotherType.Both:
                brotherBlueAnimator.SetTrigger(scriptData.BlueFace.ToString());
                brotherPinkAnimator.SetTrigger(scriptData.PinkFace.ToString());
                brotherBlueAnimator.transform.localPosition = brotherBlueBothTarget.localPosition;
                brotherPinkAnimator.transform.localPosition = brotherPinkBothTarget.localPosition;
                brotherBlueAnimator.transform.SetLocalScale(1f);
                brotherPinkAnimator.transform.SetLocalScale(1f);
                blueNameObject.SetActive(false);
                pinkNameObject.SetActive(false);
                bothNameObject.SetActive(true);
                break;
            default:
                throw new ArgumentOutOfRangeException();
        }
    }
}
