using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class ItemGrabber : MonoBehaviour {
    public Transform CameraTransform;
    public Transform HandTransform;
    public Transform TorchHandTransform;
    public CanvasGroup PrimaryIndicator;
    public Text PrimaryText;
    public CanvasGroup SecondaryIndicator;
    public Text SecondaryText;
    public LayerMask ItemLayer;
    public LayerMask DroppingRaycastMask;
    public float Distance;

    [Header("Prefabs")]
    public GameObject TorchPrefab;

    [Header("Runtime values")]
    public List<Item> GrabbedItems;
    public Torch Torch;
    public GameObject NextTorch;

    private Item LookedAtItem = null;
    private float LastItemHitTime = -1;

    private void Start() {
        PrimaryIndicator.alpha = 0;
        SecondaryIndicator.alpha = 0;
    }

    private void Update() {
        Campfire Campfire = null;
        RaycastHit Hit;
        Vector3 From = CameraTransform.position;
        Vector3 Direction = CameraTransform.forward;

        Item ThrowableItem = GetThrowableItem();
        Item TorchableItem = GetTorchableItem();
        bool CanIgniteTorch = Torch != null && TorchableItem != null;

        if (Physics.Raycast(From, Direction, out Hit, Distance, ItemLayer) &&
                Hit.collider.attachedRigidbody != null) {
            LookedAtItem = Hit.collider.attachedRigidbody.GetComponent<Item>();
            LastItemHitTime = Time.time;
        } else if (Time.time - LastItemHitTime > 0.1f) {
            LookedAtItem = null;
        }

        if (Physics.Raycast(From, Direction, out Hit, Distance * 2f, 1 << LayerMask.NameToLayer("Campfire")) &&
                Hit.collider.attachedRigidbody != null) {
            Campfire = Hit.collider.attachedRigidbody.GetComponent<Campfire>();
            CanIgniteTorch |= Campfire != null && TorchableItem != null;
        }

        if (Campfire == null && LookedAtItem != null && Input.GetButtonDown("Grab")) {
            LookedAtItem.PickUp(HandTransform);
            GrabbedItems.Add(LookedAtItem);
        }

        if (GrabbedItems.Count > 0) {
            if (CanIgniteTorch && Input.GetButtonDown("Ignite")) {
                if (Torch == null) {
                    NextTorch = TorchableItem.gameObject;
                    GrabbedItems.Remove(TorchableItem);
                    EquipNewTorch();
                } else {
                    // Starts the pass
                    NextTorch = TorchableItem.gameObject;
                    // Passing the torch will cause the current one to extinguish, 
                    // and then the new one will be equipped
                    Torch.PassTorch(TorchableItem.IgnitePoint);
                }
            }

            if (Input.GetButtonDown("Grab") && (LookedAtItem == null || Campfire != null) && ThrowableItem != null) {
                Vector3 DropPosition;
                if (Campfire != null) {
                    DropPosition = Campfire.transform.position + Vector3.up * 0.7f;
                } else {
                    if (Physics.Raycast(From, Direction, out Hit, Distance * 2f, DroppingRaycastMask)) {
                        DropPosition = Hit.point + Hit.normal * 0.1f;
                    } else {
                        DropPosition = From + Direction * Distance;
                    }
                }
                ThrowableItem.Drop(DropPosition);
                GrabbedItems.Remove(ThrowableItem);
            }
        }

        if (Torch != null && !Torch.Burning) {
            // Move torch back into the right hand
            int NextTorchIndex = -1;
            for (int I = 0; I < GrabbedItems.Count; I++) {
                if (GrabbedItems[I].gameObject == NextTorch) {
                    NextTorchIndex = I;
                    continue;
                }
            }

            // Previous torch's item component
            Item TorchItem = Torch.GetComponent<Item>();
            TorchItem.PickUp(HandTransform);
            if (NextTorchIndex != -1) {
                GrabbedItems[NextTorchIndex] = TorchItem;
            } else {
                GrabbedItems.Add(TorchItem);
            }

            // Equip new torch if there is one queued
            Torch = null;
            if (NextTorch != null) {
                EquipNewTorch();
            }
        }

        PrimaryIndicator.alpha = Mathf.Lerp(PrimaryIndicator.alpha,
            LookedAtItem != null || Campfire != null || ThrowableItem != null ? 1 : 0,
            10f * Time.deltaTime);
        if (Campfire != null && ThrowableItem != null) {
            PrimaryText.text = $"Burn {ThrowableItem.Quality.DisplayName}";
        } else if (LookedAtItem != null && Campfire == null) {
            PrimaryText.text = $"Take {LookedAtItem.Quality.DisplayName}";
        } else if (ThrowableItem != null) {
            PrimaryText.text = $"Throw {ThrowableItem.Quality.DisplayName}";
        }

        SecondaryIndicator.alpha = Mathf.Lerp(SecondaryIndicator.alpha, CanIgniteTorch ? 1 : 0, 10f * Time.deltaTime);
        if (CanIgniteTorch) {
            SecondaryText.text = $"Ignite {TorchableItem.Quality.DisplayName}";
        }
    }

    private Item GetTorchableItem() {
        Item ChosenItem = null;
        foreach (Item I in GrabbedItems) {
            Torch CurrentTorch = I.GetComponent<Torch>();
            if (I.Quality.Ignitable && (CurrentTorch == null || CurrentTorch.Burning)) {
                ChosenItem = I;
                continue;
            }
        }
        return ChosenItem;
    }

    private Item GetThrowableItem() {
        Item ChosenItem = null;
        foreach (Item I in GrabbedItems) {
            if (I.gameObject != NextTorch) {
                ChosenItem = I;
                continue;
            }
        }
        return ChosenItem;
    }

    private void EquipNewTorch() {
        GameObject TorchObj = Instantiate(TorchPrefab, NextTorch.transform.position, NextTorch.transform.rotation, TorchHandTransform);
        Torch = TorchObj.GetComponent<Torch>();
        Destroy(NextTorch);
        NextTorch = null;
    }
}
