using SVSim.Database.Common;
namespace SVSim.Database.Models;
///
/// One row per AI opponent shown on the practice (solo-play) opponent select screen.
/// Populated from seeds/practice-opponents.json by SVSim.Bootstrap.PracticeOpponentImporter.
///
/// The (, ) pair MUST exist in the client's
/// baked-in master CSV `ai/practice_ai_setting`; if it doesn't, the client's
/// PracticeAISettingDataSet.GetSettingData throws InvalidOperationException and the
/// difficulty-select dialog crashes BEFORE /practice/start is sent. Prod's catalog is
/// the safe source of truth — we can't see the CSV directly.
///
public class PracticeOpponentEntry : BaseEntity
{
/// Practice slot id (Id = practice_id from the wire; also unique).
public int PracticeId { get => Id; set => Id = value; }
/// Text-table key resolved client-side via Data.Master.GetPracticeText.
public string TextId { get; set; } = string.Empty;
/// Class (leader) id the AI plays.
public int ClassId { get; set; }
/// Portrait / character id (leader art).
public int CharaId { get; set; }
/// Title-degree id shown next to the AI name. -1 when unset.
public int DegreeId { get; set; }
/// AI deck-strength tier; key into the client's practice_ai_setting CSV.
public int AiDeckLevel { get; set; }
/// AI decision-making tier.
public int AiLogicLevel { get; set; }
/// Starting HP for the AI side (typically 20; 10 for the easiest "tutorial" rows).
public int AiMaxLife { get; set; }
/// 3D battlefield asset id (string on the wire; client int.TryParse's it).
public string Battle3dFieldId { get; set; } = "1";
/// true => entry shown but disabled with a maintenance suffix.
public bool IsMaintenance { get; set; }
/// true => entry is a special event-tied "campaign" practice.
public bool IsCampaignPractice { get; set; }
}