using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;

namespace ISIM
{
    public static class ElisCore
    {
        public static readonly CommunicationCore cc;

        static ElisCore()
        { 
            if (Global.elisActivated)
                cc = new CommunicationCore();
        }

        private static Dictionary<string, DateTime> lastMessagesTime = new Dictionary<string, DateTime>();

        /// <summary>
        /// Pokud mám povolené odpovídání a jsem afk nebo dnd - elis odešle informaci o této skučenosti
        /// </summary>
        /// <param name="contact"></param>
        /// <param name="doNotRespond">Označuje - zda se má pouze uložit čas zprávy (false) nebo zda se má případně i reagovat (true). Pokud píši já kontaktu nebo je zpráva od elis - uložím pouze čas zprávy a neodpovídám</param>
        public static void AutoRespond(ISIMContact contact, bool doNotRespond = false)
        {
            if (!(((Global.settingsDictionary["ISIMsettings"].ContainsKey("autoRespondCheckBox")) && (bool.Parse(Global.settingsDictionary["ISIMsettings"]["autoRespondCheckBox"]))) && ((Global.away) || (Global.dnd))))
                return;

            DateTime contactLastMessageTime = DateTime.MinValue;
            if (!lastMessagesTime.ContainsKey(contact.id))
                lastMessagesTime.Add(contact.id, DateTime.Now);
            else
            {
                contactLastMessageTime = lastMessagesTime[contact.id];
                lastMessagesTime[contact.id] = DateTime.Now;
            }

            if ((!doNotRespond) && (contactLastMessageTime < DateTime.Now.AddMinutes(-5)))
            {
                string contactName = contact.name == contact.id ? ISIM.Global.Converter.GetRenamedContactName(contact) : contact.name;
                if (Global.LangManager.currentCulture == "cs-CZ")
                {
                    SklonovaniCeskychJmen sklonovani = new SklonovaniCeskychJmen();
                    contactName = sklonovani.Sklonuj(contactName);
                }
                string respondMessage = "Elis: " + Global.LangManager.Translate("hello") + " " + contactName + ". " + Global.LangManager.Translate("iAmSorryBut") + " " + Global.LangManager.Translate("myLord") + " ";
                if (Global.dnd)
                    respondMessage += Global.LangManager.Translate("isDND") + ".";
                else
                    respondMessage += Global.LangManager.Translate("isAFK") + ".";

                if ((Global.settingsDictionary["ISIMsettings"].ContainsKey("awayReason")) && (Global.settingsDictionary["ISIMsettings"]["awayReason"].Replace(" ", "").Length > 0))
                    respondMessage += " " + Global.LangManager.Translate("message") + ": " + Global.settingsDictionary["ISIMsettings"]["awayReason"];

                Global.ISIMFunctions.SendChatMessage(contact, respondMessage, false);
                Global.ISIMFunctions.AddChatMessage(contact, respondMessage, DateTime.Now, Global.ISIM);
            }
        }




        /// <summary>
        /// Nech se Elis vykecává :)))
        /// </summary>
        /// <param name="contact"></param>
        public static void IQPokydRespond(ISIMContact contact, string message)
        {
            if (!Global.elisActivated) return;
            if (TextEdit.EmoticonsList.Keys.Contains(message.Trim())) return;// na smajlíky neodpovídá

            Thread replyThread = new Thread(new ThreadStart(() => IQPokydRespondCallback(contact, message)));
            replyThread.Start();
        }

        private static void IQPokydRespondCallback(ISIMContact contact, string message)
        {
            Random rand = new Random();
            Thread.Sleep(rand.Next(3, 7) * 1000);

            string elisMessage = cc.buildReply(message);

            Global.ISIMFunctions.SendChatMessage(contact, elisMessage, false);
            Global.ISIMFunctions.AddChatMessage(contact, elisMessage, DateTime.Now, Global.ISIM);
        }
    }

    public class CommunicationCore
    {
        private delegate void voidPointer();
        private delegate string stringPointer(string message);

        [DllImport("kernel32")]
        public extern static IntPtr LoadLibrary(string librayName);

        [DllImport("kernel32")]
        public extern static IntPtr GetProcAddress(IntPtr hwnd, string procedureName);

        [DllImport("kernel32")]
        public static extern IntPtr FreeLibrary(IntPtr hModule);


        IntPtr iq_dll = LoadLibrary(Global.appRunPath + "plugins\\IQPokyd.dll");

        IntPtr iq_dll_start;
        IntPtr iq_dll_reply;
        IntPtr iq_dll_exit;

        voidPointer START;
        stringPointer REPLY;
        voidPointer EXIT;

        public CommunicationCore()
        {
            string saveCurDir = Directory.GetCurrentDirectory();
            Directory.SetCurrentDirectory(Global.appRunPath + "plugins");
            iq_dll_start = GetProcAddress(iq_dll, "KYBLSoft_IQ_Pokyde_Nastartuj_Se");
            iq_dll_reply = GetProcAddress(iq_dll, "KYBLSoft_IQ_Pokyde_Odpovez_Na_Vetu");
            iq_dll_exit = GetProcAddress(iq_dll, "KYBLSoft_IQ_Pokyde_Ukonci_Se");

            START = (voidPointer)Marshal.GetDelegateForFunctionPointer(iq_dll_start, typeof(voidPointer));
            REPLY = (stringPointer)Marshal.GetDelegateForFunctionPointer(iq_dll_reply, typeof(stringPointer));
            EXIT = (voidPointer)Marshal.GetDelegateForFunctionPointer(iq_dll_exit, typeof(voidPointer));

            Directory.SetCurrentDirectory(saveCurDir);
        }

        public void start()
        {
            string saveCurDir = Directory.GetCurrentDirectory();
            Directory.SetCurrentDirectory(Global.appRunPath + "plugins");
            START();

            Directory.SetCurrentDirectory(Global.appRunPath);
            Console.WriteLine("IQ Pokyd byl zaveden - debug message");
        }

        // vrací hotovou odpověď
        public string buildReply(string recieved)
        {
            string saveCurDir = Directory.GetCurrentDirectory();
            Directory.SetCurrentDirectory(Global.appRunPath + "plugins");

            string message = REPLY(recieved);

            Directory.SetCurrentDirectory(saveCurDir);

            return message;
        }

        // uvolní alokovanou paměť a dll knihovnu
        public void finish()
        {
            try
            {
                string saveCurDir = Directory.GetCurrentDirectory();
                Directory.SetCurrentDirectory(Global.appRunPath + "plugins");

                EXIT();

                Directory.SetCurrentDirectory(saveCurDir);
            }
            catch (AccessViolationException)
            {
                Console.WriteLine("Chyba při čištění paměti IQ pokydu");
            }
            FreeLibrary(iq_dll);
        }
    }
}
