using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Npgsql.EntityFrameworkCore.PostgreSQL.Query.Expressions.Internal;
using PARR.API.Contracts.V1;
using PARR.API.Contracts.V1.Requests.BaseRequests;
using PARR.API.Contracts.V1.Responses.Base;
using PARR.API.Contracts.V1.Responses.Statistics;
using PARR.API.Controllers.V1.Base;
using PARR.BLL.Services.Interfaces;
using PARR.Constants;
using PARR.DAL.Contracts;
using PARR.DAL.Services.Interfaces;

namespace PARR.API.Controllers.V1.Statistics
{
    /// <summary>
    /// Статистика по шаблонам
    /// </summary>
    [Authorize(Roles = ParrRoles.Administrator.Role)]
    public class StatTemplateController : BaseApiController
    {
        private readonly ITemplateService templateService;
        private readonly ICalendarService calendarService;

        public StatTemplateController(
            ITemplateService templateService,
            ICalendarService calendarService
            )
        {
            this.templateService = templateService;
            this.calendarService = calendarService;
        }

        /// <summary>
        /// Статистика по шаблонам
        /// </summary>
        /// <returns></returns>
        [HttpGet(ApiRoutes.StatTemplate.Get)]
        public async Task<IActionResult> Get()
        {
            var response = new StatTemplateResponse
            {
                ActivateScheduleCount = await templateService.Get().CountAsync(t => t.IsActiveSchedule),
                ActivateTemplateCount = await templateService.Get().CountAsync(t => t.IsActiveTemplate),
                TemplateAgentCount = await templateService.Get().Include(t => t.Job).ThenInclude(t=>t.Group).CountAsync(t => t.Job!.Group!.IsAgent),
                TemplateCount = await templateService.Get().CountAsync(),
                SyncEsppScheduleCount = await templateService.Get().Include(t => t.RobotConfigurations).CountAsync(t => t.RobotConfigurations.Any(c => c.RobotCode == (int)RobotsEnum.ScheduleOrder && c.TaskStatusCode == (int)TaskStatusEnum.Ok)),
                SyncEsppTemplatesCount = await templateService.Get().Include(t => t.RobotConfigurations).CountAsync(t => t.RobotConfigurations.Any(c => c.RobotCode == (int)RobotsEnum.TemplateOrder && c.TaskStatusCode == (int)TaskStatusEnum.Ok))
            };

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


        /// <summary>
        /// Получить статистику созданных шаблонов (расписаний) в БД ПАРР
        /// </summary>
        /// <param name="timeZoneQuery"></param>
        /// <param name="startPeriodDays"></param>
        /// <returns></returns>
        [HttpGet(ApiRoutes.StatTemplate.GetForPeriod)]
        public async Task<IActionResult> GetForPeriod([FromQuery] TimeZoneOffsetClient timeZoneQuery, [FromQuery] int startPeriodDays = 3)
        {
            var endPeriod = calendarService.GetDateWithTimeZoneOffset(DateTimeOffset.UtcNow, timeZoneQuery.TimeZoneOffsetHours);
            var startPeriod = endPeriod.AddDays(-startPeriodDays);

            var query = templateService.Get()
                            .Where(t =>
                                t.DateCreated.DateTime.AddHours(timeZoneQuery.TimeZoneOffsetHours).Date >= startPeriod.Date
                                && t.DateCreated.DateTime.AddHours(timeZoneQuery.TimeZoneOffsetHours).Date <= endPeriod.Date
                                ).GroupBy(t => t.DateCreated.AddHours(timeZoneQuery.TimeZoneOffsetHours).Date)
                                .Select(t => new
                                {
                                    Date = t.Key,
                                    CreatedObjs = t.Count()
                                });

            var result = await query.ToListAsync();

            var daysList = calendarService.GetDatesForPeriod(startPeriod, endPeriod);

            var response = new List<StatTemplatePeriodResponse>();

            daysList.ForEach(date => response.Add(new StatTemplatePeriodResponse
            {
                Date = date,
                CreatedTemplatesCount = result.FirstOrDefault(t => DateOnly.FromDateTime(t.Date) == date)?.CreatedObjs ?? 0
            }));

            response = response.OrderBy(t => t.Date).ToList();

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


    }
}
