using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using Thousandto.Core.Asset;
using PathEditor.Proxy.Plugin;
using System.IO;
using Thousandto.Core.Base;
using UnityEngine.SceneManagement;
using Thousandto.Cfg.Data;
using Thousandto.Launcher.ExternalLibs;

public class PreviewSceneEditor : EditorWindow
{
    [MenuItem("Ares/场景预览")]
    static void Open()
    {
        if (!Application.isPlaying)
        {
            EditorUtility.DisplayDialog("提示", "播放状态下才能打开预览器!", "确定");
            return;
        }

        var win = (PreviewSceneEditor)EditorWindow.GetWindow(typeof(PreviewSceneEditor), true);
        win.Show();
    }

    private List<MeshCollider> _collider = new List<MeshCollider>();
    private GameObject _cameraGo = null;
    private PreviewSceneCamera _cameraCol = null;
    private GameObject _playerGo = null;
    private AnimationPlayer _playerAnim = null;
    private float _syncTime = 0f;
    private Ray _hitRay = new Ray();
    private bool wDown = false;
    private bool sDown = false;
    private bool aDown = false;
    private bool dDown = false;
    private bool _isMoving = false;
    private Vector3 _moveDir = Vector3.zero;
    private bool _useGirdData = false;
    private PathGirdData _gridData = null;

    private void OnEnable()
    {
        _collider.Clear();
        var sceneRoot = GameObject.Find("SceneRoot");
        if (sceneRoot == null)
        {
            UnityEngine.Debug.LogError("场景错误,找不到SceneRoot节点!");
            return;
        }
        var meshs = sceneRoot.GetComponentsInChildren<MeshFilter>();
        for (int i = 0; i < meshs.Length; ++i)
        {
            if (meshs[i].gameObject.layer == LayerUtils.TerrainMesh || meshs[i].gameObject.layer == LayerUtils.Terrain)
            {
                var col = meshs[i].gameObject.AddComponent<MeshCollider>();
                _collider.Add(col);
            }
        }

        var filePath = FileUtils.MapInfoDirPath + '/' + SceneManager.GetActiveScene().name + "_PathGrid.bytes";
        if (File.Exists(filePath))
        {
            _gridData = new PathGirdData();
            UnityEngine.Gonbest.MagicCube.FFileReader.ReadBytesAsync(filePath, bytes => {
                if (bytes != null)
                {
                    _gridData.Load(bytes);
                }
            });
        }
        else
        {
            _gridData = null;
        }

        if (_cameraGo != null && _cameraGo.name != "[Cameras]")
        {
            GameObject.DestroyImmediate(_cameraGo);
            _cameraGo = null;
        }

        var preCamera = sceneRoot.transform.Find("[Cameras]");
        if (preCamera != null)
        {
            _cameraGo = preCamera.gameObject;
        }
        else
        {
            _cameraGo = new GameObject("CameraRoot");
            var camera = _cameraGo.RequireComponent<Camera>();
            camera.cullingMask = ~LayerUtils.UI_Mask;
            camera.clearFlags = CameraClearFlags.Skybox;
        }
        _cameraCol = new PreviewSceneCamera();
        _cameraCol.TransformInst = _cameraGo.transform;

        var res = Resources.Load("Prefab/Player/player_0/player_001");
        _playerGo = GameObject.Instantiate(res) as GameObject;
        var anim = UnityUtils.RequireComponent<AnimListBaseScript>(_playerGo);
        anim.AddClips(AnimInfo.GetClips(anim.AnimAssetPathDic.Values));
        _playerAnim = new AnimationPlayer(anim);
        _syncTime = Time.realtimeSinceStartup;
        _playerGo.transform.position = Vector3.zero;
        _cameraCol.TargetTrans = _playerGo.transform;
    }

    private void OnDestroy()
    {
        for (int i = 0; i < _collider.Count; ++i)
        {
            GameObject.DestroyImmediate(_collider[i]);
        }
        _collider.Clear();

        if (_cameraGo != null && _cameraGo.name != "[Cameras]")
        {
            GameObject.DestroyImmediate(_cameraGo);
            _cameraGo = null;
        }
        _cameraCol = null;
        _gridData = null;
    }

