using System;
using System.Collections.Generic;
using System.Linq;
using NBC;
using NBF;
using Obi;
using RootMotion.FinalIK;
using UnityEngine;

public class FRod : FPlayerGear
{
    private CCDIK _ccdik;

    [HideInInspector] public float throwPowerForSounds;

    public bool isThrowing { get; set; }

    public FWaterDisplacement LureHookWaterDisplacement;

    [HideInInspector] public FFish currentFish;

    [HideInInspector] public FFish takeFish;


    private float bendSmooth;

    public FRodData RodData { get; private set; }

    /// <summary>
    /// 鱼竿资产组件
    /// </summary>
    public RodAsset rodAsset;

    // public RodRingAsset RodRingAsset { get; private set; }

    public RodRingNode[] rings;

    /// <summary>
    /// 鱼线处理器
    /// </summary>
    public FLineHandler lineHandler;


    public float currentLineTension;
    public float linelenghtDiferent;
    public float currentLineStrenght;

    private void Awake()
    {
        rodAsset = GetComponent<RodAsset>();
        _ccdik = GetComponent<CCDIK>();
    }

    protected override void OnStart()
    {
        RodData = GearData as FRodData;
        IKSolverCCD solver = _ccdik.solver;
        solver.OnPostUpdate =
            (IKSolver.UpdateDelegate)Delegate.Combine(solver.OnPostUpdate, new IKSolver.UpdateDelegate(OnPostUpdate));
        // fishingLine = GetComponent<FFishingLine>();
        // fishingLine.Initialize(Owner);
        for (int i = 0; i < _ccdik.solver.bones.Length; i++)
        {
            _ccdik.solver.bones[i].weight = 0.06f;
        }

        // CheckCreateFishingHandler();
    }

    public void SetRing(RodRingAsset ringAsset)
    {
        if (rodAsset.rings == null || rodAsset.rings.Length < 1) return;

        var trans = ringAsset.rings;
        RodRingNode lastRingNode = null;
        List<RodRingNode> list = new List<RodRingNode>();
        for (int i = 0; i < rodAsset.rings.Length; i++)
        {
            var ring = rodAsset.rings[i];
            if (ring == null)
            {
                Log.Error($"ring is null,index={i}");
                continue;
            }

            var lastName = ring.name.GetLastString();
            foreach (var tran in trans)
            {
                var ringNode = tran.ring;
                var lastName2 = ringNode.name.GetLastString();
                if (lastName != lastName2) continue;
                list.Add(tran);
                ringNode.SetParent(ring);
                ringNode.localPosition = Vector3.zero;
                ringNode.localRotation = Quaternion.identity;
                lastRingNode = tran;
                break;
            }
        }

        if (lastRingNode != null)
        {
            rodAsset.lineConnector = lastRingNode.point;
        }

        rings = list.ToArray();
    }
    
    
    private void OnPostUpdate()
    {
        BendControll();
        RenderLine();
    }

    protected override void OnUpdate()
    {
        linelenghtDiferent = getLineDiferent();

        float num = RodData.Config.strength * 0.01f;
        currentLineStrenght = Mathf.Clamp01(linelenghtDiferent) * (Owner.Data.currentGear.line.Config.strength + num);

        if ((bool)currentFish)
        {
            currentLineTension = linelenghtDiferent * (currentFish.fishWeight * currentFish.fishStamina);
        }
        else
        {
            currentLineTension = Mathf.Clamp(linelenghtDiferent, 0f, 50f) * 0.3f;
        }
    }


    private void BendControll()
    {
        _ccdik.solver.SetIKPositionWeight(0f);
        return;
        
        if (lineHandler == null)
        {
            _ccdik.solver.target = null;
            _ccdik.solver.SetIKPositionWeight(0f);
            return;
        }

        if (!_ccdik.solver.target)
        {
            _ccdik.solver.target = lineHandler.LineConnector_1.transform;
            return;
        }

        float num = 0.15f;
        float max = 0.3f;
        if ((bool)takeFish)
        {
            num = 10f;
            max = 1f;
        }
        else if ((bool)currentFish)
        {
            num = 0.5f + currentLineTension * currentFish.fishWeight * 0.3f;
            max = 1f;
        }
        else if (Owner.Gears.Reel && Owner.Data.currentReelingSpeed > 0f)
        {
            num = Owner.Data.currentReelingSpeed * 0.3f;
            max = 0.3f;
        }

        float num2 = Mathf.Clamp01(Mathf.Clamp01(getLineDiferent()) * num);
        if (num2 < 0.05f)
        {
            num2 = 0f;
        }

        bendSmooth = Mathf.MoveTowards(bendSmooth, num2,
            Time.deltaTime * (1f - Mathf.Clamp01(getLineDiferent())));
        if ((bool)currentFish && currentFish.isGetFish)
        {
            bendSmooth = 0f;
        }

        bendSmooth = Mathf.Clamp(bendSmooth, 0.001f, max);
        _ccdik.solver.SetIKPositionWeight(Mathf.MoveTowards(_ccdik.solver.IKPositionWeight, bendSmooth,
            Time.deltaTime * 0.5f));
    }


