using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using SvetoforVKBot.Models;
using SvetoforVKBot.Models.Commands.Admin;
using SvetoforVKBot.Models.Updates;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Web.Mvc;
using VkNet;
using VkNet.Enums.SafetyEnums;
using VkNet.Model;
using VkNet.Model.Attachments;
using VkNet.Model.Keyboard;
using VkNet.Model.RequestParams;
using System.Linq;
using System.Configuration;
using SvetoforVKBot.App_Start;

namespace SvetoforVKBot.Controllers
{
    public class NotifiesController : Controller
    {
        // Подключаем контекст базы данных
        private SvetoforVKBot.Data.SvetoforVKBotEntities db = new SvetoforVKBot.Data.SvetoforVKBotEntities();
        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }



        // GET: Notifies

        public HttpStatusCodeResult Execute()
        {
            MessagesSendParams @params = new MessagesSendParams();
            MessagesSendParams @params2 = new MessagesSendParams();
            HttpStatusCodeResult httpResult = new HttpStatusCodeResult(200);
            //SqlConnection Con = new SqlConnection(AppSettings.ConnectionString);

            var client = new VkApi();
            var keyboardBuilder = new KeyboardBuilder().Clear();
            var keyboardBuilder2 = new KeyboardBuilder().Clear();
            DateTime dt = DateTime.Now.AddHours(0);
            List<OrderLog> orders = new List<OrderLog>();
            string highWorkload = "0";
            List<int> ids = new List<int>();
            List<int> ids2 = new List<int>();
            List<int> idsFood = new List<int>();
            List<UserObject> waterNotifiesList = new List<UserObject>(); 
            string msg = "";

            string name = "";
            int age = 0;
            int genderCoef = 0;
            double kkalResult = 0;
            double colorPercent = 0;
            double dayCoef = 0;
            double curDayKkal = 0;
            double kkalResultLow = 0;
            double kkalResultHigh = 0;
            try
            {
                client.AuthorizeAsync(new ApiAuthParams
                {
                    AccessToken = ((WebConfiguration)ConfigurationManager.GetSection("VKApi")).Token
                });

                
                if (DateTime.Now.DayOfWeek == DayOfWeek.Monday && DateTime.Now.Hour == 11)
                {
                    ids = db.Users.Where(e => e.notifyCount > 0 && e.reg == 1 && e.waterNotify == 0).ToList().ConvertAll(e => e.chatId);

                    @params.Message = "Зачем организму нужна вода?🤔\n\n" +
                        "Наш организм можно сравнить с отлаженным часовым механизмом. Для его запуска необходимо наладить питьевой режим.\n" +
                        "Роль жидкости неоценима: именно она наполняет энергией в течение дня, заряжает силами на работу и учебу, служит " +
                        "питанием для физических и умственных процессов.\n\n" +
                        "Мы поможем Вам сформировать привычку пить достаточное количество воды!💦\n" +
                        "Нажмите \"Напоминать\" и в течение дня Вам будут приходить напоминания о необходимости выпить стакан воды.";

                    keyboardBuilder
                            .AddButton("Напоминать", "selectGoWaterNotify", KeyboardButtonColor.Positive)
                            .AddLine()
                            .AddButton("Неинтересно", "selectWaterNotifyCount-10", KeyboardButtonColor.Negative)
                            .AddLine()
                            .AddButton("Личный кабинет", "startPL", KeyboardButtonColor.Primary)
                            .SetInline();

                    foreach (var id in ids)
                    {
                        @params.Keyboard = keyboardBuilder.Build();
                        @params.UserId = id;
                        @params.RandomId = GetRandomId();
                        client.Messages.SendAsync(@params);

                        Thread.Sleep(500);
                    }
                }
                
                if (DateTime.Now.Hour == 7 && DateTime.Now.DayOfWeek != DayOfWeek.Saturday && DateTime.Now.DayOfWeek != DayOfWeek.Sunday)
                //if (false)
                {
                    //Проверить корректность работы
                    db.Users.ToList().ForEach(e => { e.choosenProducts = "[]"; e.cart = "{\"orders\":[]}"; });
                    db.SaveChanges();

                    idsFood = db.Users.Where(e => e.notifyCount >= 1 && e.weight != 0 && e.height != 0 && e.reg == 1 && e.track != 0).ToList().ConvertAll(e => e.chatId);

                    Dictionary<int, string> tracks = new Dictionary<int, string>(7);
                    tracks.Add(1, "Оптимизация питания");
                    tracks.Add(2, "Снижение жировой массы");
                    tracks.Add(3, "Увеличение мышечной массы");
                    tracks.Add(4, "Персональный режим");

                    //idsFood = new List<int>{3158149, 10160301 };
                    //idsFood = new List<int>{59111081};
                    foreach (var idFood in idsFood)
                    {
                        keyboardBuilder.Clear();

                        var user = db.Users.Single(usr => usr.chatId == idFood);
                        var jsPhones = JsonConvert.DeserializeObject<List<string>>(user.phone);

                        if ((DateTime.Now.Month >= user.birthday.Month) && (DateTime.Now.Day >= user.birthday.Day))
                            age = DateTime.Now.Year - user.birthday.Year;
                        else
                            age = DateTime.Now.Year - user.birthday.Year - 1;

                        #region ccalCalculator
                        Dictionary<int, string> days = new Dictionary<int, string>(7);
                        days.Add(1, "Понедельник");
                        days.Add(2, "Вторник");
                        days.Add(3, "Среда");
                        days.Add(4, "Четверг");
                        days.Add(5, "Пятница");
                        days.Add(6, "Суббота");
                        days.Add(7, "Воскресенье");

                        Dictionary<int, string> gend = new Dictionary<int, string>(3);
                        gend.Add(0, "Мужской");
                        gend.Add(1, "Мужской");
                        gend.Add(2, "Женский");

                        int curDay = (int)DateTime.Now.DayOfWeek;
                        if (curDay == 0) curDay = 7;

                        int nextDay = curDay + 1;

                        if (nextDay == 8)
                            nextDay = 1;

                        if (user.gender == 1)
                        {
                            genderCoef = 5;
                        }
                        else
                        {
                            genderCoef = -161;
                        }
                        switch (user.track)
                        {
                            case 1: //не изменяя веса
                                colorPercent = 1;
                                break;
                            case 2:
                                colorPercent = 0.75; //1 - 15%
                                break;
                            case 3:
                                colorPercent = 1.2; //1 - 15%
                                break;
                            default:
                                colorPercent = 1;
                                break;
                        }

                        for (int i = 1; i <= 7; i++)
                        {
                            switch (i)
                            {
                                case 2:
                                    dayCoef = 0.8;
                                    break;

                                case 3:
                                    dayCoef = 1.2;
                                    break;

                                case 5:
                                    dayCoef = 0.9;
                                    break;

                                case 6:
                                    dayCoef = 1.1;
                                    break;

                                default:
                                    dayCoef = 1;
                                    break;
                            }

                            kkalResult = Math.Round((((10 * user.weight) + (6.25 * user.height) - (5 * age) + genderCoef) * user.activityCoef) * colorPercent * dayCoef);
                            kkalResultHigh = Math.Round(kkalResult * 1.2);
                            kkalResultLow = Math.Round(kkalResult * 0.9);

                            if (i == curDay)
                            //if (i == curDay)
                            {
                                curDayKkal = kkalResult;
                            }
                        }
                        #endregion ccalCalculator


                        user.kkal = Convert.ToInt32(curDayKkal);
                        db.SaveChanges();

                        @params.Message = "☀Доброе утро!\n" +
                            $"Ваша норма калорий на сегодня: {Math.Round(curDayKkal * 0.9)} - {Math.Round(curDayKkal * 1.2)}\n" +
                            "Мы подготовили для Вас блюда👇🏻\n\n" +
                            "Меню также доступно в Личном кабинете в разделе \"Дневной рацион\"";

                        keyboardBuilder
                            .AddButton($"Завтрак (до {Math.Round(curDayKkal * 1.2 * 0.3)} ккал)", "selectPersonalMenu-1-" + Math.Round(curDayKkal), KeyboardButtonColor.Primary)
                            .AddLine()
                            .AddButton($"Обед (до {Math.Round(curDayKkal * 1.2 * 0.4)} ккал)", "selectPersonalMenu-2-" + Math.Round(curDayKkal), KeyboardButtonColor.Primary)
                            .AddLine()
                            .AddButton($"Перекус (до {Math.Round(curDayKkal * 1.2 * 0.1)} ккал)", "selectPersonalMenu-3-" + Math.Round(curDayKkal), KeyboardButtonColor.Primary)
                            .AddLine()
                            .AddButton($"Ужин (до {Math.Round(curDayKkal * 1.2 * 0.3)} ккал)", "selectPersonalMenu-4-" + Math.Round(curDayKkal), KeyboardButtonColor.Primary)
                            .AddLine()
                            .AddButton("Личный кабинет", "startPL", KeyboardButtonColor.Default)
                            .SetInline();

                        @params.Keyboard = keyboardBuilder.Build();
                        @params.UserId = idFood; //10160301;
                        @params.RandomId = GetRandomId();
                        client.Messages.SendAsync(@params);

                        Thread.Sleep(1500);
                    }
                }

                if (DateTime.Now.Hour == 10 ||
                    DateTime.Now.Hour == 12 ||
                    DateTime.Now.Hour == 14 ||
                    DateTime.Now.Hour == 16 ||
                    DateTime.Now.Hour == 18 ||
                    DateTime.Now.Hour == 20)
                {

                    waterNotifiesList = db.Users.Where(e => e.waterNotify >= 1 && e.waterNotify != 10).ToList().ConvertAll(e => new UserObject() {
                        chatId = e.chatId,
                        waterNotify = e.waterNotify
                    });

                    @params2.Message = "🍹💦Время выпить воды!";

                    keyboardBuilder2
                        .AddButton("Личный кабинет", "startPL", KeyboardButtonColor.Primary)
                        .AddLine()
                        .AddButton("Отключить уведомления", "selectOffWaterNotify", KeyboardButtonColor.Default)
                        .SetInline();

                    foreach (var us in waterNotifiesList)
                    {
                        if (us.waterNotify == 1 && DateTime.Now.Hour == 14)
                        {
                            @params2.Keyboard = keyboardBuilder2.Build();
                            @params2.UserId = us.chatId;
                            @params2.RandomId = GetRandomId();
                            client.Messages.SendAsync(@params2);
                        }
                        else if (us.waterNotify == 3 && (DateTime.Now.Hour == 10 || DateTime.Now.Hour == 14 || DateTime.Now.Hour == 18))
                        {
                            @params2.Keyboard = keyboardBuilder2.Build();
                            @params2.UserId = us.chatId;
                            @params2.RandomId = GetRandomId();
                            client.Messages.SendAsync(@params2);
                        }
                        else if (us.waterNotify == 6)
                        {
                            @params2.Keyboard = keyboardBuilder2.Build();
                            @params2.UserId = us.chatId;
                            @params2.RandomId = GetRandomId();
                            client.Messages.SendAsync(@params2);
                        }
                        Thread.Sleep(500);
                    }
                }
                return httpResult;
                
            }
            catch (Exception ee)
            {
                @params.Message = "‼Ошибка в NotifiesController: " + ee.Message;
                @params.Attachments = null;
                @params.Keyboard = null;
                @params.UserId = 59111081; 
                @params.RandomId = GetRandomId();
                client.Messages.Send(@params);
                return httpResult;
            }
        }

        private static readonly RandomNumberGenerator Rng = RandomNumberGenerator.Create();
        private int GetRandomId()
        {

            var intBytes = new byte[4];

            Rng.GetBytes(intBytes);

            return BitConverter.ToInt32(intBytes, 0);
        }
        
    }
}