using Microsoft.AspNetCore.Mvc;
using Nop.Web.Framework.Controllers;
using Nop.Web.Framework.Mvc.Filters;
using Nop.Web.Framework;
using Nop.Plugin.Misc.AuctionPlugin.Areas.Admin.Models;
using Nop.Services.Configuration;
using Nop.Plugin.Misc.AuctionPlugin;
using Nop.Services.Messages;
using Nop.Services.Localization;
using Nop.Services.Logging;
using Nop.Plugin.Misc.AuctionPlugin.Domains.Entities;
using Nop.Plugin.Misc.AuctionPlugin.Services;
using Nop.Web.Framework.Models.DataTables;
using Nop.Plugin.Misc.AuctionPlugin.Models;
using AyCode.Core.Extensions;
using Nop.Plugin.Misc.AuctionPlugin.Domains.Entities.Interfaces;

namespace Nop.Plugin.Misc.AuctionPlugin.Areas.Admin.Controllers;

//[AutoValidateAntiforgeryToken]
//[AuthorizeAdmin]
[Area(AreaNames.ADMIN)]
public class AuctionPluginAdminController : BasePluginController
{
    //private readonly SignalRservice _signalRservice;
    protected readonly ILocalizationService _localizationService;
    protected readonly INotificationService _notificationService;
    protected readonly ISettingService _settingService;
    protected readonly AuctionSettings _auctionSettings;
    protected readonly AuctionService _auctionService;
    protected readonly ILogger _logger;
    
    //public AuctionPluginAdminController(SignalRservice signalRservice)
    public AuctionPluginAdminController(ILocalizationService localizationService, INotificationService notificationService, ISettingService settingService, AuctionSettings auctionSettings, ILogger logger, AuctionService auctionService)
    {
        _localizationService = localizationService;
        _notificationService = notificationService;
        _settingService = settingService;
        _auctionSettings = auctionSettings;
        //_signalRservice = signalRservice;
        _auctionService = auctionService;
        _logger = logger;
    }

    public async Task<IActionResult> Configure(bool showtour = false)
    {
        return View("~/Plugins/Misc.AuctionPlugin/Areas/Admin/Views/Configure.cshtml", new ConfigurationModel());
    }

    [HttpPost, ActionName("Configure")]
    [FormValueRequired("save")]
    public async Task<IActionResult> Configure(ConfigurationModel model)
    {
        if (!ModelState.IsValid)
        {

            await _logger.ErrorAsync($"Auction configuration model error: invalid modelstate!");
            return await Configure();

        }

        if (_auctionSettings.SomeText != model.Test)
        {
            _auctionSettings.SomeText = model.Test;
            await _logger.InformationAsync($"Auction configuration saving: {_auctionSettings.SomeText}");

        }

        await _settingService.SaveSettingAsync(_auctionSettings);
        await _logger.InformationAsync($"Auction configuration saved: {_auctionSettings.SomeText}");
        //_notificationService.SuccessNotification(await _localizationService.GetResourceAsync("Admin.Plugins.Saved"));
        _notificationService.SuccessNotification("Saved");

        return await Configure();
    }

    //[HttpPost]
    //public async Task<IActionResult> TestHubConnection(string message)
    //{
    //    try
    //    {
    //        await _signalRservice.TestHub();
    //        return Json(new { success = true, message = $"Hub successfully called - {message}" });
    //    }
    //    catch (Exception ex)
    //    {
    //        return Json(new { success = false, message = $"Error: {ex.Message}" });
    //    }
    //}

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

    
    public async Task<IActionResult> AuctionList()
    {
        await _logger.InformationAsync("AnnouncementList called!");

        var model = new AuctionViewModel();
        return View("~/Plugins/Misc.AuctionPlugin/Areas/Admin/Views/AuctionList.cshtml", model);
    }

    [HttpPost]
    public async Task<IActionResult> GetAuctionViewModel(AuctionViewModel viewModel)
    {
        viewModel.AuctionDto = new Domains.Dtos.AuctionDto();
        viewModel.AuctionDto.AuctionName = viewModel.AuctionName;
        viewModel.AuctionDto.AuctionType = viewModel.AuctionType;
        viewModel.AuctionDto.Closed = viewModel.Closed;
        viewModel.AuctionDto.StartDateUtc = viewModel.StartDateUtc;
        viewModel.AuctionDto.EndDateUtc = viewModel.EndDateUtc;
        var objOfAuctionDomain = viewModel.AuctionDto.CreateMainEntity();


        await _auctionService.InsertAuctionAsync(objOfAuctionDomain);

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

    }

    [HttpPost]
    public async Task<IActionResult> GetAuctionList()
    {
        //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 _auctionService.GetAllAuctionsAsync() });
        }
        catch (Exception ex)
        {
            return BadRequest(ex);
        }
    }

    public async Task<IActionResult> TestPage()
    {
        var model = new TestPageViewModel();

        var auctions = await _auctionService.GetAllAuctionsAsync();
        var auctionDtoWithProducts = await _auctionService.GetAuctionDtoWithProductByIdAsync(1, 4, false);

        model.Message = $"Teszt üzenet; Auctions count: {auctions.Count}; Products count: {auctionDtoWithProducts.ProductToAuctionDtos.Count}";

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

    
    public async Task<IActionResult> AssignProductToAuction()
    {
        _logger.Information("AssignProductToAuction has been called");

        var result = await _auctionService.GetProductToAuctionsByAuctionIdAsync(1, false);

        return Ok(result.ToJson());
    }

    [HttpPost]
    public async Task<IActionResult> AssignProductToAuction([FromBody] AssignAuctionRequestModel model)
    {
        _logger.Information("AssignProductToAuction has been called");

        if (Convert.ToInt32(model.ProductId) <= 0 || Convert.ToInt32(model.AuctionId) <= 0)
            return BadRequest();

        var result = await _auctionService.AssignProductToAuctionAsync(Convert.ToInt32(model.ProductId), 
            Convert.ToDecimal(model.StartingPrice), Convert.ToDecimal(model.BidPrice), Convert.ToInt32(model.AuctionId), model.SortIndex);
        
        return result != null ? Ok("Baaaazdmeeeeeeeeg") : StatusCode(500, "Error assigning product to auction.");
    }

    public async Task<IActionResult> GetAuctionById(int id)
    {
        var auction = await _auctionService.GetAuctionDtoByIdAsync(id, true, false);
        if (auction == null)
            return NotFound();

        var result = Json(new
        {
            id = auction.Id,
            categoryId = auction.CategoryId,
            auctionName = auction.AuctionName,
            startDateUtc = auction.StartDateUtc,
            endtDateUtc = auction.EndDateUtc,
            closed = auction.Closed
        });
        return result;
    }

    [HttpPost]
    public async Task<IActionResult> SaveAuction(Auction auction)
    {
        var dbAuction = await _auctionService.GetAuctionByIdAsync(auction.Id);
        if (auction != null)
        {
            dbAuction.AuctionName = auction.AuctionName;
            dbAuction.CategoryId = auction.CategoryId;
            dbAuction.StartDateUtc = auction.StartDateUtc;
            dbAuction.EndDateUtc = auction.EndDateUtc;
            dbAuction.Closed = auction.Closed;
            await _auctionService.UpdateAuctionAsync(dbAuction);
        }
        return Ok();
    }
}
