using System.Collections.Generic;
using UnityEngine;

public class FWaterDisplacement : MonoBehaviour
{
    public enum MoveCharacteristic
    {
        Custom = 0,
        MoveUp_StopDown = 1,
        MoveDown_100cm = 2,
        MoveDown_150cm = 3,
        TopWater = 4,
        MoveDown = 5,
        MoveUp_StopDown_Twisters = 6
    }

    public MoveCharacteristic moveCharacteristic;

    public float objectDisplacement = 1f;

    public float waterDrag = 3f;

    public float waterMass = 3f;

    public float outwaterMass = 6f;

    public bool isInWater;
    public bool isInTerrain;

    public bool resetVelocityEnterToWater = true;

    private float normalDrag;

    public bool isFreeze;

    public bool useSplashes = true;

    public bool useSplashesOnlyInThrow;

    public bool useWaterCurrent;

    [HideInInspector] public Rigidbody rigidbody;

    [HideInInspector] public Collider collider;

    [HideInInspector] public float waterHeightPosition;

    [HideInInspector] public float depth;

    private FFishSystem fFishSystem;

    public List<FFish> fishListCreated;

    private void Start()
    {
        fFishSystem = FindObjectOfType<FFishSystem>();
        rigidbody = GetComponent<Rigidbody>();
        collider = GetComponent<Collider>();
        normalDrag = rigidbody.linearDamping;
        fishListCreated = new List<FFish>();
    }

    private void FixedUpdate()
    {
        if (isInWater)
        {
            depth = Mathf.Abs(transform.position.y);
        }
        else
        {
            depth = 0f;
        }

        AffectCharacteristic();
        AffectCharacteristicNew();
    }

    private void Update()
    {
    }

    private void AffectCharacteristic()
    {
        if (moveCharacteristic == MoveCharacteristic.Custom && !isFreeze && isInWater && transform.position.y < 0f &&
            objectDisplacement > 0f)
        {
            transform.position = Vector3.MoveTowards(transform.position,
                new Vector3(transform.position.x, waterHeightPosition, transform.position.z),
                Time.deltaTime * objectDisplacement);
        }
    }

    private void AffectCharacteristicNew()
    {
        if (isFreeze || !isInWater || transform.position.y >= -0.01f)
        {
            return;
        }

        float num = Vector3.Dot(rigidbody.linearVelocity, transform.forward);
        Quaternion b = Quaternion.Euler(0f, rigidbody.transform.localEulerAngles.y, 0f);
        rigidbody.rotation = Quaternion.Slerp(rigidbody.rotation, b, Time.deltaTime * 2f);
        switch (moveCharacteristic)
        {
            case MoveCharacteristic.MoveDown:
                if (num > 0.2f)
                {
                    rigidbody.AddForce(-Vector3.up * Time.deltaTime * Mathf.Clamp01(num) * 2f,
                        ForceMode.VelocityChange);
                }
                else
                {
                    rigidbody.AddForce(Vector3.up * Time.deltaTime * 1f, ForceMode.VelocityChange);
                }

                rigidbody.freezeRotation = true;
                break;
            case MoveCharacteristic.MoveUp_StopDown:
                if (num > 0.2f)
                {
                    rigidbody.AddForce(Vector3.up * Time.deltaTime * Mathf.Clamp01(num), ForceMode.VelocityChange);
                }
                else
                {
                    rigidbody.AddForce(-Vector3.up * Time.deltaTime * 3f, ForceMode.VelocityChange);
                }

                rigidbody.freezeRotation = true;
                break;
            case MoveCharacteristic.MoveUp_StopDown_Twisters:
                if (num > 0.2f)
                {
                    rigidbody.AddForce(Vector3.up * Time.deltaTime * Mathf.Clamp01(num), ForceMode.VelocityChange);
                }
                else
                {
                    rigidbody.AddForce(-Vector3.up * Time.deltaTime * 2.5f, ForceMode.VelocityChange);
                }

                rigidbody.freezeRotation = true;
                break;
            case MoveCharacteristic.TopWater:
                if (num > 0.2f && transform.position.y >= -0.03f)
                {
                    rigidbody.AddForce(-Vector3.up * Time.deltaTime * 1f, ForceMode.VelocityChange);
                }
                else
                {
                    rigidbody.AddForce(Vector3.up * Time.deltaTime * 1f, ForceMode.VelocityChange);
                }

                rigidbody.freezeRotation = true;
                break;
            case MoveCharacteristic.MoveDown_150cm:
                if (num > 0.2f && transform.position.y > -1.5f)
                {
                    rigidbody.AddForce(-Vector3.up * Time.deltaTime * Mathf.Clamp01(num) * 2f,
                        ForceMode.VelocityChange);
                }
                else
                {
                    rigidbody.AddForce(Vector3.up * Time.deltaTime * 1f, ForceMode.VelocityChange);
                }

                rigidbody.freezeRotation = true;
                break;
            case MoveCharacteristic.MoveDown_100cm:
                if (num > 0.2f && transform.position.y > -1f)
                {
                    rigidbody.AddForce(-Vector3.up * Time.deltaTime * Mathf.Clamp01(num) * 2f,
                        ForceMode.VelocityChange);
                }
                else
                {
                    rigidbody.AddForce(Vector3.up * Time.deltaTime * 1f, ForceMode.VelocityChange);
                }

                rigidbody.freezeRotation = true;
                break;
            case MoveCharacteristic.Custom:
                break;
        }
    }

