using DG.Tweening;
using ET.EventType;
using FairyGUI;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;

namespace ET.Client
{
    public static class CameraMgr
    {
        public static Camera MainCamera { get; private set; }

        private static Dictionary<string, UnityEngine.Object> Name_BindObj = new Dictionary<string, UnityEngine.Object>();
        private static PlayableDirector Director;
        private static readonly string StartPlayableName = "Camera02";
        private static System.Action StopCallback = null;

        public static void Init()
        {
            MainCamera = Camera.main;
            MainCamera.transform.SetPositionAndRotation(new Vector3(90, 35, 26.6f), Quaternion.Euler(20, 20, 0));
            MainCamera.fieldOfView = 60;

            var light = GameObject.Find("/Light");
            if (light != null)
            {
                light.transform.rotation = Quaternion.Euler(0, 20, 0);
            }

            if (Director == null)
            {
                Director = MainCamera.GetComponent<PlayableDirector>();
                if (Director == null)
                {
                    Log.Error("Not Found Camera PlayableDirector");
                    return;
                }
                if (Name_BindObj.Count == 0)
                {
                    foreach (var bind in Director.playableAsset.outputs)
                    {
                        var obj = Director.GetGenericBinding(bind.sourceObject);
                        Name_BindObj.Add(bind.streamName, obj);
                    }
                }

                Director.stopped += (pd) =>
                {
                    StopCallback?.Invoke();
                    StopCallback = null;
                };
            }
        }

        [Event]
        public class CameraPlaybleEventHandler : BEvent<CameraPlaybleEvent>
        {
            protected override async ETTask OnEvent(CameraPlaybleEvent a)
            {
                bool flag = GlobalViewMgr.Instance.HeadbarView.visible;
                if (flag)
                {
                    GlobalViewMgr.Instance.HeadbarView.visible = false;
                }
                await PlayTimeline(a.Playable, () =>
                {
                    if (flag)
                    {
                        GlobalViewMgr.Instance.HeadbarView.visible = true;
                    }

                    if (a.Playable == "Camera1_2")
                    {
                        var light = GameObject.Find("/Light");
                        light.transform.rotation = Quaternion.Euler(0, 225, 0);
                        EventSystem.Instance.Publish(BattleFunc.Clone((int)BattleFunc.FUNC.Start2));
                    }
                    else if (a.Playable == "Camera2_3")
                    {
                        var light = GameObject.Find("/Light");
                        light.transform.rotation = Quaternion.Euler(0, 178, 0);
                        EventSystem.Instance.Publish(BattleFunc.Clone((int)BattleFunc.FUNC.Start3));
                    }
                });
            }
        }

        public static async ETTask PlayTimeline(string timeline, System.Action cb)
        {
            var task = await YooAssetProxy.LoadAssetAsync<PlayableAsset>($"Playable_{timeline}");
            var asset = task.GetAssetObject<PlayableAsset>();
            Director.playableAsset = asset;
            foreach (var bind in asset.outputs)
            {
                if (Name_BindObj.TryGetValue(bind.streamName.ToString(), out var bindObj))
                {
                    Director.SetGenericBinding(bind.sourceObject, bindObj);
                }
            }

            StopCallback = cb;
            Director.Play();
        }

        public static async ETTask PlayStartAnimation(System.Action cb)
        {
            await PlayTimeline(StartPlayableName, cb);
        }

        //相机跟随主角
        public static void FollowMe(Vector3 pos)
        {
            /*var camera = Camera.main;
            pos.x += 7;
            pos.y = 15;
            pos.z -= 25;
            camera.transform.position = pos;*/
        }

        private static bool bShaking = false;
        public static void ShakeMe(float shakeTime, Vector3 shakeStength)
        {
            if (bShaking) return;
            bShaking = true;

            Transform trans = MainCamera.transform;
            var savePos = trans.localPosition;
            Tweener tweener = trans.DOShakePosition(shakeTime, shakeStength);
            tweener.OnComplete<Tweener>(() =>
            {
                trans.localPosition = savePos;
                bShaking = false;
            });
        }

        public static Vector3 CarmeraPos()
        {
            return Camera.main.transform.position;
        }

        public static void DragMe(Vector3 start, Vector3 end, float duration, System.Action endcb)
        {
            Transform trans = MainCamera.transform;
            trans.position = start;
            var tweener = trans.DOMove(end, duration);
            tweener.OnComplete<Tweener>(() =>
            {
                endcb ?.Invoke();
            });
        }
    }

    [Event]
    public class CameraEventHandler : BEvent<CameraEvent>
    {
        protected override async ETTask OnEvent(CameraEvent args)
        {
            var endpos = new Vector3(args.X, args.Y, args.Z);
            float time = (float)args.TimeMS / 1000;
            Transform trans = CameraMgr.MainCamera.transform;

            if (args.MoveSpeedSec > 0.0001 && time < 0.01)
            {
                var dis = Vector3.Distance(trans.position, endpos);
                time = dis / args.MoveSpeedSec;
            }
            trans.DOMove(endpos, time);
            await ETTask.CompletedTask;
        }
    }

}