using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using PARR.API.Contracts.V1;
using PARR.API.Contracts.V1.Responses.Base;
using PARR.API.Controllers.V1.Base;
using PARR.API.Services.Interfaces;
using PARR.API.Settings;
using PARR.Core.Common.Interfaces;
using PARR.Core.Repositories.Interfaces;
using PARR.Core.Repositories.Interfaces.Unit;
using PARR.Core.Services.NextRunServices;
using PARR.Core.Services.UnitService.Interfaces;
using PARR.Core.Services.Workload.Implementations;
using PARR.Domain.Cache;

namespace PARR.API.Controllers.V1
{
    [Authorize]
    public class TestController : BaseApiController
    {
        private readonly IClientService clientService;
        private readonly IRedisCacheService redisCacheService;
        private readonly INextRunService nextRunService;
        private readonly ITemplateRepository templateService;
        private readonly WorkloadCacheService workloadCacheService;
        private readonly ILogger<TestController> logger;
        private readonly IUnitService unitService;
        private readonly IUnitRepository unitRepository;

        public TestController(
            IClientService clientService,
            IRedisCacheService redisCacheService,
            INextRunService nextRunService,
            ITemplateRepository templateService,
            MqSettings mqSettings,
            WorkloadCacheService workloadCacheService,
            ILogger<TestController> logger,
            IUnitService unitService,
            IUnitRepository unitRepository
            )
        {
            this.clientService = clientService;
            this.redisCacheService = redisCacheService;
            this.nextRunService = nextRunService;
            this.templateService = templateService;
            this.workloadCacheService = workloadCacheService;
            this.logger = logger;
            this.unitService = unitService;
            this.unitRepository = unitRepository;
        }


        /// <summary>
        /// Получить мой ip
        /// </summary>
        /// <returns></returns>
        [HttpGet(ApiRoutes.Test.GetMyIp)]
        public IActionResult GetMyIp()
        {
            var ipAddress = clientService.GetClientIp();

            var ip = ipAddress?.ToString();

            return Ok(new Response<object>(new { ip }, true));
        }


        public record GetNextRunRequest(Guid TemplateId, bool IsNew);

        /// <summary>
        /// Получить nextRun
        /// </summary>
        /// <returns></returns>
        [HttpPost(ApiRoutes.Test.GetNextRun)]
        public async Task<IActionResult> GetNextRun([FromBody] GetNextRunRequest request)
        {
            var nextRun = await nextRunService.GetNextRunForTemplateAsync(request.TemplateId, request.IsNew);
            var template = await templateService.GetAsync(request.TemplateId);

            return Ok(new Response<object>(new { OldNextRun = template?.NextRun, NewNextRun = nextRun }, true));
        }



        /// <summary>
        /// Записать в кэш
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost(ApiRoutes.Test.CreateCache)]
        public async Task<IActionResult> CreateCache([FromBody] Guid unitId)
        {
            //var units = await unitRepository.Get().Take(100000).Select(t => t.Id).ToListAsync();
            //var listData = await unitService.GetWithCachingAsync(units);
            //foreach(var unit in units)
            //{
            //    //поштучно
            //    var unitTtt = await unitService.GetWithCachingAsync(unit);
            //}

            // удалить элемент
            //await unitService.RemoveFromCacheAsync(Guid.Parse("79833f20-a84f-45f4-a4ed-0dae09b683d7"));

            // todo: проверить удаление пачки юнитов !!!!!!!!!!!!!!!!!!!!!
            //await unitService.RemoveFromCacheAsync(units);


            return Ok();

            //var unit = await unitService.GetWithCachingAsync(unitId);

            //return Ok(unit);

            //#region Test bucket id

            //var idList = new List<Guid>();

            //for (int i = 0; i < 100; i++)
            //    idList.Add( Guid.NewGuid());

            //foreach(var id in idList.OrderBy(t => t))
            //{
            //    var key = CacheKeys.Unit.UnitHashWithBucket(id);
            //    var redisKey = redisCacheService.GetKey(key);

            //    logger.LogDebug("Id: {Id}, key: '{Key}', redis key: '{RedisKey}'", id, key, redisKey);
            //}

            //#endregion


            // var aaa = await workloadCacheService.GetTemplateReportDataAsync();

            //var val = await redisCacheService.GetCachedDataAsync<object>("96dAoIH/8Q9Bg8VY");

            //var hashKey = redisCacheService.GetKey(new[] { "test", "mxa" });
            //var ttl = TimeSpan.FromMinutes(10);

            //await redisCacheService.SetHashFieldAsync(hashKey, "t1", "val1", ttl);
            //await redisCacheService.SetHashFieldAsync(hashKey, "t2", "val2");
            //await redisCacheService.SetHashFieldAsync(hashKey, "t3", "val3");

            //var length = await redisCacheService.GetHashLengthAsync(hashKey);

            //var get = await redisCacheService.GetHashFieldAsync<string>(hashKey, "t1");

            //var getAll = await redisCacheService.GetAllHashFieldsAsync<string>(hashKey);

            //await redisCacheService.DeleteHashFieldAsync(hashKey, "t1");
            //var getT1 = await redisCacheService.GetHashFieldAsync<string>(hashKey, "t1");

            //var exist = await redisCacheService.HashFieldExistsAsync(hashKey, "t2");

            //await redisCacheService.DeleteHashAsync(hashKey);
            //var getT_1 = await redisCacheService.GetHashFieldAsync<string>(hashKey, "t1");

            //await redisCacheService.SetHashTtlAsync(hashKey, ttl);

            return Ok();
        }







    }

}
