namespace SpaceGame.Api.Factions.Runtime;

public sealed class FactionRuntime
{
    public required string Id { get; init; }
    public required string Label { get; init; }
    public required string Color { get; init; }
    public float Credits { get; set; }
    public float PopulationTotal { get; set; }
    public float OreMined { get; set; }
    public float GoodsProduced { get; set; }
    public int ShipsBuilt { get; set; }
    public int ShipsLost { get; set; }
    public HashSet<string> CommanderIds { get; } = new(StringComparer.Ordinal);
    public string? DefaultPolicySetId { get; set; }
    public FactionDoctrineRuntime Doctrine { get; set; } = new();
    public FactionMemoryRuntime Memory { get; set; } = new();
    public FactionStrategicStateRuntime StrategicState { get; set; } = new();
    public List<FactionDecisionLogEntryRuntime> DecisionLog { get; } = [];
    public string LastDeltaSignature { get; set; } = string.Empty;
}

public sealed class CommanderRuntime
{
    public required string Id { get; init; }
    public required string Kind { get; set; }
    public required string FactionId { get; init; }
    public string? ParentCommanderId { get; set; }
    public string? ControlledEntityId { get; set; }
    public string? PolicySetId { get; set; }
    public string? Doctrine { get; set; }
    public float ReplanTimer { get; set; }
    public bool NeedsReplan { get; set; } = true;
    public CommanderAssignmentRuntime? Assignment { get; set; }
    public CommanderSkillProfileRuntime Skills { get; set; } = new();
    public HashSet<string> SubordinateCommanderIds { get; } = new(StringComparer.Ordinal);
    public HashSet<string> ActiveObjectiveIds { get; } = new(StringComparer.Ordinal);
    public bool IsAlive { get; set; } = true;
    public int PlanningCycle { get; set; }
    public string LastDeltaSignature { get; set; } = string.Empty;
}

public sealed class CommanderAssignmentRuntime
{
    public required string ObjectiveId { get; set; }
    public string? CampaignId { get; set; }
    public string? TheaterId { get; set; }
    public required string Kind { get; set; }
    public required string BehaviorKind { get; set; }
    public string Status { get; set; } = "active";
    public float Priority { get; set; }
    public string? HomeSystemId { get; set; }
    public string? HomeStationId { get; set; }
    public string? TargetSystemId { get; set; }
    public string? TargetEntityId { get; set; }
    public Vector3? TargetPosition { get; set; }
    public string? ItemId { get; set; }
    public string? Notes { get; set; }
    public DateTimeOffset UpdatedAtUtc { get; set; } = DateTimeOffset.UtcNow;
}

public sealed class CommanderSkillProfileRuntime
{
    public int Leadership { get; set; } = 3;
    public int Coordination { get; set; } = 3;
    public int Strategy { get; set; } = 3;
}

public sealed class FactionDoctrineRuntime
{
    public string StrategicPosture { get; set; } = "balanced";
    public string ExpansionPosture { get; set; } = "measured";
    public string MilitaryPosture { get; set; } = "defensive";
    public string EconomicPosture { get; set; } = "self-sufficient";
    public int DesiredControlledSystems { get; set; } = 3;
    public int DesiredMilitaryPerFront { get; set; } = 2;
    public int DesiredMinersPerSystem { get; set; } = 1;
    public int DesiredTransportsPerSystem { get; set; } = 1;
    public int DesiredConstructors { get; set; } = 1;
    public float ReserveCreditsRatio { get; set; } = 0.2f;
    public float ExpansionBudgetRatio { get; set; } = 0.25f;
    public float WarBudgetRatio { get; set; } = 0.35f;
    public float ReserveMilitaryRatio { get; set; } = 0.2f;
    public float OffensiveReadinessThreshold { get; set; } = 0.62f;
    public float SupplySecurityBias { get; set; } = 0.55f;
    public float FailureAversion { get; set; } = 0.45f;
    public int ReinforcementLeadPerFront { get; set; } = 1;
}

public sealed class FactionMemoryRuntime
{
    public int LastPlanCycle { get; set; }
    public DateTimeOffset UpdatedAtUtc { get; set; }
    public int LastObservedShipsBuilt { get; set; }
    public int LastObservedShipsLost { get; set; }
    public float LastObservedCredits { get; set; }
    public HashSet<string> KnownSystemIds { get; } = new(StringComparer.Ordinal);
    public HashSet<string> KnownEnemyFactionIds { get; } = new(StringComparer.Ordinal);
    public List<FactionSystemMemoryRuntime> SystemMemories { get; } = [];
    public List<FactionCommodityMemoryRuntime> CommodityMemories { get; } = [];
    public List<FactionOutcomeRecordRuntime> RecentOutcomes { get; } = [];
}

