using System.Text;
using System.Text.Json;
using Flyshot.Core.Domain;

namespace Flyshot.Core.Planning.Export;

/// <summary>
/// 将规划结果导出为与 Python demo 格式兼容的文本文件。
///
/// 为什么用空格分隔而不是 CSV？
/// ---
/// 空格分隔是最简单的列对齐格式，不需要额外引号处理，也方便用 numpy.loadtxt
/// 或 C++ 的 fscanf 直接读取。真机侧的状态日志通常也是空格分隔的纯文本，
/// 保持一致便于后续做自动化 diff。
/// </summary>
public static class TrajectoryExporter
{
    /// <summary>
    /// 导出稠密关节轨迹到文本文件。
    /// </summary>
    public static void WriteJointDenseTrajectory(string path, IReadOnlyList<IReadOnlyList<double>> rows)
    {
        WriteDenseRows(path, rows);
    }

    /// <summary>
    /// 导出稠密笛卡尔轨迹到文本文件。
    /// </summary>
    public static void WriteCartesianDenseTrajectory(string path, IReadOnlyList<IReadOnlyList<double>> rows)
    {
        WriteDenseRows(path, rows);
    }

    /// <summary>
    /// 导出触发事件到 JSON 文件。
    /// </summary>
    public static void WriteShotEvents(string path, IReadOnlyList<ShotEvent> events)
    {
        var payload = events.Select(e => new
        {
            waypoint_index = e.WaypointIndex,
            trigger_time = Math.Round(e.TriggerTime, 6),
            sample_index = e.SampleIndex,
            sample_time = Math.Round(e.SampleTime, 6),
            addrs = e.AddressGroup.Addresses.ToList()
        }).ToList();

        var json = JsonSerializer.Serialize(payload, new JsonSerializerOptions
        {
            WriteIndented = true
        });

        File.WriteAllText(path, json, new UTF8Encoding(false));
    }

    private static void WriteDenseRows(string path, IReadOnlyList<IReadOnlyList<double>> rows)
    {
        var sb = new StringBuilder();
        foreach (var row in rows)
        {
            sb.AppendLine(string.Join(" ", row.Select(v => $"{v:F6}")));
        }

        File.WriteAllText(path, sb.ToString(), new UTF8Encoding(false));
    }
}
