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

public class Title : MonoBehaviour
{
    [SerializeField] private FloatReactiveProperty customerInterval = new FloatReactiveProperty(1f);
    [Space]
    [SerializeField] private GameObject startObject;
    [SerializeField] private CustomerData customerData;
    [SerializeField] private CustomerController customerControllerPrefab;
    // Start is called before the first frame update
    void Start()
    {
        // 実機でアプリ初回起動時にBGMならないの回避。1フレーム遅らせると鳴る
        Observable.NextFrame().Subscribe(_ => SoundManager.Instance.PlayBGM("bgm_Main"));
        startObject.SetActive(false);
        this.CallWaitForSeconds(1.1f, () =>
        {
            startObject.SetActive(true);
            this.CallWaitForSeconds(1f, () =>
            {
                this.UpdateAsObservable()
                    .Select(_ => Input.GetMouseButton(0))
                    .DistinctUntilChanged()
                    .Skip(1)
                    .Take(1)
                    .Subscribe(_ =>
                    {
                        SoundManager.Instance.PlaySE("se_ButtonTap");
                        this.CallWaitForSeconds(.25f, () =>
                        {
                            TransitionManager.Instance.LoadScene(GameScenes.Main);
                        });
                    }).AddTo(this);
            });
        });
        
        // お客さん
        customerInterval.Select(f => 
            Observable.Interval(TimeSpan.FromSeconds(f)))
            .Switch()
            .Subscribe(t =>
            {
                // 一般客orセレブ
                var (isSpecial, orderCount) = Market.GetCustomerData(false);
    
                // 複数パターンある場合ChooseRandom
                var prefab = isSpecial ? customerData.ChooseSpecialPrefab() : customerData.ChooseNormalPrefab();
                var customerController = Instantiate(customerControllerPrefab, transform);
            
                customerController.MoveEndObservable
                    .SkipLatestValueOnSubscribe()
                    .DistinctUntilChanged()
                    .Subscribe(prevMovingType =>
                    {
                        switch (prevMovingType)
                        {
                            case CustomerMovingType.WalkSide:
                            case CustomerMovingType.WalkSideEat:
                                Destroy(customerController.gameObject);
                                break;
                            default:
                                break;
                        }
                    }).AddTo(customerController);
                customerController.Setup(new List<Transform>{transform});
                customerController.OrderCount = orderCount;
                customerController.CustomerPrefab = prefab;
                customerController.ChangeCustomerState(CustomerState.Walk);
                
                var customerObject = new GameObject();
                customerObject.transform.parent = transform;
                customerObject.transform.localPosition = customerController.transform.localPosition;
                // controllerが破棄のタイミングでこちらも破棄
                customerController.OnDestroyAsObservable().Subscribe(_ =>
                {
                    Destroy(customerObject);
                }).AddTo(customerObject);
                // customer位置同期
                this.UpdateAsObservable().Subscribe(_ =>
                {
                    customerObject.transform.localPosition = customerController.transform.localPosition;
                }).AddTo(customerObject);
            
                var customerAnimator = Instantiate(customerController.CustomerPrefab, customerObject.transform);
                customerController.CurrentMovingType.Subscribe(x =>
                {
                    customerAnimator.SetTrigger(x);
                }).AddTo(customerAnimator);
                customerController.IsDefaultSide.Subscribe(x =>
                {
                    customerAnimator.SetSide(x);
                }).AddTo(customerAnimator);
            }).AddTo(this);
    }
}
