using ZB.MOM.WW.OtOpcUa.Configuration.Enums;

namespace ZB.MOM.WW.OtOpcUa.AdminUI.Uns;

/// <summary>
/// Parameter object carrying the operator-editable fields for a raw <c>Tag</c> create or update in the
/// v3 Raw tree (WP4 manual entry). Identity is the RawPath — the tag's device + optional tag-group +
/// name — so there is no <c>TagId</c> here: it is generated on create and never carried in the input.
/// Whitespace-only <see cref="PollGroupId"/> collapses to <c>null</c>; <see cref="TagConfig"/> is
/// validated for JSON well-formedness by the service (blank collapses to <c>{}</c>).
/// </summary>
/// <param name="Name">The tag name (a RawPath segment).</param>
/// <param name="DataType">OPC UA built-in type name (Boolean / Int32 / Float / etc.).</param>
/// <param name="AccessLevel">Tag-level OPC UA access baseline.</param>
/// <param name="WriteIdempotent">Whether writes to this tag are safe to retry.</param>
/// <param name="PollGroupId">Optional poll-group batching key; whitespace/empty collapses to <c>null</c>.</param>
/// <param name="TagConfig">Schemaless per-driver-type JSON config; validated for JSON well-formedness.</param>
public sealed record RawTagInput(
    string Name,
    string DataType,
    TagAccessLevel AccessLevel,
    bool WriteIdempotent,
    string? PollGroupId,
    string TagConfig);

/// <summary>
/// One row of the WP5 CSV import commit. <see cref="TagGroupPath"/> is a <c>/</c>-separated tag-group
/// path under the target device (its segments are auto-created as nested <c>TagGroup</c>s, reusing any
/// that already exist); <c>null</c>/blank places the tag directly under the device. <see cref="Tag"/>
/// carries the tag's editable fields.
/// </summary>
/// <param name="TagGroupPath">The <c>/</c>-separated group path under the device, or null for the device root.</param>
/// <param name="Tag">The tag's editable fields.</param>
public sealed record RawTagImportRow(string? TagGroupPath, RawTagInput Tag);

/// <summary>
/// Outcome of <see cref="IRawTreeService.ImportTagsAsync"/>. The import is all-or-nothing: on any
/// per-row validation error nothing is inserted, <see cref="Inserted"/> is <c>0</c>, and
/// <see cref="Errors"/> carries the operator-facing per-row messages. On success <see cref="Errors"/>
/// is empty and <see cref="Inserted"/> is the number of tags committed.
/// </summary>
/// <param name="Inserted">The number of tags inserted (0 when any row errored).</param>
/// <param name="Errors">The per-row validation errors; empty on success.</param>
public sealed record RawTagImportResult(int Inserted, IReadOnlyList<string> Errors);
