namespace SpaceGame.Api.Ships.Runtime;

public sealed class ShipRuntime
{
    public required string Id { get; init; }
    public required string SystemId { get; set; }
    public required ShipDefinition Definition { get; init; }
    public required string FactionId { get; init; }
    public required Vector3 Position { get; set; }
    public required Vector3 TargetPosition { get; set; }
    public required ShipSpatialStateRuntime SpatialState { get; set; }
    public Vector3 Velocity { get; set; } = Vector3.Zero;
    public ShipState State { get; set; } = ShipState.Idle;
    public required DefaultBehaviorRuntime DefaultBehavior { get; set; }
    public List<ShipOrderRuntime> OrderQueue { get; } = [];
    public ShipPlanRuntime? ActivePlan { get; set; }
    public required ShipSkillProfileRuntime Skills { get; set; }
    public bool NeedsReplan { get; set; } = true;
    public float ReplanCooldownSeconds { get; set; }
    public Dictionary<string, float> Inventory { get; } = new(StringComparer.Ordinal);
    public string? DockedStationId { get; set; }
    public int? AssignedDockingPadIndex { get; set; }
    public string? CommanderId { get; set; }
    public string? PolicySetId { get; set; }
    public string ControlSourceKind { get; set; } = "unassigned";
    public string? ControlSourceId { get; set; }
    public string? ControlReason { get; set; }
    public string? LastReplanReason { get; set; }
    public string? LastAccessFailureReason { get; set; }
    public float Health { get; set; }
    public HashSet<string> KnownStationIds { get; } = new(StringComparer.Ordinal);
    public List<string> History { get; } = [];
    public string LastSignature { get; set; } = string.Empty;
    public string LastDeltaSignature { get; set; } = string.Empty;
}

public sealed class ShipSkillProfileRuntime
{
    public int Navigation { get; set; }
    public int Trade { get; set; }
    public int Mining { get; set; }
    public int Combat { get; set; }
    public int Construction { get; set; }
}

public sealed class ShipOrderRuntime
{
    public required string Id { get; init; }
    public required string Kind { get; init; }
    public required ShipOrderSourceKind SourceKind { get; init; }
    public required string SourceId { get; init; }
    public OrderStatus Status { get; set; } = OrderStatus.Queued;
    public int Priority { get; set; }
    public bool InterruptCurrentPlan { get; set; } = true;
    public DateTimeOffset CreatedAtUtc { get; init; } = DateTimeOffset.UtcNow;
    public string? Label { get; set; }
    public string? TargetEntityId { get; set; }
    public string? TargetSystemId { get; set; }
    public Vector3? TargetPosition { get; set; }
    public string? SourceStationId { get; set; }
    public string? DestinationStationId { get; set; }
    public string? ItemId { get; set; }
    public string? NodeId { get; set; }
    public string? ConstructionSiteId { get; set; }
    public string? ModuleId { get; set; }
    public float WaitSeconds { get; set; }
    public float Radius { get; set; }
    public int? MaxSystemRange { get; set; }
    public bool KnownStationsOnly { get; set; }
    public string? FailureReason { get; set; }
}

public sealed class DefaultBehaviorRuntime
{
    public required string Kind { get; set; }
    public string? HomeSystemId { get; set; }
    public string? HomeStationId { get; set; }
    public string? AreaSystemId { get; set; }
    public string? TargetEntityId { get; set; }
    public string? ItemId { get; set; }
    public string? PreferredNodeId { get; set; }
    public string? PreferredConstructionSiteId { get; set; }
    public string? PreferredModuleId { get; set; }
    public Vector3? TargetPosition { get; set; }
    public float WaitSeconds { get; set; } = 3f;
    public float Radius { get; set; } = 24f;
    public int MaxSystemRange { get; set; }
    public bool KnownStationsOnly { get; set; }
    public List<Vector3> PatrolPoints { get; set; } = [];
    public int PatrolIndex { get; set; }
    public List<ShipOrderTemplateRuntime> RepeatOrders { get; set; } = [];
    public int RepeatIndex { get; set; }
}

public sealed class ShipOrderTemplateRuntime
{
    public required string Kind { get; init; }
    public string? Label { get; set; }
    public string? TargetEntityId { get; set; }
    public string? TargetSystemId { get; set; }
    public Vector3? TargetPosition { get; set; }
    public string? SourceStationId { get; set; }
    public string? DestinationStationId { get; set; }
    public string? ItemId { get; set; }
    public string? NodeId { get; set; }
    public string? ConstructionSiteId { get; set; }
    public string? ModuleId { get; set; }
    public float WaitSeconds { get; set; }
    public float Radius { get; set; }
    public int? MaxSystemRange { get; set; }
    public bool KnownStationsOnly { get; set; }
}

public sealed class ShipPlanRuntime
{
    public required string Id { get; init; }
    public required AiPlanSourceKind SourceKind { get; init; }
    public required string SourceId { get; init; }
    public required string Kind { get; init; }
    public required string Summary { get; set; }
    public AiPlanStatus Status { get; set; } = AiPlanStatus.Planned;
    public int CurrentStepIndex { get; set; }
    public DateTimeOffset CreatedAtUtc { get; init; } = DateTimeOffset.UtcNow;
    public DateTimeOffset UpdatedAtUtc { get; set; } = DateTimeOffset.UtcNow;
    public string? InterruptReason { get; set; }
    public string? FailureReason { get; set; }
    public List<ShipPlanStepRuntime> Steps { get; } = [];
}

public sealed class ShipPlanStepRuntime
{
    public required string Id { get; init; }
    public required string Kind { get; init; }
    public required string Summary { get; set; }
    public AiPlanStepStatus Status { get; set; } = AiPlanStepStatus.Planned;
    public int CurrentSubTaskIndex { get; set; }
    public string? BlockingReason { get; set; }
    public List<ShipSubTaskRuntime> SubTasks { get; } = [];
}

public sealed class ShipSubTaskRuntime
{
    public required string Id { get; init; }
    public required string Kind { get; init; }
    public required string Summary { get; set; }
    public WorkStatus Status { get; set; } = WorkStatus.Pending;
    public string? TargetEntityId { get; set; }
    public string? TargetSystemId { get; set; }
    public string? TargetNodeId { get; set; }
    public Vector3? TargetPosition { get; set; }
    public string? ItemId { get; set; }
    public string? ModuleId { get; set; }
    public float Threshold { get; set; }
    public float Amount { get; set; }
    public float ElapsedSeconds { get; set; }
    public float TotalSeconds { get; set; }
    public float Progress { get; set; }
    public string? BlockingReason { get; set; }
}