    private void OnTriggerStay(Collider other)
    {
        if (other.CompareTag("Water"))
        {
            isInWater = true;
            rigidbody.mass = waterMass;
            waterHeightPosition = other.transform.position.y;
            if (rigidbody.useGravity)
            {
                EnableDisableGravity(value: false);
            }

            if (rigidbody.linearDamping != waterDrag)
            {
                SetDragRigidbody(waterDrag);
            }

            if ((bool)fFishSystem)
            {
                fFishSystem.AddInwaterObject(this);
            }
        }
    }

    private void OnTriggerExit(Collider other)
    {
        if (other.CompareTag("Water"))
        {
            rigidbody.freezeRotation = false;
            isInWater = false;
            rigidbody.mass = outwaterMass;
            EnableDisableGravity(value: true);
            SetDragRigidbody(normalDrag);
            if ((bool)fFishSystem)
            {
                fFishSystem.DeleteInwaterObject(this);
            }
        }
    }

    private void EnableDisableGravity(bool value)
    {
        if (resetVelocityEnterToWater)
        {
            rigidbody.linearVelocity = Vector3.zero;
        }
        
        Rigidbody[] componentsInChildren = gameObject.GetComponentsInChildren<Rigidbody>();
        for (int i = 0; i < componentsInChildren.Length; i++)
        {
            componentsInChildren[i].useGravity = value;
        }
    }

    private void SetDragRigidbody(float value)
    {
        Rigidbody[] componentsInChildren = gameObject.GetComponentsInChildren<Rigidbody>();
        for (int i = 0; i < componentsInChildren.Length; i++)
        {
            componentsInChildren[i].linearDamping = value;
        }
    }

    public void ForceByWaterCurrent(Vector3 direction, float powerForce)
    {
        if (useWaterCurrent && isInWater)
        {
            rigidbody.AddForce(direction * powerForce, ForceMode.Acceleration);
        }
    }

    private void BuildSplash(Vector3 contactPosition)
    {
        // if (useSplashes && !(rigidbody.linearVelocity.magnitude < 3f) &&
        //     (!FScriptsHandler.Instance.m_PlayerMain.currentRod || !useSplashesOnlyInThrow ||
        //      FScriptsHandler.Instance.m_PlayerMain.currentRod.currentReel.kablagOpenState) &&
        //     !(rigidbody.linearVelocity.y > 0f))
        // {
        //     Vector3 vector = Vector3.one * (0.02f * Mathf.Abs(rigidbody.linearVelocity.y)) * transform.localScale.x;
        //     int num = 0;
        //     GameObject obj = Instantiate(FScriptsHandler.Instance.waterFishSplash[num]);
        //     obj.transform.position = new Vector3(contactPosition.x, 0.05f, contactPosition.z);
        //     obj.GetComponent<AudioSource>().volume = 0.5f * vector.x;
        //     vector = Vector3.ClampMagnitude(vector, 1f);
        //     obj.transform.localScale = vector;
        // }
    }

    private void OnTriggerEnter(Collider col)
    {
        if (col.transform.CompareTag("Water"))
        {
            BuildSplash(new Vector3(transform.position.x, SceneSettings.Instance.WaterObject.transform.position.y,
                transform.position.z));
        }
    }

    private void OnDestroy()
    {
        if ((bool)fFishSystem)
        {
            fFishSystem.DeleteInwaterObject(this);
        }
    }
}