using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using EscapeRoomEngine.Engine.Runtime.Utilities;
using JetBrains.Annotations;
using MongoDB.Bson;
using Realms;

namespace EscapeRoomEngine.Engine.Runtime.Measurements
{
    /// <summary>
    /// The representation of a session in the database. This stores all plan results during this session and what puzzles were solved.
    /// </summary>
    [SuppressMessage("ReSharper", "UnassignedGetOnlyAutoProperty")]
    public class Session : RealmObject
    {
        [PrimaryKey]
        public ObjectId ID { get; set; }
        public float Time { get; set; }
        /// <summary>
        /// The plan results for each section during this section.
        /// </summary>
        /// <remarks>The order of the plan results corresponds with the order of the solved puzzles.</remarks>
        public IList<PlanResult> PlanResults { get; }
        /// <summary>
        /// The puzzles solved during this session.
        /// </summary>
        /// <remarks>The order of the solved puzzles corresponds with the order of the plan results.</remarks>
        public IList<Puzzle> PuzzlesSolved { get; }

        /// <summary>
        /// The section percentiles the current player has been placed in.
        /// </summary>
        public IEnumerable<float> Percentiles => PlanResults.Select(result => result.SectionPercentile);
        /// <summary>
        /// The average of all section percentiles.
        /// </summary>
        public float MeanPercentile => PlanResults.Count == 0 ? .5f : Probability.Mean(Percentiles.ToArray());

        [UsedImplicitly]
        public Session()
        {
            ID = ObjectId.GenerateNewId();
        }

        public override string ToString()
        {
            return $"Session {ID}: {PuzzlesSolved.Count} puzzles solved in {Time.ToTimeSpan():m':'ss}";
        }
    }
}