namespace MiGu.Server.Ota;

public sealed class OtaSettings
{
    public int BandwidthKbps { get; set; }
    public int MaxCar { get; set; } = 2;
    public bool LatencyEnabled { get; set; }
    public int RttThresholdMs { get; set; } = 200;
    /// <summary>skip | confirm</summary>
    public string OverThreshold { get; set; } = "skip";
    public int BackupPeriodMinutes { get; set; } = 60;
    public bool BackupExe { get; set; }
    public string? NewVersionName { get; set; }
}

public sealed class OtaFileArtifact
{
    public string Hash { get; set; } = "";
    public string Path { get; set; } = "";
    public string FileName { get; set; } = "";
    public string? Time { get; set; }
    public long Size { get; set; }
}

public sealed class OtaTarget
{
    public string PackageId { get; set; } = "";
    public string? Name { get; set; }
    public DateTimeOffset ActivatedAt { get; set; }
    public Dictionary<string, OtaFileArtifact> Components { get; set; } = new(StringComparer.OrdinalIgnoreCase);
}

public sealed class OtaPackageInfo
{
    public string Id { get; set; } = "";
    public string? SourceIp { get; set; }
    public DateTimeOffset CreatedAt { get; set; }
    public long TotalBytes { get; set; }
    public bool IsTarget { get; set; }
    public Dictionary<string, OtaFileArtifact> Components { get; set; } = new(StringComparer.OrdinalIgnoreCase);
}

public sealed class OtaComponentVersion
{
    public string? Version { get; set; }
    public string? Time { get; set; }
}

public sealed class OtaAppVersions
{
    public OtaComponentVersion? Exe { get; set; }
    public OtaComponentVersion? Dll { get; set; }
    public OtaComponentVersion? Pdb { get; set; }
}

public sealed class OtaVehicleRow
{
    public string Id { get; set; } = "";
    public string Name { get; set; } = "";
    public string? Ip { get; set; }
    public string? State { get; set; }
    public string? Group { get; set; }
    public bool Reachable { get; set; }
    public int? RttMs { get; set; }
    public OtaAppVersions? Medulla { get; set; }
    public OtaAppVersions? Detour { get; set; }
    public OtaAppVersions? Clumsy { get; set; }
    public Dictionary<string, string>? Match { get; set; }
}

public sealed class OtaJobStep
{
    public string CarId { get; set; } = "";
    public string? Ip { get; set; }
    public string Component { get; set; } = "";
    public string Status { get; set; } = "pending";
    public string? Error { get; set; }
}

public sealed class OtaJob
{
    public string Id { get; set; } = "";
    /// <summary>sync | customFile | configPush</summary>
    public string Kind { get; set; } = "sync";
    public string Status { get; set; } = "pending";
    public DateTimeOffset CreatedAt { get; set; }
    public DateTimeOffset? FinishedAt { get; set; }
    public string? CreatedBy { get; set; }
    public string? PackageId { get; set; }
    public List<string> CarIds { get; set; } = new();
    public List<string> Components { get; set; } = new();
    public bool RequireLatencyCheck { get; set; }
    public int DoneSteps { get; set; }
    public int TotalSteps { get; set; }
    public List<OtaJobStep> Steps { get; set; } = new();
    public string? Message { get; set; }
    // customFile
    public string? CustomFileName { get; set; }
    public string? CustomRemotePath { get; set; }
    public int? CustomRestartOp { get; set; }
    public string? CustomLocalPath { get; set; }
    public List<OtaCustomFileItem> CustomFiles { get; set; } = new();
    public List<int> CustomRestartOps { get; set; } = new() { -1 };
    // configPush
    public string? ConfigApp { get; set; }
    public string? ConfigJson { get; set; }
}

public sealed class CreateSyncJobRequest
{
    public List<string> CarIds { get; set; } = new();
    public List<string>? Components { get; set; }
    public bool? RequireLatencyCheck { get; set; }
}

public sealed class PullPackageRequest
{
    public string CarId { get; set; } = "";
}

public sealed class CreateCustomFileJobRequest
{
    public List<string> CarIds { get; set; } = new();
    public string RemotePath { get; set; } = "";
    /// <summary>兼容旧单值；优先用 RestartOps。</summary>
    public int RestartOp { get; set; } = -1;
    /// <summary>-1 不重启；0 Medulla；1 Clumsy；2 Detour；3 WatchDog。可多选。</summary>
    public List<int>? RestartOps { get; set; }
    public bool? RequireLatencyCheck { get; set; }
}

public sealed class OtaCustomFileItem
{
    public string LocalPath { get; set; } = "";
    public string FileName { get; set; } = "";
}

public sealed class CreateConfigPushRequest
{
    public List<string> CarIds { get; set; } = new();
    public string App { get; set; } = "";
    public string Json { get; set; } = "";
    public bool? RequireLatencyCheck { get; set; }
}
