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

namespace AsbCloudInfrastructure.Services.Trajectory
{
#nullable enable
    public class TrajectoryVisualizationService : ITrajectoryVisualizationService
    {
        private readonly IPlannedTrajectoryRepository repository;

        public TrajectoryVisualizationService(IPlannedTrajectoryRepository repository)
        {
            this.repository = repository;
        }

        public async Task<IEnumerable<TrajectoryVisualizationDto>> GetTrajectoryAsync(int idWell, CancellationToken token)
        {
            var geoCoordinates = (await repository.GetAsync(idWell, token)).ToArray();

            if (geoCoordinates.Length < 2)
                return Enumerable.Empty<TrajectoryVisualizationDto>();

            var cartesianCoordinates = new List<TrajectoryVisualizationDto>(geoCoordinates.Length) {
                new (),
            };

            for (var i = 1; i < geoCoordinates.Length; i++)
            {
                var intervalGeoParams = geoCoordinates[i - 1];
                var deltaWellLength = geoCoordinates[i].WellboreDepth - intervalGeoParams.WellboreDepth;
                var projectionLengthToXYSurface = deltaWellLength * Math.Sin(intervalGeoParams.ZenithAngle * Math.PI / 180);

                var dz = deltaWellLength * Math.Cos(intervalGeoParams.ZenithAngle * Math.PI / 180);
                var dx = projectionLengthToXYSurface * Math.Sin(intervalGeoParams.AzimuthGeo * Math.PI / 180);
                var dy = projectionLengthToXYSurface * Math.Cos(intervalGeoParams.AzimuthGeo * Math.PI / 180);

                var preCoordinates = cartesianCoordinates[i - 1];
                var coordinates = new TrajectoryVisualizationDto
                {
                    Z = preCoordinates.Z + dz,
                    X = preCoordinates.X + dx,
                    Y = preCoordinates.Y + dy,
                };

                cartesianCoordinates.Add(coordinates);
            }

            return cartesianCoordinates;
        }
    }
}