using AutoMapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using PARR.API.Contracts.V1;
using PARR.API.Contracts.V1.Requests;
using PARR.API.Contracts.V1.Responses;
using PARR.API.Contracts.V1.Responses.Base;
using PARR.API.Controllers.V1.Base;
using PARR.API.Services.Interfaces;
using PARR.Core.Repositories.Interfaces;
using PARR.Domain.Common.Roles;
using PARR.Domain.Entities;
using PARR.Domain.Enums;

namespace PARR.API.Controllers.V1
{
    [Authorize(Roles = ParrRoles.EsppRobot.RoleOrAdmin)]
    public class RobotTaskRobotStatusController : BaseApiController
    {
        private readonly IRobotConfigurationRepository robotConfigurationService;
        private readonly IRobotHistoryRepository robotHistoryService;
        private readonly IMapper mapper;
        private readonly IClientService clientService;

        public RobotTaskRobotStatusController(
             IRobotConfigurationRepository robotConfigurationService,
             IRobotHistoryRepository robotHistoryService,
             IMapper mapper,
             IClientService clientService
            )
        {
            this.robotConfigurationService = robotConfigurationService;
            this.robotHistoryService = robotHistoryService;
            this.mapper = mapper;
            this.clientService = clientService;
        }


        /// <summary>
        /// Изменить статус выполнения задания роботом по ИД задания
        /// </summary>
        /// <param name="taskId"></param>
        /// <returns></returns>
        [HttpPut(ApiRoutes.RobotTaskRobotStatus.ChangeRobotStatus)]
        public async Task<IActionResult> ChangeStatus([FromRoute] Guid taskId, [FromBody] RobotTaskChangeRobotStatusRequest request)
        {
            var config = await robotConfigurationService.Get()
                                .FirstOrDefaultAsync(t => t.Id == taskId);

            if (config == null)
                return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel { Message = $"Не найдено задание с id: {taskId}" } }));

            //изменение статуса робота
            robotConfigurationService.ChangeRobotStatus(request.RobotStatusCode, config);

            //если успех, изменяем статус задания на успех
            if (request.RobotStatusCode == RobotStatusEnum.Complete)
                robotConfigurationService.ChangeTaskStatus(TaskStatusEnum.Ok, config);

            if (!await robotConfigurationService.CommitAsync())
                return BadRequest("Ошибка при изменении статуса работы робота.");

            //записываем в лог робота
            if (request.RobotStatusCode == RobotStatusEnum.InProgress || request.RobotStatusCode == RobotStatusEnum.Complete)
            {
                var historyLevel = request.RobotStatusCode == RobotStatusEnum.InProgress ? RobotHistoryLevelEnum.Start : RobotHistoryLevelEnum.Complete;

                var history = new RobotHistory
                {
                    Id = Guid.NewGuid(),
                    HistoryLevel = (int)historyLevel,
                    TaskStatusCode = config.TaskStatusCode,
                    RobotConfigurationId = config.Id,
                    RobotIp = clientService.GetClientIp()?.ToString(),
                    RobotId = request.RobotId
                };
                await robotHistoryService.CreateAsync(history);
                await robotHistoryService.CommitAsync();
            }

            var configToResponse = await robotConfigurationService.Get()
                                .Include(t => t.Robot)
                                .Include(t => t.TaskStatus)
                                .Include(t => t.RobotStatus)
                                .FirstOrDefaultAsync(t => t.Id == taskId);

            var response = mapper.Map<RobotConfigurationResponse>(configToResponse);

            return Ok(new Response<RobotConfigurationResponse>(response, true));
        }


    }
}
