using System;
using System.Collections;
using System.Collections.Generic;
using Fantasy;
using NBC.Asset;
using NBF.Utils;
using UnityEngine;
using Object = UnityEngine.Object;

namespace NBF
{
    public class FRod : FHandItem
    {
        private float _tension;


        /// <summary>
        /// 可用的
        /// </summary>
        public bool Usable { get; private set; }

        public RodAsset Asset;

        public FPlayer Player { get; protected set; }
        public ItemInfo ItemInfo;

        public FReel Reel;
        public FHook Hook;
        public FBobber Bobber;
        public FBait Bait;
        public FLure Lure;
        public FWeight Weight;
        public FLine Line;


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

        public Transform GearRoot;

        // public FWaterDisplacement LureHookWaterDisplacement;

        [HideInInspector] public FFish currentFish;
        public RodRingNode[] rings;

        /// <summary>
        /// 线长度
        /// </summary>
        public float lineLength = 1.5f;

        /// <summary>
        /// 浮漂线长度
        /// </summary>
        public float floatLength = 0.5f;

        public float Tension
        {
            get => _tension;
            private set
            {
                if (!Mathf.Approximately(_tension, value))
                {
                    _tension = value;
                    // OnTensionChanged?.Invoke(_tension);
                }
            }
        }

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


        private void Awake()
        {
            Asset = GetComponent<RodAsset>();
        }

        private void Update()
        {
            if (Input.GetKeyDown(KeyCode.Alpha0))
            {
                SetLineLength(lineLength);
            }
            else if (Input.GetKeyDown(KeyCode.Plus) || Input.GetKeyDown(KeyCode.Equals))
            {
                lineLength += 0.1f;
                SetLineLength(lineLength);
            }
            else if (Input.GetKeyDown(KeyCode.Minus))
            {
                lineLength -= 0.1f;
                SetLineLength(lineLength);
            }
        }

        public void SetLineLength(float lineLength, bool stretchRope = true)
        {
            if (!Line) return;
            if (Line.IsLure)
            {
                //没有浮漂类型
                Line.Lure.SetJointDistance(lineLength);
                if (stretchRope)
                {
                    Line.SetObiRopeStretch(Tension > 0f ? 0f : lineLength);
                }
            }
            else
            {
                //有浮漂
                Line.Lure.SetJointDistance(floatLength);
                Line.Bobber.SetJointDistance(lineLength - floatLength);
                if (stretchRope)
                {
                    Line.SetObiRopeStretch(Tension > 0f ? 0f : lineLength - floatLength);
                }
            }
        }

        private void LateUpdate()
        {
            Test();
        }

        public IEnumerator Destroy()
        {
            if (GearRoot != null)
            {
                Object.Destroy(GearRoot.gameObject);
            }

            yield return 1;
        }

