using System;
using UnityEngine;
using WaveHarmonic.Crest;

[ExecuteInEditMode]
[RequireComponent(typeof(Rigidbody))]
public class Buoyancy : MonoBehaviour
{
    // public WaterSurface targetSurface;
    public WaterRenderer _water;
    
    [Tooltip("物体浮力的近似半径")] public float sphereRadiusApproximation = 0.25f;

    [Tooltip("指定由其他变形（波浪、涌浪等）引起的运动乘数。")] public float waveForceMultiplier = 1f;

    [Tooltip("指定由水面水流引起的移动的乘数。")] public float currentSpeedMultiplier = 1f;

    [Tooltip("指定由介质黏性所引起的阻力的乘数。")] public float dragMultiplier = 1f;

    public float defaultRigidbodyDrag = 0.1f;

    public float underwaterRigidbodyAngularDrag = 1f;

    public float overwaterRigidbodyAngularDrag = 0.05f;

    [Tooltip("指定表面张力的数值。数值过高时，物体在水面上弹跳的速度会减慢。")]
    public float surfaceTensionDamping = 10f;

    [Tooltip("启用后，净力会以随机偏移量施加出来，从而产生角速度。")]
    public bool applyForceWithRandomOffset;

    [Tooltip("启用调试绘制")] public bool drawDebug;

    private Vector3 currentDirection;


    private Vector3 waterPosition;

    private Vector3 normal;

    private Vector3 deformationDirection;

    private Rigidbody rigidbodyComponent;

    private float h;

    private float hNormalized;

    private bool _isEnabled = true;

    readonly SampleFlowHelper _SampleFlowHelper = new();

    private void Start()
    {
        rigidbodyComponent = GetComponent<Rigidbody>();
        rigidbodyComponent.useGravity = false;
        rigidbodyComponent.linearDamping = defaultRigidbodyDrag;
        if (_water == null)
        {
            Debug.LogWarning("没有找到水组件");
        }
    }

    public void EnablePhysics(bool set)
    {
        _isEnabled = set;
    }

