using Frontend.ViewModels;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using TriathlonRaceTracking.Data;
using TriathlonRaceTracking.Models;

namespace Frontend.Services
{
    public class TimingService : ITimingService
    {
        private readonly TriathlonRaceTrackingContext _context;
        public TimingService(TriathlonRaceTrackingContext context)
        {
            _context = context;
        }

        public IList<AthleteViewModel> GetStandings(int raceId)
        {
            var data = _context.Registrations
                .Include(r => r.Timings)
                    .ThenInclude(t => t.TimingPoint)
                .Include(r => r.Athlete)
                .Where(r => r.RaceID == raceId);

            var result = new List<AthleteViewModel>();
            foreach (var position in data)
            {
                var athleteVM = new AthleteViewModel(position.Athlete.FullName, position.Athlete.Nationality);
                if (position.Timings.Count == 0)
                {
                    athleteVM.Time = "DNS";
                }
                else
                {
                    var start = position.Timings.Where(t => t.TimingPoint.Type == TimingType.Start).Max(t => t.Time);
                    var furthestPosition = GetFurthestPosition(position.Timings);
                    athleteVM.Time = TimeFromStart(start, furthestPosition).ToString();
                    athleteVM.Timings = position.Timings.Select(t => new TimingPointViewModel
                    {
                        Time = TimeFromStart(start, t),
                        Order = (int)t.TimingPoint.Type,
                        Name = t.TimingPoint.Name,
                        Code = t.TimingPoint.Code
                    }).ToList();
                }

                result.Add(athleteVM);
            }

            return result;

        }

        private static TimeSpan TimeFromStart(DateTime start, Timing timingPoint)
        {
            return timingPoint.Time.Subtract(start);
        }

        private Timing GetFurthestPosition(List<Timing> timings)
        {
            Timing furthest = new Timing() { ID = -1 };
            foreach (var timing in timings)
            {
                if (timing.TimingPointID > furthest.TimingPointID)
                    furthest = timing;
            }
            return furthest;
        }

        public IQueryable<TimingPoint> GetTimingPoints(int raceId)
        {
            return _context.TimingPoints.Where(tp => tp.RaceID == raceId);
        }
    }
}
