using RioJoy.Core.Calibration;
using RioJoy.Core.Mapping;

namespace RioJoy.Core.Profiles;

/// <summary>
/// A per-game profile: everything about how the cockpit behaves for one
/// non-native game (see docs/PLAN.md §Profiles). The unified profile supersedes
/// the legacy single-file <c>RIO.ini</c>. Profiles never describe the native
/// games — those are the hands-off/yield case.
/// </summary>
public sealed class RioProfile
{
    /// <summary>Display name (unique within a library).</summary>
    public string Name { get; set; } = "Unnamed";

    /// <summary>RIO serial port (e.g. "COM3"); null = use the app default.</summary>
    public string? RioComPort { get; set; }

    /// <summary>Plasma/VFD serial port; null = use the app default or none.</summary>
    public string? PlasmaComPort { get; set; }

    /// <summary>
    /// The <c>iRIO</c> map: RIO address (0x00..0x6F) → 16-bit map word. Only
    /// mapped addresses need entries.
    /// </summary>
    public Dictionary<int, int> Buttons { get; set; } = new();

    /// <summary>Axis calibration / invert options.</summary>
    public AxisCalibrationConfig Calibration { get; set; } = new();

    /// <summary>Plasma greeting text shown on load (null = leave display as-is).</summary>
    public string? PlasmaGreeting { get; set; }

    /// <summary>Cockpit wallpaper image path (generated in Phase 7).</summary>
    public string? WallpaperPath { get; set; }

    /// <summary>
    /// Overlay label text per template region (region/layer name → display text,
    /// e.g. <c>"b-00" → "FIRE"</c>). Drives the Phase 7 wallpaper generator
    /// (<see cref="Overlay.OverlayLayoutEngine"/>); empty/absent entries render
    /// nothing. The region geometry itself lives in the shared overlay template.
    /// </summary>
    public Dictionary<string, string> OverlayLabels { get; set; } = new();

    /// <summary>
    /// Executable names that select this profile when they are the foreground app
    /// (matched case-insensitively, with or without ".exe").
    /// </summary>
    public List<string> MatchExecutables { get; set; } = new();

    /// <summary>Build a <see cref="RioInputMap"/> from <see cref="Buttons"/>.</summary>
    public RioInputMap ToInputMap()
    {
        var map = new RioInputMap();
        foreach ((int address, int raw) in Buttons)
            map[address] = new RioMapEntry((ushort)raw);
        return map;
    }
}
