using System;
using System.Collections.Generic;
using MultiWheelC.TrajectoryPlanning.Utils;

namespace MultiWheelC.TrajectoryPlanning.Mapping;

/// <summary>
/// 环境占据图构建结果。
/// 返回：成功时提供可供适配的 EnvironmentGridMap；失败时提供失败原因和已处理来源状态。
/// </summary>
public sealed class EnvironmentMapBuildResult
{
    private EnvironmentMapBuildResult(bool succeeded, EnvironmentGridMap map, IReadOnlyList<ObstacleProjectionResult> sourceResults, string failureReason, PlanningOperationStopReason stopReason)
    {
        Succeeded = succeeded; Map = map; SourceResults = sourceResults ?? Array.Empty<ObstacleProjectionResult>(); FailureReason = failureReason ?? string.Empty; StopReason = stopReason;
    }
    /// <summary>构建是否成功。true 时 Map 非空；false 时读取 FailureReason。</summary>
    public bool Succeeded { get; }
    /// <summary>成功生成的构建期环境栅格；失败时为 null。</summary>
    public EnvironmentGridMap Map { get; }
    /// <summary>已尝试来源的投影结果，用于记录已应用、空或失败状态。</summary>
    public IReadOnlyList<ObstacleProjectionResult> SourceResults { get; }
    /// <summary>失败原因。成功时为空字符串。</summary>
    public string FailureReason { get; }
    /// <summary>内部预算停止原因；普通构建成功或失败时为 None。</summary>
    internal PlanningOperationStopReason StopReason { get; }
    /// <summary>创建成功结果。参数 map 为已完成栅格，sourceResults 为来源投影记录。</summary>
    public static EnvironmentMapBuildResult Success(EnvironmentGridMap map, IReadOnlyList<ObstacleProjectionResult> sourceResults) { return new EnvironmentMapBuildResult(true, map, sourceResults, null, PlanningOperationStopReason.None); }
    /// <summary>创建失败结果。参数 reason 为诊断文本，sourceResults 可包含失败前已处理的来源。</summary>
    public static EnvironmentMapBuildResult Failure(string reason, IReadOnlyList<ObstacleProjectionResult> sourceResults) { return new EnvironmentMapBuildResult(false, null, sourceResults, reason, PlanningOperationStopReason.None); }
    /// <summary>创建已取消或超时结果；不发布构建期可写地图。</summary>
    internal static EnvironmentMapBuildResult Stopped(PlanningOperationStopReason stopReason, IReadOnlyList<ObstacleProjectionResult> sourceResults)
    {
        if (stopReason == PlanningOperationStopReason.None) throw new ArgumentOutOfRangeException(nameof(stopReason));
        return new EnvironmentMapBuildResult(false, null, sourceResults,
            stopReason == PlanningOperationStopReason.Cancelled ? "地图构建已取消。" : "地图构建已超时。", stopReason);
    }
}
