using System;
using UniRx;
using UnityEngine;
using UnityEngine.UI;

namespace MyGame.Scenes.Main.Scripts
{
    public enum CookState
    {
        Ready,
        Progress,
        Complete
    }
    public class AutoCookView : MonoBehaviour
    {
        [SerializeField] private Animator cookAnimator;
        [SerializeField] private GameObject[] progressImages;
        [SerializeField] private Button autoCookButton;
        [SerializeField] private Transform buttonTarget;
        [SerializeField] private GameObject notifyIcon;
        
        public IObservable<Unit> Button => autoCookButton.OnClickAsObservable().TakeUntilDestroy(this);
        private IDisposable timerDisposable;

        private void Start()
        {
            Observable.TimerFrame(0, FrameCountType.Update).Subscribe(_ =>
            {
                var screenPos = Camera.main.WorldToScreenPoint(buttonTarget.position);
                var graphic = autoCookButton.image.GetComponent<Graphic>();
                var camera = graphic.canvas.worldCamera;
                if (graphic.canvas.renderMode == RenderMode.ScreenSpaceOverlay)
                {
                    camera = null;
                }

                RectTransformUtility.ScreenPointToWorldPointInRectangle(graphic.rectTransform, screenPos, camera,
                    out var buttonPos);
                autoCookButton.transform.position = buttonPos;
            }).AddTo(this);
        }

        public void Initialize()
        {
            Ready();
        }

        public void Ready()
        {
            cookAnimator.enabled = false;
            SetProgress(0f);
        }

        public void CheckNotify()
        {
            notifyIcon.SetActive(CheckComplete());
        }

        public static bool CheckComplete()
        {
            var gameData = GameDataManager.GameData;
            var remainingTime = DateTime.FromBinary(gameData.AutoCookFinishTime).Subtract(DateTime.UtcNow);
            return gameData.AutoCookProducts.Length != 0 && remainingTime.TotalSeconds <= 0;
        }

        public void SetActive(bool active)
        {
            autoCookButton.gameObject.SetActive(active);
            gameObject.SetActive(active);
        }

        private void SetProgress(float value)
        {
            // Debug.Log($"setprogress:{value}");
            var border = Mathf.FloorToInt(progressImages.Length * Mathf.Clamp01(value));
            for (var i = 0; i < progressImages.Length; i++)
            {
                progressImages[i].SetActive(i + 1 == border);
            }
        }

        public void ResetTimer(int remainingTime, int duration)
        {
            cookAnimator.enabled = true;
            SetProgress(1f - (float)remainingTime/duration);
            // タイマーの更新処理
            timerDisposable?.Dispose();
            timerDisposable = Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(1f))
                .Select(x => (int)(remainingTime - x))
                .TakeWhile(x => x > 0)
                .Subscribe(x =>
                {
                    SetProgress(1f - (float)x/duration);
                }, () =>
                {
                    cookAnimator.enabled = false;
                }).AddTo(this);
        }

        public void ShowDialog(CookState state, Action onClose = null)
        {
            switch (state)
            {
                case CookState.Ready:
                    AutoCookDialog.ShowDialog(onClose);
                    break;
                case CookState.Progress:
                    AutoCookProgressView.ShowDialog();
                    break;
                case CookState.Complete:
                    AutoCookCompleteView.ShowDialog(onClose);
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }
    }
}