    private void FixedUpdate()
    {
        if (!_isEnabled)
        {
            h = 0f;
            hNormalized = 0f;
            rigidbodyComponent.useGravity = true;
            return;
        }

        if (_water == null)
            return;

        rigidbodyComponent.useGravity = false;

        // 缓存常用值
        Vector3 pos = transform.position;
        Vector3 velocity = rigidbodyComponent.linearVelocity;
        float radius = sphereRadiusApproximation;
        float diameter = 2f * radius;

        // 1) 当前位置的水面示例图
        FetchWaterSurfaceData(pos, out waterPosition, out normal, out currentDirection);

        // 水平“波浪推动”方向源自表面法线
        deformationDirection = Vector3.ProjectOnPlane(normal, Vector3.up);

        // 2) 近似球体的浸没深度（0 至 2R）
        float bottomY = pos.y - radius;
        h = Mathf.Clamp(waterPosition.y - bottomY, 0f, diameter);
        hNormalized = (diameter > 0f) ? (h / diameter) : 0f;

        // 3) 浸没体积（球冠形） V(h) = πh²/3 * (3R - h)
        float submergedVolume = MathF.PI * h * h / 3f * (3f * radius - h);

        // 4)角向阻尼从空气状态转变为水状态
        rigidbodyComponent.angularDamping = Mathf.Lerp(
            overwaterRigidbodyAngularDrag,
            underwaterRigidbodyAngularDrag,
            hNormalized
        );

        // 5) 力（保持与您原始的数学计算/单位一致）
        Vector3 gravityAcceleration = Physics.gravity;

        // 注意：保持原样（先将加速度和力相加，然后使用加速度模式）
        Vector3 weightVector = rigidbodyComponent.mass * gravityAcceleration;
        Vector3 gravityTerm = Vector3.Lerp(gravityAcceleration, weightVector, hNormalized);

        // 物理常数（与原文相同）
        const float rhoWater = 997f; // kg/m^3
        const float rhoAir = 0.001293f; // kg/m^3
        const float muAir = 0.0000181f; // Pa·s
        const float muWater = 0.001f; // Pa·s
        const float dragCoefficient = 0.47f;

        // 浮力: -ρ * V * g
        Vector3 buoyancyTerm = (-rhoWater) * submergedVolume * gravityAcceleration;

        // 线性粘性阻力（类似斯托克斯效应）：6πRμ(-v) -> 通过浸入使空气/水混合
        Vector3 dragAir = MathF.PI * 6f * radius * muAir * (-velocity);
        Vector3 dragWater = MathF.PI * 6f * radius * muWater * (-velocity);
        Vector3 viscousDragTerm = Vector3.Lerp(dragAir, dragWater, hNormalized) * dragMultiplier;

        // 合力（仍被视为加速度）
        Vector3 netAcceleration = gravityTerm + buoyancyTerm + viscousDragTerm;

        // 可选的随机偏移量，用于产生角速度
        Vector3 randomOffset = Vector3.zero;
        if (applyForceWithRandomOffset)
        {
            randomOffset = new Vector3(
                UnityEngine.Random.Range(-1f, 1f),
                UnityEngine.Random.Range(-1f, 1f),
                UnityEngine.Random.Range(-1f, 1f)
            ) * (radius / 5f);
        }

        rigidbodyComponent.AddForceAtPosition(
            netAcceleration,
            pos + randomOffset,
            ForceMode.Acceleration
        );

        // 6) 仅在表面过渡区域（0 < hN < 1）存在额外的力作用。
        if (hNormalized > 0f && hNormalized < 1f)
        {
            Vector3 gravityDir = gravityAcceleration.normalized;

            // 表面张力阻尼：抵消沿重力方向的速度
            Vector3 verticalVelocity = Vector3.Dot(velocity, gravityDir) * gravityDir;
            Vector3 surfaceTensionAccel = -verticalVelocity * surfaceTensionDamping;

            rigidbodyComponent.AddForce(surfaceTensionAccel, ForceMode.Acceleration);
            rigidbodyComponent.AddForce(deformationDirection * waveForceMultiplier, ForceMode.Acceleration);
            rigidbodyComponent.AddForce(currentDirection * currentSpeedMultiplier, ForceMode.Acceleration);
        }

        // 7) 终端速度夹具（公式相同，只是命名不同）
        float area = MathF.PI * radius * radius;
        float g = -gravityAcceleration.y; // positive value

        float terminalVelocityInAir = Mathf.Sqrt(2f * rigidbodyComponent.mass * g / (rhoAir * area * dragCoefficient));
        float terminalVelocityInWater =
            Mathf.Sqrt(2f * rigidbodyComponent.mass * g / (rhoWater * area * dragCoefficient));
        float terminalVelocity = Mathf.Lerp(terminalVelocityInAir, terminalVelocityInWater, hNormalized);

        float speed = rigidbodyComponent.linearVelocity.magnitude;
        if (speed > terminalVelocity && speed > 1e-6f)
        {
            rigidbodyComponent.linearVelocity = rigidbodyComponent.linearVelocity / speed * terminalVelocity;
        }
    }

    private Vector3 FetchWaterSurfaceData(Vector3 point, out Vector3 positionWS, out Vector3 normalWS,
        out Vector3 currentDirectionWS)
    {
        currentDirectionWS = Vector3.zero;
        positionWS = Vector3.zero;
        normalWS = Vector3.up;
        return point;
    }

    public Vector3 GetCurrentWaterPosition()
    {
        return waterPosition;
    }


    public float GetNormalizedHeightOfSphereBelowSurface()
    {
        return hNormalized;
    }

    private void OnDrawGizmosSelected()
    {
        if (drawDebug)
        {
            Gizmos.color = Color.magenta;
            Gizmos.DrawLine(base.transform.position, base.transform.position + normal);
            Gizmos.color = Color.green;
            Gizmos.DrawLine(base.transform.position, base.transform.position + deformationDirection * 10f);
            Gizmos.color = Color.red;
            Gizmos.DrawLine(base.transform.position, base.transform.position + currentDirection);
            Gizmos.color = Color.yellow;
            Gizmos.DrawSphere(base.transform.position, sphereRadiusApproximation);
            
            // 绘制 Rigidbody 的重心点位
            Vector3 centerOfMassWorld = transform.TransformPoint(rigidbodyComponent != null ? rigidbodyComponent.centerOfMass : Vector3.zero);
            Gizmos.color = Color.cyan;
            Gizmos.DrawSphere(centerOfMassWorld, 0.1f);
            Gizmos.DrawLine(centerOfMassWorld, centerOfMassWorld + Vector3.up * 0.5f);
        }
    }
}