using UnityEngine;

namespace IndianOceanAssets.Engine2_5D
{
    /// <summary>
    /// 摄像机边界（空气墙）—— 框定摄像机可移动的矩形范围。
    /// 摄像机碰到边界后停下，玩家仍可继续走。
    ///
    /// 原理：在 LateUpdate（晚于 CameraFollow 的 Update）把摄像机位置钳制到
    /// 以本物体为中心、size 为尺寸的矩形内（仅 XZ 平面，Y 不限制）。
    /// [DefaultExecutionOrder(10000)] 保证本脚本在其它 LateUpdate 之后执行，
    /// 即使以后把 CameraFollow 改成 LateUpdate 也能正确钳制。
    ///
    /// 为什么不会抖：
    /// CameraFollow 每帧用 Lerp 把摄像机往目标推（可能推出边界），
    /// 本脚本随后把它钳回边界。边界是固定直线，钳制结果每帧一致 → 稳定不抖。
    ///
    /// 用法：
    /// 1. 场景中创建空物体，挂上此脚本
    /// 2. 把空物体放到摄像机活动范围的中心点
    /// 3. 设置 size（X=宽度，Y=深度，以本物体位置为中心）
    /// 4. targetCamera 留空则自动用 Camera.main
    /// 5. Scene 视图会显示青色线框，方便对齐
    /// </summary>
    [DefaultExecutionOrder(10000)]
    public class CameraBounds : MonoBehaviour
    {
        [Tooltip("要约束的摄像机（留空则使用 Camera.main）")]
        [SerializeField] private Camera targetCamera;

        [Tooltip("边界尺寸（X=宽度，Y=深度，以本物体位置为中心）")]
        [SerializeField] private Vector2 size = new Vector2(30f, 30f);

        [Tooltip("Scene 视图是否显示边界线框")]
        [SerializeField] private bool drawGizmo = true;

        [Tooltip("线框颜色")]
        [SerializeField] private Color gizmoColor = Color.cyan;

        private Transform _camTransform;
        private bool _resolved;

        private void Start()
        {
            ResolveCamera();
        }

        private void ResolveCamera()
        {
            var cam = targetCamera != null ? targetCamera : Camera.main;
            if (cam != null)
            {
                _camTransform = cam.transform;
                _resolved = true;
            }
            else
            {
                _resolved = false;
            }
        }

        private void LateUpdate()
        {
            if (!_resolved || _camTransform == null)
            {
                ResolveCamera();
                if (_camTransform == null) return;
            }

            Vector3 pos = _camTransform.position;
            Vector3 center = transform.position;
            float minX = center.x - size.x * 0.5f;
            float maxX = center.x + size.x * 0.5f;
            float minZ = center.z - size.y * 0.5f;
            float maxZ = center.z + size.y * 0.5f;

            _camTransform.position = new Vector3(
                Mathf.Clamp(pos.x, minX, maxX),
                pos.y,
                Mathf.Clamp(pos.z, minZ, maxZ)
            );
        }

        /// <summary>
        /// 把世界坐标钳制到边界内（仅 XZ，Y 不变）。供外部调用。
        /// </summary>
        public Vector3 ClampPosition(Vector3 pos)
        {
            Vector3 center = transform.position;
            return new Vector3(
                Mathf.Clamp(pos.x, center.x - size.x * 0.5f, center.x + size.x * 0.5f),
                pos.y,
                Mathf.Clamp(pos.z, center.z - size.y * 0.5f, center.z + size.y * 0.5f)
            );
        }

        private void OnDrawGizmos()
        {
            if (!drawGizmo) return;

            Vector3 c = transform.position;
            float hx = size.x * 0.5f;
            float hz = size.y * 0.5f;
            Vector3 p1 = new Vector3(c.x - hx, c.y, c.z - hz);
            Vector3 p2 = new Vector3(c.x + hx, c.y, c.z - hz);
            Vector3 p3 = new Vector3(c.x + hx, c.y, c.z + hz);
            Vector3 p4 = new Vector3(c.x - hx, c.y, c.z + hz);

            Gizmos.color = gizmoColor;
            Gizmos.DrawLine(p1, p2);
            Gizmos.DrawLine(p2, p3);
            Gizmos.DrawLine(p3, p4);
            Gizmos.DrawLine(p4, p1);

            // 中心十字
            Gizmos.color = new Color(gizmoColor.r, gizmoColor.g, gizmoColor.b, 0.6f);
            const float k = 0.5f;
            Gizmos.DrawLine(c - new Vector3(k, 0, 0), c + new Vector3(k, 0, 0));
            Gizmos.DrawLine(c - new Vector3(0, 0, k), c + new Vector3(0, 0, k));
        }
    }
}
