using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using ScrambleKit.Move;

namespace ScrambleKit.Weapons
{
    [RequireComponent(typeof(MoveInputSource))]
    public class ControlsWeapon : MonoBehaviour
    {
        private MoveInputSource input;
        private List<WeaponCore> weapons;

        private const string TRIGGER = "Trigger";
        private const string SWITCHWEAPON = "SwitchWeapon";
        private const string DROPWEAPON = "DropWeaon";


        void FixedUpdate()
        {
            if(weapons == null) // one-time init, done in FixedUpdate to allow all weapon scripts to finish "start" first
            {
                weapons = new List<WeaponCore>();
                WeaponInventoryChanged();
            }

            if(input.ConsumeTrigger(TRIGGER))
            {
                Attack();
            }
            else if (input.ConsumeTrigger(DROPWEAPON))
            {
                DropWeapon();
            }
            else if (input.ConsumeTrigger(SWITCHWEAPON))
            {
                SwitchWeapon();
            }
        }

        private void SwitchWeapon()
        {
            Debug.Log("WeaponSwitching");
            if (weapons.Count < 2)
                return;

            WeaponCore readyWeapon = GetReadyWeapon();
            if (readyWeapon == null)
                weapons[0].Ready(input);
            else
            {
                int curr = weapons.IndexOf(readyWeapon);
                int next = (curr + 1) % weapons.Count;
                weapons[curr].Stow();
                weapons[next].Ready(input);
            }
        }

        private void Attack()
        {
            WeaponCore readyWeapon = GetReadyWeapon();
            if (readyWeapon != null)
                readyWeapon.transform.SendMessage("Attack");
        }

        private WeaponCore GetReadyWeapon()
        {
            return weapons.Where(w => w.IsReady).FirstOrDefault();
        }

        public void DropWeapon()
        {
            WeaponCore readyWeapon = GetReadyWeapon();
            if (readyWeapon != null)
                readyWeapon.Drop();
        }

        public void WeaponInventoryChanged()
        {
            weapons.Clear();
            weapons.AddRange(GetComponentsInChildren<WeaponCore>(true));
            Debug.Log("Found " + weapons.Count + " weapons attached to " + transform.name);
            if (HoldingButNotReady())
                weapons[0].Ready(input);
        }

        private bool HoldingButNotReady()
        {
            return weapons.Count != 0
                && weapons.Where(w => w.IsReady).Count() == 0;
        }

        void AddBindingNames(HashSet<string> bindingNames)
        {
            bindingNames.Add(TRIGGER);
            bindingNames.Add(SWITCHWEAPON);
            bindingNames.Add(DROPWEAPON);
        }

        void Start()
        {
            input = transform.root.GetComponent<MoveInputSource>();
        }

    }
}