public sealed class FactionSystemMemoryRuntime
{
    public required string SystemId { get; init; }
    public DateTimeOffset LastSeenAtUtc { get; set; }
    public int LastEnemyShipCount { get; set; }
    public int LastEnemyStationCount { get; set; }
    public bool ControlledByFaction { get; set; }
    public string? LastRole { get; set; }
    public float FrontierPressure { get; set; }
    public float RouteRisk { get; set; }
    public float HistoricalShortagePressure { get; set; }
    public int OffensiveFailures { get; set; }
    public int DefensiveFailures { get; set; }
    public int OffensiveSuccesses { get; set; }
    public int DefensiveSuccesses { get; set; }
    public DateTimeOffset? LastContestedAtUtc { get; set; }
    public DateTimeOffset? LastShortageAtUtc { get; set; }
}

public sealed class FactionCommodityMemoryRuntime
{
    public required string ItemId { get; init; }
    public float HistoricalShortageScore { get; set; }
    public float HistoricalSurplusScore { get; set; }
    public float LastObservedBacklog { get; set; }
    public DateTimeOffset UpdatedAtUtc { get; set; }
    public DateTimeOffset? LastCriticalAtUtc { get; set; }
}

public sealed class FactionOutcomeRecordRuntime
{
    public required string Id { get; init; }
    public required string Kind { get; set; }
    public required string Summary { get; set; }
    public string? RelatedCampaignId { get; set; }
    public string? RelatedObjectiveId { get; set; }
    public DateTimeOffset OccurredAtUtc { get; set; } = DateTimeOffset.UtcNow;
}

public sealed class FactionStrategicStateRuntime
{
    public int PlanCycle { get; set; }
    public DateTimeOffset UpdatedAtUtc { get; set; }
    public string Status { get; set; } = "stable";
    public FactionBudgetRuntime Budget { get; set; } = new();
    public FactionEconomicAssessmentRuntime EconomicAssessment { get; set; } = new();
    public FactionThreatAssessmentRuntime ThreatAssessment { get; set; } = new();
    public List<FactionTheaterRuntime> Theaters { get; } = [];
    public List<FactionCampaignRuntime> Campaigns { get; } = [];
    public List<FactionOperationalObjectiveRuntime> Objectives { get; } = [];
    public List<FactionAssetReservationRuntime> Reservations { get; } = [];
    public List<FactionProductionProgramRuntime> ProductionPrograms { get; } = [];
}

public sealed class FactionBudgetRuntime
{
    public float ReservedCredits { get; set; }
    public float ExpansionCredits { get; set; }
    public float WarCredits { get; set; }
    public int ReservedMilitaryAssets { get; set; }
    public int ReservedLogisticsAssets { get; set; }
    public int ReservedConstructionAssets { get; set; }
}

public sealed class FactionEconomicAssessmentRuntime
{
    public int PlanCycle { get; set; }
    public DateTimeOffset UpdatedAtUtc { get; set; }
    public int MilitaryShipCount { get; set; }
    public int MinerShipCount { get; set; }
    public int TransportShipCount { get; set; }
    public int ConstructorShipCount { get; set; }
    public int ControlledSystemCount { get; set; }
    public int TargetMilitaryShipCount { get; set; }
    public int TargetMinerShipCount { get; set; }
    public int TargetTransportShipCount { get; set; }
    public int TargetConstructorShipCount { get; set; }
    public bool HasShipyard { get; set; }
    public bool HasWarIndustrySupplyChain { get; set; }
    public string? PrimaryExpansionSiteId { get; set; }
    public string? PrimaryExpansionSystemId { get; set; }
    public float ReplacementPressure { get; set; }
    public float SustainmentScore { get; set; }
    public float LogisticsSecurityScore { get; set; }
    public int CriticalShortageCount { get; set; }
    public string? IndustrialBottleneckItemId { get; set; }
    public List<FactionCommoditySignalRuntime> CommoditySignals { get; } = [];
}

public sealed class FactionThreatAssessmentRuntime
{
    public int PlanCycle { get; set; }
    public DateTimeOffset UpdatedAtUtc { get; set; }
    public int EnemyFactionCount { get; set; }
    public int EnemyShipCount { get; set; }
    public int EnemyStationCount { get; set; }
    public string? PrimaryThreatFactionId { get; set; }
    public string? PrimaryThreatSystemId { get; set; }
    public List<FactionThreatSignalRuntime> ThreatSignals { get; } = [];
}

public sealed class FactionTheaterRuntime
{
    public required string Id { get; init; }
    public required string Kind { get; set; }
    public required string SystemId { get; set; }
    public string Status { get; set; } = "active";
    public float Priority { get; set; }
    public float SupplyRisk { get; set; }
    public float FriendlyAssetValue { get; set; }
    public string? TargetFactionId { get; set; }
    public string? AnchorEntityId { get; set; }
    public Vector3? AnchorPosition { get; set; }
    public DateTimeOffset UpdatedAtUtc { get; set; } = DateTimeOffset.UtcNow;
    public List<string> CampaignIds { get; } = [];
}

