using System;
using System.Linq;
using I2.Loc;
using UniRx;
using UnityEngine;
using UnityEngine.UI;

namespace MyGame.Scenes.Main.Scripts
{
    public class AutoCookProgressView : MonoBehaviour
    {
        private static readonly string CallbackTag = "AutoCoolProgressCallback";
        private static readonly int OpenTrigger = Animator.StringToHash("OpenTrigger");
        private static readonly int CloseTrigger = Animator.StringToHash("CloseTrigger");

        [SerializeField] private Animator backgroundAnimator;
        [SerializeField] private Button closeButton;
        
        [SerializeField] private Text progressText;
        [SerializeField] private Animator cookAnimator;
        [SerializeField] private Transform progressImage;
        [SerializeField] private float minProgressYPos;
        [SerializeField] private float maxProgressYPos;
        
        private IDisposable timerDisposable;

        private void Start()
        {
            var gameData = GameDataManager.GameData;
            var autoCookDataList = SpreadsheetDataManager.Instance.GetBaseDataList<AutoCookData>(Const.AutoCookDataSheet);
            var autoCookData = autoCookDataList.First(data => data.level == gameData.AutoCookLevel);
            var remainingTime = DateTime.FromBinary(gameData.AutoCookFinishTime).Subtract(DateTime.UtcNow);

            closeButton.OnClickAsObservable().Take(1).Subscribe(_ =>
            {
                LocalCacheManager.Load<Action>(CallbackTag, null)?.Invoke();
                LocalCacheManager.Remove(CallbackTag);
                transform.parent.SetLocalScale(0);
                backgroundAnimator.SetTrigger(CloseTrigger);
                this.CallWaitForSeconds(.25f, () =>
                {
                    TransitionManager.Instance.UnloadScene(GameScenes.AutomaticCookingConfirmation);
                });
            }).AddTo(this);

            ResetTimer((int)remainingTime.TotalSeconds, (int)TimeSpan.FromHours(autoCookData.duration).TotalSeconds);
        }

        private void SetProgressImage(float value)
        {
            var yPos = Mathf.Lerp(minProgressYPos, maxProgressYPos, value);
            progressImage.localPosition = progressImage.localPosition.SetY(yPos);
        }

        private void SetTime(int seconds)
        {
            progressText.text = $"{ScriptLocalization.UI.RemainingTime}{TimeSpan.FromSeconds(seconds):g}";
        }
        
        private void ResetTimer(int remainingTime, int duration)
        {
            // タイマーの更新処理
            timerDisposable?.Dispose();
            SetTime(remainingTime);
            SetProgressImage(1f - (float)remainingTime/duration);
            timerDisposable = Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(1f))
                .Select(x => (int)(remainingTime - x))
                .TakeWhile(x => x > 0)
                .Subscribe(x =>
                {
                    SetTime(x);
                    SetProgressImage(1f - (float)x/duration);
                }, () =>
                {
                    cookAnimator.enabled = false;
                }).AddTo(this);
        }
        
        public static void ShowDialog(Action onClose = null){
            LocalCacheManager.Save(CallbackTag, onClose);
            TransitionManager.Instance.LoadSceneAdditive(GameScenes.AutomaticCookingConfirmation);
        }
    }
}