using System;
using System.Data;
using System.Linq;
using System.Threading;
using System.Collections.Generic;

using FilterAPI.Networking;

namespace FilterTimers.Timers
{
    internal class IAbstateTimer
    {
        #region Timer Variables

        private Int32 Interval;
        private Int32 Duration;

        #endregion

        private Boolean IsDone = true;

        public IAbstateTimer(Int32 I, Int32 D)
        {
            Interval = I;
            Duration = D;

            Thread NewThread = new Thread(delegate ()
            {
                while (true)
                {
                    Thread.Sleep(Interval * 1000);

                    if (IsDone) { Run(); }
                }
            });

            NewThread.Start();
        }

        private void Run()
        {
            IsDone = false;

            try
            {
                String[] OnlinePlayers = Program.SQL.GetOnlinesIDs().ToArray();

                Dictionary<Int32, Dictionary<Byte, UInt16>> nOwnernItemIDs = Program.SQL.GetnItemIDsFornStorageType(8);

                foreach (String OnlinePlayer in OnlinePlayers)
                {
                    Int32 nCharNo = Program.SQL.GetnCharNoFromsID(OnlinePlayer);

                    Dictionary<String, Byte> AbstatesToGive = new Dictionary<String, Byte>();

                    foreach (DataRow Row in Program.ItemAbstates.Table.Rows)
                    {
                        if (nOwnernItemIDs.ContainsKey(nCharNo) && nOwnernItemIDs[nCharNo].ContainsValue(Convert.ToUInt16(Row.ItemArray[0])))
                        {
                             DataRow AbstateViewRow = Program.AbStateView.Table.Rows.Cast<DataRow>().Where(ItemArray => Convert.ToUInt16(ItemArray.ItemArray[0]) == Convert.ToUInt16(Row.ItemArray[2])).FirstOrDefault();

                            if (Convert.ToString(Row.ItemArray[1]) == "-") { AbstatesToGive.Add(Convert.ToString(AbstateViewRow.ItemArray[1]), Convert.ToByte(Row.ItemArray[3])); }
                            else
                            {
                                DataRow ItemAbstateGroupsRow = Program.ItemAbstateGroups.Table.Rows.Cast<DataRow>().Where(ItemArray => ItemArray.ItemArray[0].ToString() == Row.ItemArray[1].ToString()).FirstOrDefault();

                                if (!Convert.ToBoolean(ItemAbstateGroupsRow.ItemArray[2]))
                                {
                                    if (AbstatesToGive.ContainsKey(Convert.ToString(AbstateViewRow.ItemArray[1]))) { AbstatesToGive[Convert.ToString(AbstateViewRow.ItemArray[1])] += Convert.ToByte(Row.ItemArray[3]); }
                                    else { AbstatesToGive.Add(Convert.ToString(AbstateViewRow.ItemArray[1]), Convert.ToByte(ItemAbstateGroupsRow.ItemArray[1])); }
                                }
                                else
                                {
                                    DataRow[] GroupItems = Program.ItemAbstates.Table.Rows.Cast<DataRow>().Where(ItemArray => ItemArray.ItemArray[1].ToString() == ItemAbstateGroupsRow.ItemArray[0].ToString()).ToArray();

                                    Boolean HasAllItems = true;

                                    foreach (DataRow GroupItem in GroupItems)
                                    {
                                        if (!nOwnernItemIDs[nCharNo].ContainsValue(Convert.ToUInt16(Row.ItemArray[0]))) { HasAllItems = false; }
                                    }

                                    if (HasAllItems)
                                    {
                                        if (AbstatesToGive.ContainsKey(Convert.ToString(AbstateViewRow.ItemArray[1]))) { AbstatesToGive[Convert.ToString(AbstateViewRow.ItemArray[1])] += Convert.ToByte(Row.ItemArray[3]); }
                                        else { AbstatesToGive.Add(Convert.ToString(AbstateViewRow.ItemArray[1]), Convert.ToByte(ItemAbstateGroupsRow.ItemArray[1])); }
                                    }
                                }
                            }
                        }
                    }

                    foreach (String AbstateToGive in AbstatesToGive.Keys)
                    {
                        using (var LocalPacket = new Packet(5, 11))
                        {
                            LocalPacket.PacketWriter.Write(AbstateToGive);
                            LocalPacket.PacketWriter.Write(Duration * 1000);
                            LocalPacket.PacketWriter.Write(AbstatesToGive[AbstateToGive]);
                            LocalPacket.PacketWriter.Write(OnlinePlayer);

                            Program.LocalClient.SendPacket(LocalPacket);
                        }
                    }
                    
                    AbstatesToGive.Clear();
                }

                nOwnernItemIDs.Clear();
            }
            catch (Exception Error) { Program.SendConsoleText(ConsoleColor.Red, "Timers error - Gear abstate giver\n{0}", Error.ToString()); }

            IsDone = true;
        }
    }
}
