using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace WebApiKnockoutDemo.Controllers
{
    public class JudgingController : ApiController
    {
        private Models.JudgingEntities entities = new Models.JudgingEntities();

        [HttpGet]
        public IEnumerable<Models.Rating> PersonRatings(int id)
        {
            return entities.Ratings.Where(r => r.CompetitorID == id);
        }

        [HttpGet]
        public IEnumerable<Models.Person> AvailableJudges(int id)
        {
            return entities.People
                .Where(p => p.Judges) // only if they are allowed to judge
                .Where(p => !p.RatingsGiven.Any(comp => comp.CompetitorID == id)) // only if they have NOT rated this competitor already
                .Where(p => p.Id != id); // a person cannot judge themselves, even if they are registered both to compete and judge
        }       

        [HttpGet]
        public IEnumerable<Models.Person> Competitors(bool includeRatings = false)
        {
            // Note: Person has reference to Rating, which has reference to Person (in generated EF code).  To avoid circular serialization crash
            // I set getters on the navigation properties to "internal" access modifier.
            System.Data.Entity.Infrastructure.DbQuery<Models.Person> people = entities.People;
            if (includeRatings)
                people = people.Include("RatingsReceived");  // What is this? Related table not loaded by default unless mentioned in original query.  Use include to force join.

            return people.Where(p => p.Competes);
        }

        [HttpGet]
        public Models.Outcome Outcome(int id)
        {
            return new Models.Outcome
            {
                Competitor = Competitors(true)
                    .Single(p => p.Id == id),
                Star = "" // For single outcome request, we don't calculate "Star" value
            };            
        }

        [HttpGet]
        public IEnumerable<Models.Outcome> Outcomes()
        {            

            var outcomes =
                Competitors(true)
                .Select(cmp => new Models.Outcome { Competitor = cmp })
                .OrderByDescending(ot => ot.AverageRating)
                .ToList();

            var avgRatings = outcomes
                .Select(r => r.AverageRating)
                .OrderByDescending(r => r)
                .Distinct()
                .ToList();

            
            decimal goldStar = avgRatings.FirstOrDefault();

            decimal silverStar = avgRatings.ElementAtOrDefault(1);

            foreach (var ot in outcomes)
                ot.CalculateStar(goldStar, silverStar);

            return outcomes;


            
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                entities.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}
