using System;
using System.Linq;
using MusicMetaTagger.Core.Model;
using MusicMetaTagger.Core.Services;

namespace MusicMetaTagger.Client.AllMusicGuide.Services
{
	public class TrackRater : ITrackRater
	{
		private readonly IMusicGuide _musicGuide;

		public TrackRater(IMusicGuide musicGuide)
		{
			_musicGuide = musicGuide;
		}

		public int? RateTrack(Track track)
		{
			if (track == null)
				throw new ArgumentNullException("track");

			if (track.PerformerIds == null || track.PerformerIds.Count == 0)
				return null;

			// get the track pick statistics for this album
			var albumInfo = _musicGuide.GetAlbum(track.AlbumId);
			
			if (!albumInfo.Rating.HasValue)
				return null;
			
			// get the album rating statistics for this artist
			double artistAlbumRatingMean = 0;
			var artistInfo = _musicGuide.GetArtist(albumInfo.ArtistId);

			if (artistInfo != null)
			{
				var currentDi =
					artistInfo.Discography.Find(di => di.AlbumId == albumInfo.AlbumId);

				artistAlbumRatingMean =
					(from di in artistInfo.Discography
					 where currentDi == null || di.ReleaseType == currentDi.ReleaseType
					 where di.Rating.HasValue
					 select di.Rating.Value).Average();
			}

			// calculate the track rating
			var trackRating = albumInfo.Rating.Value;
			if (albumInfo.Rating.Value >= 9 && albumInfo.Tracks.Any(t => t.Pick)) trackRating -= 1;
			if (artistAlbumRatingMean >= 8 && albumInfo.Tracks.Any(t => t.Pick)) trackRating -= 1;
			if (albumInfo.Pick) trackRating += 1;
			if (track.Pick) trackRating += 2;
		
			return Math.Min(Math.Max(0, trackRating), 10);
		}
	}
}
