using Theriapolis.Core.Rules.Quests;

namespace Theriapolis.Core.Persistence;

/// <summary>
/// Phase 6 M4 — bidirectional translator between the live
/// <see cref="QuestEngine"/> and its serializable
/// <see cref="QuestSnapshot"/>.
/// </summary>
public static class QuestCodec
{
    public static QuestSnapshot Capture(QuestEngine engine)
    {
        var snap = new QuestSnapshot();
        foreach (var s in engine.Active.Values)    snap.Active.Add(CaptureState(s));
        foreach (var s in engine.Completed.Values) snap.Completed.Add(CaptureState(s));
        foreach (var line in engine.Journal)       snap.Journal.Add(line);
        return snap;
    }

    public static void Restore(QuestEngine engine, QuestSnapshot snap)
    {
        engine.Clear();
        foreach (var s in snap.Active)    engine.AdoptActive(RestoreState(s));
        foreach (var s in snap.Completed) engine.AdoptCompleted(RestoreState(s));
        foreach (var line in snap.Journal) engine.Journal.Add(line);
    }

    private static QuestStateSnapshot CaptureState(QuestState s) => new()
    {
        QuestId       = s.QuestId,
        CurrentStep   = s.CurrentStep,
        Status        = (byte)s.Status,
        StartedAt     = s.StartedAt,
        StepStartedAt = s.StepStartedAt,
        JournalLines  = s.Journal.ToArray(),
    };

    private static QuestState RestoreState(QuestStateSnapshot s)
    {
        var st = new QuestState
        {
            QuestId       = s.QuestId,
            CurrentStep   = s.CurrentStep,
            Status        = (QuestStatus)s.Status,
            StartedAt     = s.StartedAt,
            StepStartedAt = s.StepStartedAt,
        };
        foreach (var line in s.JournalLines) st.Journal.Add(line);
        return st;
    }
}
