using Theriapolis.Core;
using Theriapolis.Core.Persistence;
using Theriapolis.Core.Persistence.SaveMigrations;
using Xunit;

namespace Theriapolis.Tests.Persistence;

/// <summary>
/// Phase 7 M0 — additive V7→V8 migration. Phase-6.5 saves continue to
/// load post-Phase-7; the new <see cref="SaveBody"/> sections (anchors,
/// building deltas, dungeon state) default-initialise to empty, which
/// correctly represents "no anchors persisted, no buildings modified,
/// no dungeons visited" — the truth for any pre-Phase-7 save.
/// </summary>
public sealed class V7ToV8MigrationTests
{
    [Fact]
    public void V7Header_IsAcceptedByMigration()
    {
        var header = new SaveHeader { Version = 7 };
        Assert.True(SaveCodec.IsCompatible(header),
            "v7 must remain readable post-Phase-7 (MIN_VERSION = 5; v7 is one bump back).");

        var body = new SaveBody();
        bool ok = Migrations.MigrateUp(header, body);
        Assert.True(ok);
        Assert.Equal(C.SAVE_SCHEMA_VERSION, header.Version);
    }

    [Fact]
    public void V6Header_ChainsThroughV7ToV8()
    {
        // v6 → v7 → v8 chain: a Phase-6 save should still load with two
        // additive migrations applied in order.
        var header = new SaveHeader { Version = 6 };
        Assert.True(SaveCodec.IsCompatible(header));

        var body = new SaveBody();
        bool ok = Migrations.MigrateUp(header, body);
        Assert.True(ok);
        Assert.Equal(C.SAVE_SCHEMA_VERSION, header.Version);
    }

    [Fact]
    public void V7SaveBody_AfterMigration_PreservesPhase65Fields()
    {
        var header = new SaveHeader { Version = 7 };
        var body = new SaveBody
        {
            Player = new() { Name = "Wanderer", PositionX = 10, PositionY = 10 },
            PlayerCharacter = new()
            {
                CladeId = "canidae", SpeciesId = "wolf",
                ClassId = "fangsworn", BackgroundId = "pack_raised",
                STR = 15, DEX = 12, CON = 13, INT = 10, WIS = 13, CHA = 8,
                Level = 3, Xp = 950, MaxHp = 28, CurrentHp = 28,
                SubclassId = "pack_forged",
                LearnedFeatureIds = new[] { "packmates_howl" },
            },
        };

        bool ok = Migrations.MigrateUp(header, body);
        Assert.True(ok);
        Assert.Equal(C.SAVE_SCHEMA_VERSION, header.Version);

        // Phase 6.5 fields untouched.
        Assert.Equal(3, body.PlayerCharacter!.Level);
        Assert.Equal("pack_forged", body.PlayerCharacter.SubclassId);
        Assert.Contains("packmates_howl", body.PlayerCharacter.LearnedFeatureIds);
    }
}
