using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Decal.Interop.Filters;
using Decal.Interop.Net;

namespace Decal.DecalFilters
{
    [ComVisible(true)]
    [Guid("4540C969-08D1-46BF-97AD-6B19D3C10BEE")]
    [ClassInterface(ClassInterfaceType.None)]
    [ComSourceInterfaces("Decal.Interop.Filters.ICharacterStatsEvents\0\0")]
    [ProgId("DecalFilters.CharacterStats")]
    public class CharacterStatsImpl : ICharacterStats, INetworkFilter2
    {
        // COM events
        public event ICharacterStatsEvents_LoginEventHandler Login;
        public event ICharacterStatsEvents_Spellbook_AddEventHandler Spellbook_Add;
        public event ICharacterStatsEvents_Spellbook_DeleteEventHandler Spellbook_Delete;
        public event ICharacterStatsEvents_LoginCompleteEventHandler LoginComplete;
        public event ICharacterStatsEvents_ActionCompleteEventHandler ActionComplete;
        public event ICharacterStatsEvents_StatusMessageEventHandler StatusMessage;
        public event ICharacterStatsEvents_DeathEventHandler Death;
        public event ICharacterStatsEvents_ChangePortalModeEventHandler ChangePortalMode;
        public event ICharacterStatsEvents_ChangeEnchantmentsEventHandler ChangeEnchantments;
        public event ICharacterStatsEvents_ChangePlayerEventHandler ChangePlayer;
        public event ICharacterStatsEvents_ChangeVitalEventHandler ChangeVital;
        public event ICharacterStatsEvents_ChangeXPSEventHandler ChangeXPS;
        public event ICharacterStatsEvents_ChangeFellowshipEventHandler ChangeFellowship;
        public event ICharacterStatsEvents_LogoffEventHandler Logoff;
        public event ICharacterStatsEvents_CastSpellEventHandler CastSpell;
        public event ICharacterStatsEvents_ChangeShortcutEventHandler ChangeShortcut;
        public event ICharacterStatsEvents_ChangeSpellbarEventHandler ChangeSpellbar;
        public event ICharacterStatsEvents_ChangeSettingsEventHandler ChangeSettings;
        public event ICharacterStatsEvents_ChangeSettingFlagsEventHandler ChangeSettingFlags;
        public event ICharacterStatsEvents_ChangeOptionEventHandler ChangeOption;

        // State
        private int _character;
        private int _level, _rank, _skillPoints;
        private int _totalExp, _unassignedExp;
        private long _totalXP64, _unassignedXP64;
        private string _server = "", _name = "", _race = "", _gender = "", _classTemplate = "";
        private string _accountName = "";
        private int _health, _stamina, _mana;
        private int _birth, _age, _deaths;
        private int _followers, _monarchFollowers, _vassalCount;
        private int _loginStatus, _serverPopulation, _accountCharCount;
        private int _burdenUnits, _burden, _vitae;
        private int _characterOptions, _characterOptionFlags, _quickslots;
        private uint _xpToNextLevel;
        private readonly List<int> _spellbook = new List<int>();
        private readonly List<int> _augmentations = new List<int>();

        // ICharacterStats
        public int Character => _character;
        public int Level => _level;
        public int Rank => _rank;
        public int TotalExp => _totalExp;
        public int UnassignedExp => _unassignedExp;
        public int SkillPoints => _skillPoints;
        public string Server => _server;
        public string Name => _name;
        public string Race => _race;
        public string Gender => _gender;
        public string ClassTemplate => _classTemplate;

        public int AttributeCount => 6;
        public int SkillCount => 39;
        public int VitalCount => 3;

        // Parameterized properties
        public AttributeInfo Attribute => null;
        public SkillInfo Skill => null;
        public SkillInfo Vital => null;

        public int SpellLearned => _spellbook.Count;
        public int TotalSpells => _spellbook.Count;
        public int Health => _health;
        public int Stamina => _stamina;
        public int Mana => _mana;
        public int Birth => _birth;
        public int Age => _age;
        public int Deaths => _deaths;
        public int VassalCount => _vassalCount;

        public AllegianceInfo Monarch => null;
        public AllegianceInfo Patron => null;
        public AllegianceInfo MyAllegiance => null;
        public AllegianceInfo Vassal => null;

        public int Followers => _followers;
        public int MonarchFollowers => _monarchFollowers;
        public int EnchantmentCount => 0;
        public Enchantment Enchantment => null;
        public int EffectiveAttribute => 0;
        public int EffectiveSkill => 0;
        public int EffectiveVital => 0;
        public int Vitae => _vitae;
        public int BurdenUnits => _burdenUnits;
        public int Burden => _burden;
        public long TotalXP_64 => _totalXP64;
        public long UnassignedXP_64 => _unassignedXP64;
        public int LoginStatus => _loginStatus;
        public int ServerPopulation => _serverPopulation;
        public string AccountName => _accountName;
        public int AccountCharCount => _accountCharCount;
        public int AccountCharID => 0;
        public string AccountCharName => string.Empty;
        public int Quickslots => _quickslots;
        public int CharacterOptions => _characterOptions;
        public uint XPToNextLevel => _xpToNextLevel;
        public int CharacterOptionFlags => _characterOptionFlags;

        public bool AugmentationExists(eAugmentations key, out int pValue)
        {
            pValue = 0;
            int idx = _augmentations.IndexOf((int)key);
            if (idx >= 0) { pValue = 1; return true; }
            return false;
        }

        public int SpellBarCount(int barNumber) => 0;
        public int SpellBar(int barNumber, int index) => 0;
        public int AugmentationCount() => _augmentations.Count;
        public int Augmentation(int index) => index >= 0 && index < _augmentations.Count ? _augmentations[index] : 0;
        public int[] SpellbookArray => _spellbook.ToArray();
        public int[] AugmentationArray => _augmentations.ToArray();
        public int[] SpellBarArray(int barNumber) => Array.Empty<int>();

        // INetworkFilter2
        public void Initialize(NetService pService) { }
        public void Terminate() { }

        public void DispatchServer(IMessage2 Message)
        {
            // Process character stat updates from network messages
        }

        public void DispatchClient(IMessage2 Message) { }
    }
}
