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

namespace Theriapolis.Tests.Persistence;

/// <summary>
/// Phase 6.5 M0 — additive V6→V7 migration. Every v6 field carries over
/// unchanged; the new <see cref="PlayerCharacterState.SubclassId"/>,
/// <see cref="PlayerCharacterState.LearnedFeatureIds"/>, and
/// <see cref="PlayerCharacterState.LevelUpHistory"/> default-initialise
/// to empty values.
/// </summary>
public sealed class V6ToV7MigrationTests
{
    [Fact]
    public void V6Header_IsAcceptedByMigration()
    {
        var header = new SaveHeader { Version = 6 };
        Assert.True(SaveCodec.IsCompatible(header),
            "v6 must remain readable post-Phase-6.5 (MIN_VERSION = 5).");

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

    [Fact]
    public void V6SaveBody_AfterMigration_HasFreshLevelUpFields()
    {
        var header = new SaveHeader { Version = 6 };
        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 = 1, Xp = 0, MaxHp = 11, CurrentHp = 11,
            },
        };

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

        // Existing fields untouched.
        Assert.Equal("Wanderer", body.Player.Name);
        Assert.Equal(1, body.PlayerCharacter!.Level);

        // New v7 fields default-initialised to empty.
        Assert.Equal("", body.PlayerCharacter.SubclassId);
        Assert.Empty(body.PlayerCharacter.LearnedFeatureIds);
        Assert.Empty(body.PlayerCharacter.LevelUpHistory);
    }

    [Fact]
    public void NewSaveHeader_DefaultsToCurrentSchemaVersion()
    {
        // Phase 7 M0 bumped SAVE_SCHEMA_VERSION to 8; the old test
        // hardcoded 7. This version-of-record test is an early-warning
        // that future bumps remember to add a chained migration entry.
        var header = new SaveHeader();
        Assert.Equal(C.SAVE_SCHEMA_VERSION, header.Version);
        Assert.True(header.Version >= 7,
            "Schema version must not regress below the v7 floor introduced in Phase 6.5.");
    }
}