        public IEnumerator InitRod(FPlayer player, ItemInfo itemInfo)
        {
            ItemInfo = itemInfo;
            Player = player;

            transform.localPosition = Vector3.zero;
            transform.localRotation = Quaternion.identity;
            transform.localScale = Vector3.one;
            SceneSettings.Instance.GearNode.position = Player.transform.position;
            yield return 1;
            var obj = new GameObject($"rod_{itemInfo.Id}_{itemInfo.ConfigId}");
            obj.transform.SetParent(SceneSettings.Instance.GearNode);
            // obj.transform.SetParent(player.transform);
            // obj.transform.localPosition = Vector3.zero;
            obj.transform.position = player.transform.position;
            obj.transform.rotation = player.transform.rotation;
            obj.transform.localScale = Vector3.one;
            GearRoot = obj.transform;

            var parent = GearRoot;

            List<ItemInfo> children = RoleModel.Instance.GetBindItems(itemInfo.Id);

            ItemInfo lineItemInfo = null;

            CreateFishingHandler();
            yield return 1; //等待1帧
            // children.Sort();
            foreach (var child in children)
            {
                var itemType = child.ConfigId.GetItemType();
                if (itemType == ItemType.Reel)
                {
                    Reel = child.Config.InstantiateAndComponent<FReel>(Asset.ReelConnector, Vector3.zero,
                        Quaternion.identity);
                    Reel.SetItemInfo(child);
                }
                else if (itemType == ItemType.Bobber)
                {
                    Bobber = child.Config.InstantiateAndComponent<FBobber>(parent, Vector3.zero,
                        Quaternion.identity);
                    Bobber.SetItemInfo(child);
                }
                else if (itemType == ItemType.Hook)
                {
                    Hook = child.Config.InstantiateAndComponent<FHook>(parent, Vector3.zero,
                        Quaternion.identity);
                    Hook.SetItemInfo(child);
                }
                else if (itemType == ItemType.Bait)
                {
                    Bait = child.Config.InstantiateAndComponent<FBait>(parent, Vector3.zero,
                        Quaternion.identity);
                    Bait.SetItemInfo(child);
                }
                else if (itemType == ItemType.Lure)
                {
                    Lure = child.Config.InstantiateAndComponent<FLure>(parent, Vector3.zero,
                        Quaternion.identity);
                    Lure.SetItemInfo(child);
                }
                else if (itemType == ItemType.Weight)
                {
                    Weight = child.Config.InstantiateAndComponent<FWeight>(parent, Vector3.zero,
                        Quaternion.identity);
                    Weight.SetItemInfo(child);
                }
                else if (itemType == ItemType.Line)
                {
                    lineItemInfo = child;
                }
            }

            yield return 1;
            if (Reel)
            {
                Reel.reelingDrag = 0.699f;
                Reel.transform.SetParent(Asset.ReelConnector);
                Reel.transform.localPosition = Vector3.zero;
                Reel.transform.localEulerAngles = Vector3.zero;
                Reel.Init(player, this);
            }

            if (Bobber)
            {
                Bobber.Init(Player, this);
            }

            if (Hook)
            {
                Hook.Init(Player, this);
                // LureHookWaterDisplacement = Hook.GetComponent<FWaterDisplacement>();
            }

            if (Bait)
            {
                Bait.Init(Player, this);
            }

            if (Lure)
            {
                Lure.Init(Player, this);
            }

            if (Weight)
            {
                Weight.Init(Player, this);
            }

            yield return 1; //等待1帧

            transform.SetParent(Player.ModelAsset.RodRoot);
            transform.localPosition = Vector3.zero;
            transform.rotation = Player.ModelAsset.RodRoot.rotation;

            Usable = true;
        }


        public void CreateFishingHandler()
        {
            if (Line == null)
            {
                Debug.LogError("创建钓组=====");
                var rodType = (ItemSubType)ItemInfo.Config.Type;
                if (rodType == ItemSubType.RodTele)
                {
                    CreateObiFishingLine(0);
                }
                else if (rodType == ItemSubType.RodSpine || rodType == ItemSubType.RodBolo)
                {
                    CreateObiFishingLine(1);
                }
            }
        }


        public void CreateObiFishingLine(int currentLineTypeIndex)
        {
            if (!Line)
            {
                var lineSolverPrefab = Assets.Load<GameObject>("Assets/ResRaw/Prefabs/Line/LineSolver.prefab");
                var solver = Instantiate(lineSolverPrefab, GearRoot);
                solver.transform.position = Asset.lineConnector.position;
                solver.transform.rotation = Asset.lineConnector.rotation;
                var indexNames = new[] { "fishing line float set", "fishing line spinning" };
                var path =
                    $"Assets/ResRaw/Prefabs/Line/{indexNames[currentLineTypeIndex]}.prefab";
                var prefab = Assets.Load<GameObject>(path);

                GameObject obj = Instantiate(prefab, solver.transform);
                obj.transform.localPosition = Vector3.zero;
                obj.transform.localScale = Vector3.one;
                obj.transform.rotation = Quaternion.identity;

                Line = obj.GetComponent<FLine>();
                Line.transform.position = Asset.lineConnector.position;
                Line.Init(this.Player, this);

                // var obiSolver = solver.GetComponent<ObiSolver>();
                // obiSolver.parameters.ambientWind = Vector3.zero;
                // obiSolver.wind.
                // obiSolver.simulateWhenInvisible
            }
        }

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

            var trans = ringAsset.rings;
            RodRingNode lastRingNode = null;
            List<RodRingNode> list = new List<RodRingNode>();
            for (int i = 0; i < Asset.rings.Length; i++)
            {
                var ring = Asset.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)
            {
                Asset.lineConnector = lastRingNode.point;
            }

            rings = list.ToArray();
        }

        private void Test()
        {
            // var root = Player.ModelAsset.RodRoot;
            // if (!root) return;
            // transform.SetPositionAndRotation(root.position, root.rotation);
        }
    }
}