using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Text;
using Assets.Scripts.Events;
using Assets.Scripts.Player;
using UnityEngine;

namespace Assets.Scripts.Core
{
    public class PlayerStats {
        public delegate void HeroDelegate(PlayerHero hero);

        public PlayerHero[] PlayerCharacters { get; private set; }
        private readonly Dictionary<string, bool> _flags = new Dictionary<string, bool>();

        public PlayerStats() {
            PlayerCharacters = new [] {
                MobFactory.MakeLua(), MobFactory.MakeFavo(), MobFactory.MakeCouro()
            };
            CurrentAct = Act.Act_1;
            Gold = 30;
        }

        public bool GetFlag(string name) {
            bool value;
            _flags.TryGetValue(name, out value);
            return value;
        }

        public void SetFlag(string name, bool value) {
            _flags.Remove(name);
            _flags.Add(name, value);
        }

        public Act CurrentAct { get; set; }

        public bool HasCharacter(string name) {
            return PlayerCharacters.Any(c => c.IsAlive() && c.Name == name);
        }

        public PlayerHero RandomHero() {
            return LivingCharacters.RandomElement();
        }

        public void ForAllHeroes (HeroDelegate d) {
            foreach (var p in PlayerCharacters) {
                d(p);
            }
        }

        public void ForNHeroes (int n, HeroDelegate d) {
            var ps = new List<PlayerHero>(PlayerCharacters);
            ps.Shuffle();
            for (int i = 0; i < n; i++) {
                d(ps[i]);
            }
        }

        public void Rest() {
            foreach (var c in PlayerCharacters) {
                c.Heal(3);
                c.HealSanity(3);
            }
        }

        public PlayerHero[] LivingCharacters {
            get { return PlayerCharacters.Where(p => p.IsAlive()).ToArray(); }
        }

        public PlayerHero[] DeadCharacters {
            get { return PlayerCharacters.Where(p => !p.IsAlive()).ToArray(); }
        }

        private int _gold;
        public int Gold {
            get { return _gold; }
            set { _gold = Mathf.Max(0, value); }
        }

        public int CultistsDefeated { get; set; }

        public void AddHero(PlayerHero newHero) {
            var chars = PlayerCharacters.ToList();
            chars.Add(newHero);
            PlayerCharacters = chars.ToArray();
        }

        public void RemoveDead() {
            PlayerCharacters = LivingCharacters.ToArray();
        }
    }
}
