using System;
using System.Collections.Generic;
using System.Linq;

namespace FishDice.LuckyDice
{
    public static class ComboFactBuilder
    {
        public static ComboFacts Build(DiceRollResult result)
        {
            if (result == null)
            {
                throw new ArgumentNullException(nameof(result));
            }

            if (result.SetType != DiceSetType.Normal)
            {
                throw new InvalidOperationException("Only normal dice rolls can be converted to combo facts.");
            }

            if (result.DiceCount != result.Faces.Count)
            {
                throw new InvalidOperationException("Dice count does not match rolled face count.");
            }

            if (result.Faces.Any(face => face.SetType != DiceSetType.Normal))
            {
                throw new InvalidOperationException("Combo facts cannot include lucky dice result faces.");
            }

            var faceCounts = result.Faces
                .GroupBy(face => face.Key)
                .ToDictionary(group => group.Key, group => group.Count());
            var numberValues = result.Faces
                .Where(face => face.NumberValue.HasValue)
                .Select(face => face.NumberValue.Value)
                .ToArray();
            var cloverCount = faceCounts.TryGetValue(LuckyDiceKeys.CloverFaceKey, out var count) ? count : 0;
            var orderedKey = string.Join("_", result.Faces.Select(face => face.Key));
            var normalizedKey = string.Join("_", result.Faces.Select(face => face.Key).OrderBy(key => key, StringComparer.Ordinal));

            return new ComboFacts(
                result.RollSessionId,
                result.SetType,
                result.DiceCount,
                result.Faces,
                faceCounts,
                numberValues.Sum(),
                numberValues,
                cloverCount,
                normalizedKey,
                orderedKey);
        }
    }
}
