using System.Collections.Generic;
using System.Linq;
using System.Text;
using Assets.Scripts.Core;
using UnityEngine;

namespace Assets.Scripts.Events
{
    public class EventFactory {
        private static EventFactory _instance;
        private Act _currentAct;
        private int _sequenceNumber;

        private readonly Dictionary<Act, List<GameEvent>> _events = new Dictionary<Act, List<GameEvent>>();
        private readonly Dictionary<string, GameEvent> _specificEvents = new Dictionary<string, GameEvent>();

        public static EventFactory Instance {
            get { return _instance ?? (_instance = new EventFactory()); }
        }

        private EventFactory() {
            InitializeEvents();
        }

        public GameEvent GetRandomEvent(PlayerStats stats) {
            var act = stats.CurrentAct;
            var candidates = _events[act].Where(e => !stats.GetFlag("EventPlayed:" + e.Id) && e.CanTrigger(stats)).ToArray();
            if (candidates.Length > 0) {
                var pick = candidates.RandomElement();
                if (!pick.Recurring) {
                    stats.SetFlag("EventPlayed:" + pick.Id, true);
                }
                return pick;
            }
            return null;
        }

        public GameEvent GetSpecificEvent (string name) {
            return _specificEvents[name];
        }

        public void AddEvent(GameEvent e) {
            e.Id = _currentAct + ":" + _sequenceNumber;
            _sequenceNumber++;
            _events[_currentAct].Add(e);
        }

        public void StartActSetup (Act act) {
            _sequenceNumber = 0;
            _currentAct = act;
            _events.Add(_currentAct, new List<GameEvent>());
        }

        public void AddSpecificEvent(GameEvent e, string name) {
            _specificEvents.Add(name, e);
        }

        private void InitializeEvents () {
            new Act1Events().Run(this);
            new Act2Events().Run(this);
            new Act3Events().Run(this);
            new SpecialEvents().Run(this);
        }
    }
}
