using System.Text.Json.Serialization;
namespace Theriapolis.Core.Data;
///
/// Phase 6 M0 — describes how to lay buildings inside a settlement footprint.
///
/// Two flavours:
/// 1. **Hand-authored preset** — `kind == "preset"`. The
/// array specifies each building by template id and offset from the
/// settlement centre. Used for narrative anchors (Millhaven, Thornfield).
/// 2. **Procedural rule-based** — `kind == "procedural"`. The
/// array specifies a mix of category weights ("inn" 0.1, "shop" 0.3,
/// "house" 0.6) and a target building count;
/// rolls templates from the matching categories until the target count is
/// met or no more building slots fit inside the plaza radius.
///
/// Bound to a settlement either by anchor name (preset) or by tier
/// (procedural fallback for any non-anchor settlement of that tier).
///
public sealed record SettlementLayoutDef
{
[JsonPropertyName("id")]
public string Id { get; init; } = "";
/// "preset" or "procedural".
[JsonPropertyName("kind")]
public string Kind { get; init; } = "procedural";
/// For preset layouts: matches Settlement.Anchor.ToString() (e.g. "Millhaven").
[JsonPropertyName("anchor")]
public string Anchor { get; init; } = "";
/// For procedural layouts: matches Settlement.Tier (1–5).
[JsonPropertyName("tier")]
public int Tier { get; init; } = 0;
// ── Preset payload ─────────────────────────────────────────────────────
/// Building placements for preset layouts. Ignored when kind == "procedural".
[JsonPropertyName("buildings")]
public SettlementBuildingPlacement[] Buildings { get; init; } = Array.Empty();
// ── Procedural payload ─────────────────────────────────────────────────
/// Category mix for procedural layouts. Ignored when kind == "preset".
[JsonPropertyName("category_weights")]
public Dictionary CategoryWeights { get; init; } = new();
/// Target building count for procedural layouts.
[JsonPropertyName("target_building_count")]
public int TargetBuildingCount { get; init; } = 5;
///
/// Plaza radius in tactical tiles to search for building slots (procedural).
/// If 0, the stamper picks one based on tier.
///
[JsonPropertyName("plaza_radius_tiles")]
public int PlazaRadiusTiles { get; init; } = 0;
}
public sealed record SettlementBuildingPlacement
{
/// BuildingTemplateDef.Id to stamp.
[JsonPropertyName("template")]
public string Template { get; init; } = "";
///
/// Offset from settlement centre in tactical tiles. (0,0) places the
/// building's centre on the settlement centre tile.
///
[JsonPropertyName("offset")]
public int[] Offset { get; init; } = new[] { 0, 0 };
///
/// Optional rotation: 0 / 90 / 180 / 270. Phase 6 M0 ignores; reserved
/// so layouts don't have to be re-authored when rotation lands.
///
[JsonPropertyName("rotation_deg")]
public int RotationDeg { get; init; } = 0;
///
/// Override the role tag for one or more roles in this building. E.g.
/// the innkeeper template has role "innkeeper"; this preset assigns
/// it the named role "millhaven.innkeeper" so quest scripts can
/// reference the specific NPC.
///
[JsonPropertyName("role_overrides")]
public Dictionary RoleOverrides { get; init; } = new();
}