using System;
using System.Globalization;
using System.Threading.Tasks;
using FarmmapsApi.Models;
using FarmmapsApi.Services;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using static FarmmapsApi.Extensions;
using static FarmmapsApiSamples.Constants;


namespace FarmmapsVRApoten
{
    public class PotenService
    {
        private readonly ILogger<PotenService> _logger;
        private readonly FarmmapsApiService _farmmapsApiService;
        private readonly GeneralService _generalService;

        public PotenService(ILogger<PotenService> logger, FarmmapsApiService farmmapsApiService,
            GeneralService generalService)
        {
            _logger = logger;
            _farmmapsApiService = farmmapsApiService;
            _generalService = generalService;
        }

        public async Task<Item> CalculateApplicationMapAsync(Item cropfieldItem, Item inputItem, string meanDensity, string variation, bool countPerArea, bool useShadow, string inputLayerName = null)
        {
            var potenApplicationMapRequest = new TaskRequest()  { TaskType = VRAPLANTING_TASK };
            if (inputItem != null) {potenApplicationMapRequest.attributes["inputCode"] = inputItem.Code; }
            potenApplicationMapRequest.attributes["meanDensity"] = meanDensity;
            potenApplicationMapRequest.attributes["variation"] = variation;
            potenApplicationMapRequest.attributes["variation"] = variation;
            potenApplicationMapRequest.attributes["countPerArea"] = countPerArea.ToString();
            potenApplicationMapRequest.attributes["useShadow"] = useShadow.ToString();
            potenApplicationMapRequest.attributes["inputLayerName"] = inputLayerName;

            var taskCode = await _farmmapsApiService.QueueTaskAsync(cropfieldItem.Code, potenApplicationMapRequest);
            _logger.LogInformation($"itemTaskCode: {taskCode}");
            _logger.LogInformation($"potenTaskmapRequest: {potenApplicationMapRequest}");
            _logger.LogInformation($"potenTaskmapRequest type: {potenApplicationMapRequest.TaskType}");
            _logger.LogInformation($"cropfieldItemCode: {cropfieldItem.Code}");

            await PollTask(TimeSpan.FromSeconds(5), async (tokenSource) => {
                var itemTaskStatus = await _farmmapsApiService.GetTaskStatusAsync(cropfieldItem.Code, taskCode);
                _logger.LogInformation($"Waiting on calculation of application map; Status: {itemTaskStatus.State}");
                if (itemTaskStatus.IsFinished)
                    tokenSource.Cancel();
            });


            var itemTask = await _farmmapsApiService.GetTaskStatusAsync(cropfieldItem.Code, taskCode);
            if (itemTask.State == ItemTaskState.Error)
            {
                _logger.LogError($"Something went wrong with task execution: {itemTask.Message}");
                return null;
            }

            var itemName = $"VRAPoten";
            var applianceMapItem = await _generalService.FindChildItemAsync(cropfieldItem.Code,
                GEOTIFF_PROCESSED_ITEMTYPE, itemName,
                i => i.Updated >= itemTask.Finished.GetValueOrDefault(DateTime.UtcNow) &&
                            i.Name.ToLower().Contains(itemName.ToLower()));

            if (applianceMapItem == null)
            {
                _logger.LogError("Could not find the VRAPoten geotiff child item under cropfield");
                return null;
            }

            return applianceMapItem;

        }

    }
}