    public float getLineDiferent()
    {
        if (!lineHandler)
        {
            return 0f;
        }

        return Vector3.Distance(lineHandler.LineConnector_1.transform.position,
            rodAsset.lineConnector.position) - Owner.Data.lineLength;
    }

    public void DestroyCurrentFish()
    {
        Debug.Log("Destroy fish frod");
        // if ((bool)currentPlayer.currentChwytak)
        // {
        //     Destroy(currentPlayer.currentChwytak.gameObject);
        //     currentPlayer.currentChwytak = null;
        //     Debug.Log("Destroy chwytak");
        // }

        if ((bool)currentFish)
        {
            Destroy(currentFish.gameObject);
            currentFish = null;
        }
    }

    private void OnDestroy()
    {
        // GameManager.Instance._playerData.PlayerSlotsEquip[indexOfslot].rod.status =
        //     GameManager.PlayerData.CRods.Status.InEquip;

        if ((bool)lineHandler)
        {
            ObiSolver component = lineHandler.GetComponent<ObiSolver>();
            SceneSettings.Instance.obiFixedUpdater.solvers.Remove(component);
            Destroy(lineHandler.gameObject);
            lineHandler = null;
        }
    }


    public void CreateFishingHandler()
    {
        if (lineHandler == null)
        {
            if (Owner.Data.currentGear != null && Owner.Data.currentGear.rod != null)
            {
                Debug.LogError("创建钓组=====");
                var rodType = Owner.Data.currentGear.Type;
                if (rodType == GearType.Pole || rodType == GearType.SpinningFloat)
                {
                    CreateObiFishingLine(0);
                }
                else if (rodType == GearType.Spinning)
                {
                    CreateObiFishingLine(1);
                }
            }
        }
    }

    public void CreateObiFishingLine(int currentLineTypeIndex)
    {
        // if ((bool)Owner.Gears.Reel && !currentLineHandler)
        if (!lineHandler)
        {
            var indexNames = new[] { "FFishingLine_0", "FFishingLine_1", "FFishingLine_3" };
            var path = $"GameItemsPrefabs/Lines/{indexNames[currentLineTypeIndex]}";
            var prefab = Resources.Load<GameObject>(path);

            // var toRodConnector = rodAsset.lineConnector.GetComponent<Rigidbody>();
            GameObject obj = Instantiate(prefab, Owner.Gears.GearParent.position,
                Quaternion.identity, Owner.Gears.GearParent);

            lineHandler = obj.GetComponent<FLineHandler>();
            // lineHandler.transform.SetParent(toRodConnector.transform);
            lineHandler.transform.position = rodAsset.lineConnector.position;
            lineHandler.LineConnector_0.target = rodAsset.lineConnector;//.GetComponent<Rigidbody>();
            // lineHandler.toRodConnector.target = rodAsset.lineConnector;
            lineHandler.Rod = this;
            var obiSolver = lineHandler.GetComponent<ObiSolver>();
            SceneSettings.Instance.obiFixedUpdater.solvers.Add(obiSolver);
        }
    }

    public void RenderLine()
    {
        if (!lineHandler)
        {
            return;
        }

        if (!Owner.Gears.Reel) return;
        if (!rodAsset.lineRenderer) return;

        var reel = Owner.Gears.Reel;
        int num = 0;
        bool isBlockLineByFinger = reel.isBlockLineByFinger;
        if (reel.AnimatorCtrl.Unlock && isBlockLineByFinger && reel.reelAsset.type == ReelAsset.Type.Normal)
        {
            rodAsset.lineRenderer.positionCount = rings.Length + 3;
        }
        else
        {
            rodAsset.lineRenderer.positionCount = rings.Length + 2;
        }

        rodAsset.lineRenderer.SetPosition(num, reel.reelAsset.lineIntersectHelper.position);
        num++;
        if (reel.AnimatorCtrl.Unlock && reel.reelAsset.type == ReelAsset.Type.Normal)
        {
            rodAsset.lineRenderer.SetPosition(num, reel.reelAsset.lineIntersect.position);
            num++;
            if (isBlockLineByFinger)
            {
                // rodAsset.lineRenderer.SetPosition(num, reel.reelAsset.lineFingerPoint.position);
                // num++;
            }
        }
        else
        {
            rodAsset.lineRenderer.SetPosition(num, reel.reelAsset.lineConnector.position);
            num++;
        }

        for (int num2 = 0; num2 < rings.Length; num2++)
        {
            rodAsset.lineRenderer.SetPosition(num, rings[num2].point.position);
            num++;
        }
    }
    
    
}