public sealed class FactionCampaignRuntime
{
    public required string Id { get; init; }
    public required string Kind { get; set; }
    public string Status { get; set; } = "planned";
    public float Priority { get; set; }
    public string? TheaterId { get; set; }
    public string? TargetFactionId { get; set; }
    public string? TargetSystemId { get; set; }
    public string? TargetEntityId { get; set; }
    public string? CommodityId { get; set; }
    public string? SupportStationId { get; set; }
    public int CurrentStepIndex { get; set; }
    public DateTimeOffset CreatedAtUtc { get; set; } = DateTimeOffset.UtcNow;
    public DateTimeOffset UpdatedAtUtc { get; set; } = DateTimeOffset.UtcNow;
    public string? Summary { get; set; }
    public string? PauseReason { get; set; }
    public float ContinuationScore { get; set; }
    public float SupplyAdequacy { get; set; }
    public float ReplacementPressure { get; set; }
    public int FailureCount { get; set; }
    public int SuccessCount { get; set; }
    public string? FleetCommanderId { get; set; }
    public bool RequiresReinforcement { get; set; }
    public List<FactionPlanStepRuntime> Steps { get; } = [];
    public List<string> ObjectiveIds { get; } = [];
}

public sealed class FactionOperationalObjectiveRuntime
{
    public required string Id { get; init; }
    public required string CampaignId { get; set; }
    public string? TheaterId { get; set; }
    public required string Kind { get; set; }
    public required string DelegationKind { get; set; }
    public required string BehaviorKind { get; set; }
    public string Status { get; set; } = "planned";
    public float Priority { get; set; }
    public string? CommanderId { get; set; }
    public string? HomeSystemId { get; set; }
    public string? HomeStationId { get; set; }
    public string? TargetSystemId { get; set; }
    public string? TargetEntityId { get; set; }
    public Vector3? TargetPosition { get; set; }
    public string? ItemId { get; set; }
    public string? Notes { get; set; }
    public int CurrentStepIndex { get; set; }
    public DateTimeOffset CreatedAtUtc { get; set; } = DateTimeOffset.UtcNow;
    public DateTimeOffset UpdatedAtUtc { get; set; } = DateTimeOffset.UtcNow;
    public bool UseOrders { get; set; }
    public string? StagingOrderKind { get; set; }
    public int ReinforcementLevel { get; set; }
    public List<FactionPlanStepRuntime> Steps { get; } = [];
    public List<string> ReservedAssetIds { get; } = [];
}

public sealed class FactionPlanStepRuntime
{
    public required string Id { get; init; }
    public required string Kind { get; set; }
    public string Status { get; set; } = "planned";
    public string? Summary { get; set; }
    public string? BlockingReason { get; set; }
}

public sealed class FactionAssetReservationRuntime
{
    public required string Id { get; init; }
    public required string ObjectiveId { get; set; }
    public string? CampaignId { get; set; }
    public required string AssetKind { get; set; }
    public required string AssetId { get; set; }
    public float Priority { get; set; }
    public DateTimeOffset CreatedAtUtc { get; set; } = DateTimeOffset.UtcNow;
    public DateTimeOffset UpdatedAtUtc { get; set; } = DateTimeOffset.UtcNow;
}

public sealed class FactionProductionProgramRuntime
{
    public required string Id { get; init; }
    public required string Kind { get; set; }
    public string Status { get; set; } = "planned";
    public float Priority { get; set; }
    public string? CampaignId { get; set; }
    public string? CommodityId { get; set; }
    public string? ModuleId { get; set; }
    public string? ShipKind { get; set; }
    public string? TargetSystemId { get; set; }
    public int TargetCount { get; set; }
    public int CurrentCount { get; set; }
    public string? Notes { get; set; }
}

public sealed class FactionDecisionLogEntryRuntime
{
    public required string Id { get; init; }
    public required string Kind { get; set; }
    public required string Summary { get; set; }
    public string? RelatedEntityId { get; set; }
    public int PlanCycle { get; set; }
    public DateTimeOffset OccurredAtUtc { get; set; } = DateTimeOffset.UtcNow;
}

public sealed class FactionCommoditySignalRuntime
{
    public required string ItemId { get; init; }
    public float AvailableStock { get; set; }
    public float OnHand { get; set; }
    public float ProductionRatePerSecond { get; set; }
    public float CommittedProductionRatePerSecond { get; set; }
    public float UsageRatePerSecond { get; set; }
    public float NetRatePerSecond { get; set; }
    public float ProjectedNetRatePerSecond { get; set; }
    public float LevelSeconds { get; set; }
    public string Level { get; set; } = "unknown";
    public float ProjectedProductionRatePerSecond { get; set; }
    public float BuyBacklog { get; set; }
    public float ReservedForConstruction { get; set; }
}

public sealed class FactionThreatSignalRuntime
{
    public required string ScopeId { get; init; }
    public required string ScopeKind { get; init; }
    public int EnemyShipCount { get; set; }
    public int EnemyStationCount { get; set; }
    public string? EnemyFactionId { get; set; }
}
