using Friflo.Engine.ECS;
using LittleSim.Content;
using LittleSim.Scenes;
using Microsoft.Xna.Framework;
using MrGameEng.Genetics;
using MrGameEng.Graphics;

namespace LittleSim.Sim;

/// <summary>
/// Единая точка создания сущности-животного: спрайт вида, признаки из генома формулами генов, тинт по
/// оттенку меха и компонент-организм. Переиспользуется начальным спавном, размножением и загрузкой —
/// чтобы все животные собирались одинаково. Зеркало <see cref="PlantFactory"/>.
/// </summary>
public static class AnimalFactory
{
    // Якоря оттенка меха: тёплый рыжевато-песочный → холодный серо-голубой (по гену furColor).
    private static readonly Color FurWarm = new(255, 226, 188);
    private static readonly Color FurCool = new(206, 222, 235);

    /// <summary>Создаёт животное вида <paramref name="species"/> с заданным геномом и поколением.</summary>
    public static Entity Create(
        EntityStore store,
        AnimalSet animals,
        int species,
        Vector2 position,
        Genome genome,
        int generation,
        int cellSize
    )
    {
        var sp = animals[species];
        var traits = AnimalPhenotype.FromTraits(Phenotype.Compute(genome, animals.GeneRegistry));

        var sprite = new Sprite(sp.Region, GameLayers.Beings);
        sprite.CenterOrigin();
        sprite.Color = Tint(traits);

        // Размер спрайта задаёт ген размера тела; деф-fallback — на случай отсутствия гена.
        var sizeCells = traits.BodySize > 0f ? traits.BodySize : sp.Def.SizeCells;

        return store.CreateEntity(
            new Transform2D(position, scale: new Vector2(cellSize * sizeCells / sp.Region.Width)),
            sprite,
            new AnimalOrganism
            {
                Genome = genome,
                Traits = traits,
                Species = species,
                Generation = generation,
            }
        );
    }

    // Цвет животного из генов: лёгкий тёплый/холодный сдвиг меха (ген furHue) поверх текстуры —
    // субтильный, чтобы не перекрашивать уже цветной спрайт зверя (как leafHue у растений).
    private static Color Tint(in AnimalPhenotype traits)
    {
        var fur = Color.Lerp(FurWarm, FurCool, Math.Clamp(traits.FurHue, 0f, 1f));
        return Color.Lerp(Color.White, fur, 0.5f);
    }
}
