// Decompiled with JetBrains decompiler
using Plus.Communication.Packets.Outgoing;
using Plus.Communication.Packets.Outgoing.Rooms.Polls;
using Plus.Database.Interfaces;
using Plus.HabboHotel.GameClients;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;

namespace Plus.HabboHotel.Rooms.Polls
{
    public static class RoomPollManager
    {
        public static int POLL_DECLINE_TIMEOUT = 1800;
        public static List<Poll> Polls;
        public static List<UserPollData> UsersCachedPolls;
        public static Dictionary<int, UserPollData> UsersAnsweringPolls;
        public static List<UserPollDecline> UsersDeclinedPolls;

        public static bool Initialized { get; private set; }

        public static void Init()
        {
            if (Initialized)
                return;
            Polls = new List<Poll>();
            UsersAnsweringPolls = new Dictionary<int, UserPollData>();
            UsersCachedPolls = new List<UserPollData>();
            UsersDeclinedPolls = new List<UserPollDecline>();
            FlushData();
            PlusEnvironment.GetGame().GetClientManager().OnClientDisconnect += new GameClientManager.ClientDisconnected(RoomPollManager_OnClientDisconnect);
            Initialized = true;
        }

        private static void RoomPollManager_OnClientDisconnect(GameClient client)
        {
            int id = client.GetHabbo().Id;
            if (!UsersAnsweringPolls.ContainsKey(id))
                return;
            UsersAnsweringPolls.Remove(id);
        }

        public static void TrySendPollInvinte(int roomid, GameClient Session)
        {
            Poll poll = GetPollByRoomId(roomid);
            if (poll == null || IsDeclined(Session.GetHabbo().Id, poll.Id) || UsersCachedPolls.Count((c =>
            {
                if (c.PollId == poll.Id)
                    return c.UserId == Session.GetHabbo().Id;
                return false;
            })) >= poll.Limit)
                return;
            Session.SendMessage(new SendPollInvinteComposer(poll));
        }

        public static bool TryGetPoll(int Id, out Poll poll)
        {
            poll = GetPoll(Id);
            return poll != null;
        }

        public static void DeclinePoll(int userid, int pollid)
        {
            UsersDeclinedPolls.Add(new UserPollDecline(userid, pollid, checked((int)PlusEnvironment.GetUnixTimestamp())));
        }

        public static bool IsDeclined(int userid, int pollid)
        {
            UserPollDecline userPollDecline = UsersDeclinedPolls.FirstOrDefault((c =>
            {
                if (c.UserId == userid)
                    return c.PollId == pollid;
                return false;
            }));
            if (userPollDecline == null)
                return false;
            if (!userPollDecline.CanInvinteAgain)
                return true;
            UsersDeclinedPolls.Remove(userPollDecline);
            return false;
        }

        public static Poll GetPoll(int id)
        {
            return Polls.FirstOrDefault((c => c.Id == id));
        }

        public static Poll GetPoll(string code)
        {
            return Polls.FirstOrDefault(c => c.CodeName == code);
        }

        public static Poll GetPollByRoomId(int roomid)
        {
            return Polls.FirstOrDefault(c => c.RoomId == roomid);
        }

        public static void RemovePoll(Poll Poll)
        {
            Polls.Remove(Poll);
        }

        public static void StartUserAnsweringPoll(int userid, int pollid)
        {
            if (GetPoll(pollid) == null)
                return;
            RemoveUserAnsweringPoll(userid);
            UsersAnsweringPolls.Add(userid, new UserPollData(userid, pollid));
        }

        public static UserPollData GetUserAnsweringPoll(int userid, int pollid)
        {
            if (!UsersAnsweringPolls.ContainsKey(userid))
                return null;
            UserPollData usersAnsweringPoll = UsersAnsweringPolls[userid];
            if (usersAnsweringPoll.PollId == pollid)
                return usersAnsweringPoll;
            UsersAnsweringPolls.Remove(userid);
            return null;
        }

        public static void RemoveUserAnsweringPoll(int userid)
        {
            if (!UsersAnsweringPolls.ContainsKey(userid))
                return;
            UsersAnsweringPolls.Remove(userid);
        }

        public static void FinishuserAnsweringPoll(int userid)
        {
            if (!UsersAnsweringPolls.ContainsKey(userid))
                return;
            UserPollData usersAnsweringPoll = UsersAnsweringPolls[userid];
            usersAnsweringPoll.Finish();
            UsersAnsweringPolls.Remove(userid);
            UsersCachedPolls.Add(usersAnsweringPoll);
        }

        public static void FlushData()
        {
            Polls.Clear();
            DataTable table1;
            using (IQueryAdapter queryReactor = PlusEnvironment.GetDatabaseManager().GetQueryReactor())
            {
                queryReactor.SetQuery("SELECT * FROM server_polls");
                table1 = queryReactor.getTable();
            }
            foreach (DataRow row in (InternalDataCollectionBase)table1.Rows)
            {
                Poll poll = new Poll(row);
                Polls.Add(poll);
            }
            using (IQueryAdapter queryReactor = PlusEnvironment.GetDatabaseManager().GetQueryReactor())
            {
                queryReactor.SetQuery("SELECT * FROM server_polls_users");
                table1 = queryReactor.getTable();
            }
            DataTable table2;
            using (IQueryAdapter queryReactor = PlusEnvironment.GetDatabaseManager().GetQueryReactor())
            {
                queryReactor.SetQuery("SELECT * FROM server_polls_users_answers");
                table2 = queryReactor.getTable();
            }
            foreach (DataRow row in (InternalDataCollectionBase)table1.Rows)
                UsersCachedPolls.Add(new UserPollData(row, table2));
        }
    }
}
