using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data.DailyReport;
using AsbCloudApp.Data.DailyReport.Blocks.Sign;
using AsbCloudApp.Data.DailyReport.Blocks.Subsystems;
using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
using AsbCloudDb;
using AsbCloudDb.Model;
using AsbCloudDb.Model.DailyReports;
using Mapster;
using Microsoft.EntityFrameworkCore;

namespace AsbCloudInfrastructure.Repository;

public class DailyReportRepository : CrudRepositoryBase<DailyReportDto, DailyReport>,
	IDailyReportRepository
{
	public DailyReportRepository(IAsbCloudDbContext dbContext)
		: base(dbContext)
	{
	}

	public async Task<IEnumerable<DailyReportDto>> GetAsync(int idWell, FileReportRequest request, CancellationToken cancellationToken)
	{
		var skip = request.Skip ?? 0;
		var take = request.Take ?? 10;

		var query = GetQuery().Where(d => d.IdWell == idWell);

		if (request.GeDate.HasValue)
		{
			var geDate = request.GeDate.Value.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc);
			query = query.Where(d => d.Date >= geDate);
		}

		if (request.LeDate.HasValue)
		{
			var leDate = request.LeDate.Value.ToDateTime(TimeOnly.MinValue, DateTimeKind.Utc);
			query = query.Where(d => d.Date <= leDate);	
		}

		if (request.SortFields?.Any() == true)
		{
			query = query.SortBy(request.SortFields);
		}
		else
		{
			query = query.OrderBy(d => d.Date);
		}

		var entities = await query
			.Skip(skip)
			.Take(take)
			.AsNoTracking()
			.ToArrayAsync(cancellationToken);

		var dtos = entities.Select(Convert);

		return dtos;
	}

	public async Task<DailyReportDto?> GetOrDefaultAsync(int idWell, DateTime date, CancellationToken cancellationToken)
	{
		var entity = await GetQuery()
			.AsNoTracking()
			.SingleOrDefaultAsync(d => d.IdWell == idWell && d.Date == date, cancellationToken);

		return entity is null ? null : Convert(entity);
	}

	protected override DailyReportDto Convert(DailyReport src)
	{
		var dto = new DailyReportDto
		{
			Id = src.Id,
			IdWell = src.IdWell,
			DateLastUpdate = src.DateLastUpdate,
			Date = src.Date,
			SignBlock = src.SignBlock?.Adapt<SignBlockDto>(),
			TimeBalanceBlock = src.TimeBalanceBlock?.Adapt<TimeBalanceBlockDto>(),
			SubsystemBlock = src.SubsystemBlock?.Adapt<SubsystemBlockDto>()
		};
		
		return dto;
	}
}