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

namespace PARR.API.Controllers.V1.Statistics
{
    /// <summary>
    /// Статистика выполняения заданий роботами, по полю RobotConfigurations.RobotStatusCode
    /// </summary>
    [Authorize(Roles = ParrRoles.Administrator.Role)]
    public class StatRobotStatusController : BaseApiController
    {
        private readonly IRobotRepository robotService;
        private readonly IRobotConfigurationRepository robotConfigurationService;
        private readonly IRobotStatusRepository robotStatusService;
        private readonly IMapper mapper;

        public StatRobotStatusController(
            IRobotRepository robotService,
            IRobotConfigurationRepository robotConfigurationService,
            IRobotStatusRepository robotStatusService,
            IMapper mapper
            )
        {
            this.robotService = robotService;
            this.robotConfigurationService = robotConfigurationService;
            this.robotStatusService = robotStatusService;
            this.mapper = mapper;
        }

        /// <summary>
        /// Статистика работы роботов
        /// </summary>
        /// <returns></returns>
        [HttpGet(ApiRoutes.StatRobotStatus.Get)]
        public async Task<IActionResult> Get()
        {
            var confStat = await robotConfigurationService.Get()
                           .AsNoTracking()
                           .GroupBy(t => new { t.RobotCode, t.RobotStatusCode })
                           .Select(t => new { RobotCode = t.Key.RobotCode, RobotStatusCode = t.Key.RobotStatusCode, Count = t.Count() })
                           .ToListAsync();

            var robots = await robotService.Get().AsNoTracking().ToListAsync();
            var robotStatuses = await robotStatusService.Get().AsNoTracking().ToListAsync();

            var response = new List<StatRobotStatusResponse>();

            foreach (var robot in robots)
            {
                var item = new StatRobotStatusResponse { Robot = mapper.Map<RobotResponse>(robot) };
                robotStatuses.ForEach(stat =>
                {
                    item.Statistics.Add(new StatRobotStatusItemResponse
                    {
                        Status = mapper.Map<RobotStatusResponse>(stat),
                        Count = confStat.FirstOrDefault(t => t.RobotStatusCode == stat.Code && t.RobotCode == robot.Code)?.Count ?? 0
                    });
                });
                item.Statistics = item.Statistics.OrderBy(t => t.Status?.Code).ToList();
                response.Add(item);
            }

            response = response.OrderBy(t => t.Robot?.Code).ToList();

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