using DocumentFormat.OpenXml.EMMA;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Nop.Plugin.Misc.AuctionPlugin.Areas.Admin.Models;
using Nop.Plugin.Misc.AuctionPlugin.Domains;
using Nop.Plugin.Misc.AuctionPlugin.Domains.Entities;
using Nop.Plugin.Misc.AuctionPlugin.Hubs;
using Nop.Plugin.Misc.AuctionPlugin.Hubs.Messages;
using Nop.Plugin.Misc.AuctionPlugin.Services;
using Nop.Services.Logging;
using Nop.Web.Framework;
using Nop.Web.Framework.Controllers;
using Nop.Web.Framework.Models.DataTables;
using Nop.Web.Framework.Mvc;
using Nop.Web.Framework.Mvc.Filters;
using System;
using System.Linq;
using AyCode.Core.Extensions;

namespace Nop.Plugin.Misc.AuctionPlugin.Areas.Admin.Controllers
{
    [AutoValidateAntiforgeryToken]
    [AuthorizeAdmin]
    [Area(AreaNames.ADMIN)]
    public class AnnouncementController : BasePluginController
    {

        #region Field

        private readonly IAnnouncementService _announcementService;
        private IHubContext<AuctionHub> _announcementHubContext;
        private readonly ILogger _logger;

        #endregion

        #region Ctr

        public AnnouncementController(
            IAnnouncementService announcementService,
            IHubContext<AuctionHub> announcementHubContext,
            AuctionService auctionService,
            ILogger logger)
        {
            _announcementService = announcementService;
            _announcementHubContext = announcementHubContext;
            _logger = logger;
        }

        #endregion

        #region Methods    

        public IActionResult GetAnnouncementViewModel()
        {
            var model = new AnnouncementViewModel();
            return View("~/Plugins/Misc.AuctionPlugin/Areas/Admin/Views/Announcement.cshtml", model);
        }

        [HttpPost]
        public async Task<IActionResult> GetAnnouncementViewModel(AnnouncementViewModel viewModel)
        {
            Announcement objOfAnnouncementDomain = new Announcement();
            objOfAnnouncementDomain.Name = viewModel.Name;
            objOfAnnouncementDomain.Body = viewModel.Body;
            objOfAnnouncementDomain.IsActive = viewModel.IsActive;
            objOfAnnouncementDomain.Created = DateTime.UtcNow;
            await _announcementService.InsertAsync(objOfAnnouncementDomain);

            if (viewModel.IsActive == true)
            {
                var announcement = new MessageWrapper
                {
                    MessageType = "announcement",
                    Data = new AnnouncementMessage
                    {
                        Title = viewModel.Name,
                        Message = viewModel.Body,
                    }.ToJson()
                };

                var jsonMessage = JsonConvert.SerializeObject(announcement, Formatting.Indented, new JsonSerializerSettings
                {
                    ContractResolver = new CamelCasePropertyNamesContractResolver()
                });

                await _logger.InformationAsync($"sending announcements");
                await _announcementHubContext.Clients.All.SendAsync("send", jsonMessage);
                //await _announcementHubContext.Clients.All.SendAsync("send", viewModel.Body.ToString());
            }
            return RedirectToAction("AnnouncementList");

        }

        public async Task<IActionResult> SendBidNotificationViewModel()
        {
            var viewModel = new BidNotificationViewModel();
            viewModel.ProductName = "Picasso - Önarckép";
            viewModel.BidPrice = 200000;
            viewModel.NextStepAmount = AuctionService.GetStepAmount(viewModel.BidPrice);
            return View("~/Plugins/Misc.AuctionPlugin/Areas/Admin/Views/BidNotification.cshtml", viewModel);

        }

        [HttpPost]
        public async Task<IActionResult> SendBidNotificationViewModel(BidNotificationViewModel viewModel)
        {
            //AuctionBid objOfAuctionBid = new AuctionBid();
            //objOfAuctionBid.ProductId = 4;
            //objOfAuctionBid.BidPrice = viewModel.BidPrice;
            
            //objOfAuctionBid.Created = DateTime.UtcNow;
            //await _announcementService.InsertAsync(objOfAuctionBid);


            var bid = new MessageWrapper
            {
                MessageType = "bidNotification",
                Data = new BidNotificationMessage
                {
                    //AuctionDto = TODO: ??? - J.
                    ProductName = viewModel.ProductName,
                    CurrentPrice = viewModel.BidPrice,
                    NextStepAmount = viewModel.NextStepAmount,
                    //NextBidPrice = AuctionService.GetNextBidPrice(viewModel.BidPrice, startingPrice, viewModel.NextStepAmount)
                }.ToJson()
            };
            var jsonMessage = JsonConvert.SerializeObject(bid, Formatting.Indented,
        new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }
        );

            await _announcementHubContext.Clients.All.SendAsync("send", jsonMessage);


            return View("~/Plugins/Misc.AuctionPlugin/Areas/Admin/Views/BidNotification.cshtml", viewModel);

        }

        [HttpPost]
        public async Task<IActionResult> Edit(Announcement model)
        {
            var entity = await _announcementService.GetAnnouncementByIdAsync(model.Id);
            entity.Name = model.Name;
            entity.Body = model.Body;
            entity.IsActive = model.IsActive;
            entity.Created = DateTime.UtcNow;
            await _announcementService.UpdateAsync(entity);

            if (model.IsActive == true)
            {
                await _announcementHubContext.Clients.All.SendAsync("send", model.Body.ToString());
            }
            return RedirectToAction("AnnouncementList");

        }

        public async Task<IActionResult> Edit(int Id)
        {
            var singleAnnouncement = await _announcementService.GetAnnouncementByIdAsync(Id);
            var model = new Announcement();
            model.Id = singleAnnouncement.Id;
            model.Name = singleAnnouncement.Name;
            model.Body = singleAnnouncement.Body;
            model.IsActive = singleAnnouncement.IsActive;

            return View("~/Plugins/Misc.AuctionPlugin/Areas/Admin/Views/Announcement.cshtml", model);

        }

        public async Task<IActionResult> Delete(int Id)
        {
            var singleAnnouncement = await _announcementService.GetAnnouncementByIdAsync(Id);
            await _announcementService.DeleteAsync(singleAnnouncement);
            return new NullJsonResult();
        }


        public async Task<IActionResult> AnnouncementList()
        {
            await _logger.InformationAsync("AnnouncementList called!");
            var model = new AnnouncementViewModel();
            return View("~/Plugins/Misc.AuctionPlugin/Areas/Admin/Views/AnnouncementList.cshtml", model);
        }

        [HttpPost]
        //public async Task<IActionResult> GetAnnouncementList([FromBody] KendoGridRequestModel request)
        public async Task<IActionResult> GetAnnouncementList()
        {
            //await _logger.InformationAsync("GetAnnouncementList called!");
            //var total = (await _announcementService.GetAnnouncementsAsync()).Count();
            //var result = await _announcementService.GetAnnouncementsAsync(request.Page, request.PageSize);

            //return Json(new
            //{
            //    Data = result,
            //    Total = total
            //});

            try
            {
                return Ok(new DataTablesModel { Data = await _announcementService.GetAnnouncementsAsync() });
            }
            catch (Exception ex)
            {
                return BadRequest(ex);
            }
        }

        #endregion

    }

}
