using AsbCloudApp.Data;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
using AsbCloudDb.Model;
using AsbCloudDb.Model.WITS;
using Microsoft.EntityFrameworkCore;

namespace AsbCloudInfrastructure.Repository;

public class TrajectoryFactRepository : ITrajectoryFactRepository
{
	private readonly IAsbCloudDbContext dbContext;

	public TrajectoryFactRepository(IAsbCloudDbContext dbContext)
	{
		this.dbContext = dbContext;
	}

	public async Task<IEnumerable<TrajectoryGeoFactDto>> GetAsync(TrajectoryGeoFactRequest request, CancellationToken token) =>
		(await BuildQuery(request)
			.Where(coord => coord.Deptsvym.HasValue &&
							coord.Svyinc.HasValue &&
							coord.Svyazc.HasValue)
			.AsNoTracking()
			.ToArrayAsync(token))
		.Select(r => new TrajectoryGeoFactDto
		{
			IdWell = request.IdWell,
			AzimuthMagnetic = r.Svymtf,
			VerticalDepth = r.Deptsvyv,
			WellboreDepth = r.Deptsvym!.Value,
			ZenithAngle = r.Svyinc!.Value,
			AzimuthGeo = r.Svyazc!.Value
		});

	public Task<IEnumerable<TrajectoryGeoFactDto>> GetAsync(int idWell, CancellationToken token) =>
		GetAsync(new TrajectoryGeoFactRequest
		{
			IdWell = idWell
		}, token);

	private IQueryable<Record7> BuildQuery(TrajectoryGeoFactRequest request)
	{
		var well = dbContext.Wells.SingleOrDefault(w => w.Id == request.IdWell);

		if (well is null)
			throw new ArgumentInvalidException($"Скважина с Id: {request.IdWell} не найдена", nameof(request.IdWell));

		var query = dbContext.Record7.Where(r => r.IdTelemetry == well.IdTelemetry)
			.Where(x => x.IdTelemetry == well.IdTelemetry);

		if (request.GeDate.HasValue)
			query = query.Where(r => r.DateTime >= request.GeDate.Value);

		if (request.LtDate.HasValue)
			query = query.Where(r => r.DateTime <= request.LtDate.Value);

		return query.OrderBy(e => e.Deptsvym);
	}
}