    private void Update()
    {
        if (!Application.isPlaying)
        {
            Close();
            return;
        }
        var dt = Time.realtimeSinceStartup - _syncTime;
        _syncTime = Time.realtimeSinceStartup;

        if (_cameraCol != null)
        {
            _cameraCol.Update();
        }
        if (_playerAnim != null)
        {
            _playerAnim.Update(dt);
        }

        var playerPos = _playerGo.transform.position;
        if (_isMoving)
        {
            playerPos += _moveDir * 10f * dt;
            _playerGo.transform.forward = _moveDir;

            if (!_playerAnim.IsPlaying)
            {
                _playerAnim.Play(AnimClipNameDefine.NormalRun, AnimationPartType.AllBody, WrapMode.Loop);
            }
        }
        else
        {
            if (!_playerAnim.IsPlaying)
            {
                _playerAnim.Play(AnimClipNameDefine.NormalIdle, AnimationPartType.AllBody, WrapMode.Loop);
            }
        }

        if (_useGirdData && _gridData != null)
        {
            playerPos.y = _gridData.GetHeight(playerPos.x, playerPos.z);
        }
        else
        {
            _hitRay.origin = new Vector3(playerPos.x, 1000f, playerPos.z);
            _hitRay.direction = Vector3.down;

            RaycastHit hitInfo;
            if (Physics.Raycast(_hitRay, out hitInfo, 1000f, LayerUtils.Terrain_Mask))
            {
                playerPos.y = hitInfo.point.y;
            }
            else
            {
                playerPos.y = 0f;
            }
        }
        _playerGo.transform.position = playerPos;


    }

    private void OnGUI()
    {
        switch (Event.current.type)
        {
            case EventType.KeyDown:
                {
                    if (Event.current.keyCode == KeyCode.W)
                    {
                        wDown = true;
                        Event.current.Use();
                    }
                    if (Event.current.keyCode == KeyCode.S)
                    {
                        sDown = true;
                        Event.current.Use();
                    }
                    if (Event.current.keyCode == KeyCode.A)
                    {
                        aDown = true;
                        Event.current.Use();
                    }
                    if (Event.current.keyCode == KeyCode.D)
                    {
                        dDown = true;
                        Event.current.Use();
                    }
                }
                break;
            case EventType.KeyUp:
                {
                    if (Event.current.keyCode == KeyCode.W)
                    {
                        wDown = false;
                        Event.current.Use();
                    }
                    if (Event.current.keyCode == KeyCode.S)
                    {
                        sDown = false;
                        Event.current.Use();
                    }
                    if (Event.current.keyCode == KeyCode.A)
                    {
                        aDown = false;
                        Event.current.Use();
                    }
                    if (Event.current.keyCode == KeyCode.D)
                    {
                        dDown = false;
                        Event.current.Use();
                    }
                }
                break;
        }

        if (wDown || sDown || aDown || dDown)
        {
            var frontDir = _playerGo.transform.position - _cameraGo.transform.position;
            frontDir.y = 0;
            frontDir = frontDir.normalized;
            float angle = 0f;
            if (wDown && aDown)
            {
                angle = -45f;
            }
            else if (wDown && dDown)
            {
                angle = 45f;
            }
            else if (sDown && aDown)
            {
                angle = -135f;
            }
            else if (sDown && dDown)
            {
                angle = 135f;
            }
            else if (wDown)
            {
                angle = 0f;
            }
            else if (sDown)
            {
                angle = 180f;
            }
            else if (aDown)
            {
                angle = -90f;
            }
            else if (dDown)
            {
                angle = 90f;
            }
            _moveDir = (Quaternion.AngleAxis(angle, Vector3.up) * frontDir).normalized;
            if (!_isMoving)
            {
                _isMoving = true;
                _playerAnim.Play(AnimClipNameDefine.NormalRun, AnimationPartType.AllBody, WrapMode.Loop);
            }
        }
        else
        {
            if (_isMoving)
            {
                _playerAnim.Play(AnimClipNameDefine.NormalIdle, AnimationPartType.AllBody, WrapMode.Loop);
                _isMoving = false;
            }
        }
        if (_cameraCol != null)
        {
            EditorGUILayout.BeginHorizontal();
            _cameraCol.CurPitch = EditorGUILayout.FloatField("CurPitch", _cameraCol.CurPitch);
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            _cameraCol.CurYaw = EditorGUILayout.FloatField("CurYaw", _cameraCol.CurYaw);
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            _cameraCol.CurDis = EditorGUILayout.FloatField("CurDis", _cameraCol.CurDis);
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            _cameraCol.CurOffsetY = EditorGUILayout.FloatField("CurOffsetY", _cameraCol.CurOffsetY);
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            _cameraCol.CurOffsetX = EditorGUILayout.FloatField("CurOffsetX", _cameraCol.CurOffsetX);
            EditorGUILayout.EndHorizontal();

            if (_gridData != null)
            {
                EditorGUILayout.BeginHorizontal();
                _useGirdData = EditorGUILayout.Toggle("使用高度数据", _useGirdData);
                EditorGUILayout.EndHorizontal();
            }
        }
    }
}