namespace ZB.MOM.WW.ScadaBridge.CentralUI.ScriptAnalysis;

/// <summary>
/// Which runtime globals surface a script is analyzed against. Template and
/// shared scripts see <see cref="SandboxScriptHost"/> (mirroring the site
/// runtime's ScriptGlobals); inbound API method scripts see
/// <see cref="InboundScriptHost"/> (with <c>Route</c> and <c>Parameters</c>).
/// </summary>
public enum ScriptKind
{
    Template,
    InboundApi
}

public record DiagnoseRequest(
    string Code,
    IReadOnlyList<string>? DeclaredParameters = null,
    IReadOnlyList<ScriptShape>? SiblingScripts = null,
    IReadOnlyList<AttributeShape>? SelfAttributes = null,
    IReadOnlyList<CompositionContext>? Children = null,
    CompositionContext? Parent = null,
    ScriptKind Kind = ScriptKind.Template);

public record DiagnoseResponse(IReadOnlyList<DiagnosticMarker> Markers);

/// <summary>
/// Shape Monaco's setModelMarkers expects (with severity mapped to Monaco's
/// MarkerSeverity enum: 1=Hint, 2=Info, 4=Warning, 8=Error).
/// </summary>
public record DiagnosticMarker(
    int Severity,
    int StartLineNumber,
    int StartColumn,
    int EndLineNumber,
    int EndColumn,
    string Message,
    string Code);

public record CompletionsRequest(
    string CodeText,
    int Line,
    int Column,
    IReadOnlyList<string>? DeclaredParameters = null,
    IReadOnlyList<ScriptShape>? SiblingScripts = null,
    IReadOnlyList<AttributeShape>? SelfAttributes = null,
    IReadOnlyList<CompositionContext>? Children = null,
    CompositionContext? Parent = null,
    ScriptKind Kind = ScriptKind.Template);

public record CompletionsResponse(IReadOnlyList<CompletionItem> Items);

public record CompletionItem(
    string Label,
    string InsertText,
    string Detail,
    string Kind,
    /// <summary>Monaco CompletionItemInsertTextRule. 4 = InsertAsSnippet.</summary>
    int InsertTextRules = 0);

public record HoverRequest(
    string CodeText,
    int Line,
    int Column,
    IReadOnlyList<ScriptShape>? SiblingScripts = null,
    IReadOnlyList<ParameterShape>? DeclaredParameters = null,
    IReadOnlyList<AttributeShape>? SelfAttributes = null,
    IReadOnlyList<CompositionContext>? Children = null,
    CompositionContext? Parent = null);

public record HoverResponse(string? Markdown);

public record SignatureHelpRequest(
    string CodeText,
    int Line,
    int Column,
    IReadOnlyList<ScriptShape>? SiblingScripts = null,
    IReadOnlyList<CompositionContext>? Children = null,
    CompositionContext? Parent = null);

public record SignatureHelpResponse(
    string? Label,
    IReadOnlyList<SignatureHelpParameter>? Parameters,
    int ActiveParameter);

public record SignatureHelpParameter(string Label, string? Documentation);

/// <summary>
/// Shape metadata for a script. Captured from the form's ParameterListEditor
/// and ReturnTypeEditor (for siblings) or from SharedScriptCatalog (for shared
/// scripts). Used by hover, signature-help, snippet expansion, and the
/// argument-count diagnostic.
/// </summary>
public record ScriptShape(
    string Name,
    IReadOnlyList<ParameterShape> Parameters,
    string? ReturnType);

public record ParameterShape(string Name, string Type, bool Required);

/// <summary>
/// Attribute declared on a template: name + canonical SCADA type (Boolean,
/// Integer, Float, String, Object, List).
/// </summary>
public record AttributeShape(string Name, string Type);

/// <summary>
/// One end of a composition relationship — either a child (referenced by
/// composition instance name) or the parent (referenced by template name).
/// The shape carries the attributes and scripts at that scope so the editor
/// can complete <c>Children["X"].Attributes["Y"]</c> and
/// <c>Children["X"].CallScript("Z")</c> with the right metadata.
/// </summary>
public record CompositionContext(
    string Name,
    IReadOnlyList<AttributeShape> Attributes,
    IReadOnlyList<ScriptShape> Scripts);

public record FormatRequest(string Code);
public record FormatResponse(string Code);

public record InlayHintsRequest(
    string Code,
    IReadOnlyList<ScriptShape>? SiblingScripts = null);

public record InlayHintsResponse(IReadOnlyList<InlayHint> Hints);

public record InlayHint(int Line, int Column, string Label);
