using System;
using System.Linq;
using Diz.Skinning;
using EFT;
using EFT.Interactive;
using EFT.InventoryLogic;
using EFT.UI;
using UnityEngine;

namespace EscapeFromTarkovCheat.Utils
{

    public static class GameUtils
    {
        public static float Map(float value, float sourceFrom, float sourceTo, float destinationFrom, float destinationTo)
        {
            return (value - sourceFrom) / (sourceTo - sourceFrom) * (destinationTo - destinationFrom) + destinationFrom;
        }
        public static bool IsPlayerValid(Player player)
        {
            return player != null && player.Transform != null && player.PlayerBones != null && player.PlayerBones.transform != null;
        }
        public static bool IsExfiltrationPointValid(ExfiltrationPoint lootItem)
        {
            return lootItem != null;
        }
        public static bool IsLootItemValid(LootItem lootItem)
        {
            return lootItem != null && lootItem.Item != null && lootItem.Item.Template != null;
        }

        public static bool IsLootableContainerValid(LootableContainer lootableContainer)
        {
            return lootableContainer != null && lootableContainer.Template != null;
        }

        public static bool IsPlayerAlive(Player player)
        {
            if (!IsPlayerValid(player))
                return false;

            if (player.HealthController == null)
                return false;

            return player.HealthController.IsAlive;
        }
        public static bool IsPlayerVisible(Player player)
        {
            if (player == null || Camera.main == null)
                return false;

            // 可视检查部位
            BifacialTransform[] pointsToCheck = {
                player.PlayerBones.Head,
                player.PlayerBones.Spine3,
                player.PlayerBones.Pelvis
            };

            foreach (BifacialTransform point in pointsToCheck)
            {
                if (point == null)
                    continue;

                // 射线方向
                Vector3 direction = point.position - Camera.main.transform.position;

                // 射线检测
                if (!Physics.Raycast(Camera.main.transform.position, direction, out RaycastHit hit, direction.magnitude))
                {
                    continue;
                }

                // 射线命中
                if (hit.collider.gameObject == player.gameObject)
                {
                    return true;
                }
            }

            return false;
        }
        public static Vector3 WorldPointToScreenPoint(Vector3 worldPoint)
        {
            Vector3 screenPoint = Main.MainCamera.WorldToScreenPoint(worldPoint);

            screenPoint.y = Screen.height - screenPoint.y;

            return screenPoint;
        }

        public static bool IsScreenPointVisible(Vector3 screenPoint)
        {
            return screenPoint.z > 0.01f && screenPoint.x > -5f && screenPoint.y > -5f && screenPoint.x < Screen.width && screenPoint.y < Screen.height;
        }

        public static Vector3 GetBonePosByID(Player player, int id)
        {
            Vector3 result;
            try
            {
                result = SkeletonBonePos(player.PlayerBones.AnimatedTransform.Original.gameObject.GetComponent<PlayerBody>().SkeletonRootJoint, id);
            }
            catch (Exception)
            {
                result = Vector3.zero;
            }
            return result;
        }

        public static Vector3 GetBonePosByEID(Player player, BoneType eid)
        {
            Vector3 result;
            try
            {
                result = SkeletonBonePos(player.PlayerBones.AnimatedTransform.Original.gameObject.GetComponent<PlayerBody>().SkeletonRootJoint, (int)eid);
            }
            catch (Exception)
            {
                result = Vector3.zero;
            }
            return result;
        }

        public static Vector3 SkeletonBonePos(Skeleton skeleton, int id)
        {
            return skeleton.Bones.ElementAt(id).Value.position;
        }
        public static void AddConsoleLog(string log)
        {
            if (PreloaderUI.Instantiated)
                ConsoleScreen.Log(log);
        }
        public static Vector3 GetTargetPosition()
        {
            var centerPosition = Main.LocalPlayer.Transform.position;

            if (Main.LocalPlayer.HandsController is Player.FirearmController firearmController)
            {
                if (Physics.Raycast(new Ray(firearmController.Fireport.position, firearmController.WeaponDirection), out RaycastHit hit, float.MaxValue))
                {
                    centerPosition = hit.point;
                }
            }

            return centerPosition;
        }
        public static bool IsGroundLoot(LootItem lootItem)
        {
            return lootItem.GetComponent<Corpse>() == null;
        }
        public static bool IsInteractableLoot(LootItem lootItem)
        {
            var collider = lootItem.GetComponent<Collider>();
            return collider != null && collider.enabled;
        }
        public static bool IsInventoryItemValid(Item item)
        {
            return item != null && item.Template != null;
        }
    }
}