using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data.ProcessMap;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Repositories;
using AsbCloudApp.Services;

namespace AsbCloudInfrastructure.Services.ProcessMap.ProcessMapWellboreDevelopment;

public class ProcessMapWellboreDevelopmentService : IProcessMapWellboreDevelopmentService
{
	private readonly ITelemetryService telemetryService;
	private readonly IWellService wellService;
	private readonly IProcessMapWellboreDevelopmentRepository processMapWellboreDevelopmentRepository;

	public ProcessMapWellboreDevelopmentService(ITelemetryService telemetryService,
		IWellService wellService,
		IProcessMapWellboreDevelopmentRepository processMapWellboreDevelopmentRepository)
	{
		this.telemetryService = telemetryService;
		this.wellService = wellService;
		this.processMapWellboreDevelopmentRepository = processMapWellboreDevelopmentRepository;
	}

	public async Task<int> InsertAsync(ProcessMapWellboreDevelopmentDto processMapWellboreDevelopment, CancellationToken cancellationToken)
	{
		var well = await wellService.GetOrDefaultAsync(processMapWellboreDevelopment.IdWell, cancellationToken)
			?? throw new ArgumentInvalidException(nameof(processMapWellboreDevelopment.IdWell),
                $"Скважины с Id: {processMapWellboreDevelopment.IdWell} не существует");

		processMapWellboreDevelopment.LastUpdate = DateTimeOffset.UtcNow;

		return await processMapWellboreDevelopmentRepository.InsertAsync(processMapWellboreDevelopment, cancellationToken);
	}

	public async Task<int> UpdateAsync(ProcessMapWellboreDevelopmentDto processMapWellboreDevelopment, CancellationToken cancellationToken)
	{
		var well = await wellService.GetOrDefaultAsync(processMapWellboreDevelopment.IdWell, cancellationToken);

		if (well is null)
			throw new ArgumentInvalidException(nameof(processMapWellboreDevelopment.IdWell),
                $"Скважины с Id: {processMapWellboreDevelopment.IdWell} не существует");

		processMapWellboreDevelopment.LastUpdate = DateTimeOffset.UtcNow;

		var result = await processMapWellboreDevelopmentRepository.UpdateAsync(processMapWellboreDevelopment, cancellationToken);

		if (result == ICrudRepository<ProcessMapWellboreDevelopmentDto>.ErrorIdNotFound)
			throw new ArgumentInvalidException(nameof(processMapWellboreDevelopment.Id),
                $"Проработки с Id: {processMapWellboreDevelopment.Id} не существует");

		return result;
	}

	public async Task<IEnumerable<ProcessMapWellboreDevelopmentDto>> GetByTelemetryAsync(string uid, DateTime updateFrom,
		CancellationToken cancellationToken)
	{
		var idWell = telemetryService.GetIdWellByTelemetryUid(uid);

		if (!idWell.HasValue)
			throw new ArgumentInvalidException(nameof(uid), $"Неправильный телеметрии. Uid: {uid}");

		return await processMapWellboreDevelopmentRepository.GetAllAsync(idWell.Value, updateFrom, cancellationToken);
	}
}