@using RobotNet.Shares
@using RobotNet.Clients
@using RobotNet.WebApp.Scripts.Models

@inject ISnackbar Snackbar
@inject IHttpClientFactory httpFactory

<MudDialog>
    <TitleContent>
        <MudText Typo="Typo.h6">
            @Title
        </MudText>
    </TitleContent>
    <DialogContent>
        <div class="d-flex flex-column" style="width: 500px;">
            @foreach (var param in Model.Parameters)
            {
                <div class="d-flex align-items-center mb-2">
                    <div class="d-flex flex-row-reverse me-2" style="width: 200px;">
                        <MudText>@param.Name : </MudText>
                    </div>
                    <div style="flex: 1;">
                        @switch (param.Type)
                        {
                            case "System.Boolean":
                                <MudSwitch T="bool" Color="Color.Primary" @bind-Value="@param.BoolValue" />
                                break;
                            case "System.Byte":
                                <MudNumericField T="byte"
                                                 @bind-Value="@param.ByteValue"
                                                 Min="@System.Byte.MinValue"
                                                 Max="@System.Byte.MaxValue"
                                                 Label="@param.Type"
                                                 ShrinkLabel="true"
                                                 Variant="Variant.Outlined"
                                                 Margin="Margin.Dense" />
                                break;
                            case "System.SByte":
                                <MudNumericField T="sbyte"
                                                 @bind-Value="@param.SByteValue"
                                                 Min="@System.SByte.MinValue"
                                                 Max="@System.SByte.MaxValue"
                                                 Label="@param.Type"
                                                 ShrinkLabel="true"
                                                 Variant="Variant.Outlined"
                                                 Margin="Margin.Dense" />
                                break;
                            case "System.Int16":
                                <MudNumericField T="short"
                                                 @bind-Value="@param.ShortValue"
                                                 Min="@System.Int16.MinValue"
                                                 Max="@System.Int16.MaxValue"
                                                 Label="@param.Type"
                                                 ShrinkLabel="true"
                                                 Variant="Variant.Outlined"
                                                 Margin="Margin.Dense" />
                                break;
                            case "System.UInt16":
                                <MudNumericField T="ushort"
                                                 @bind-Value="@param.UShortValue"
                                                 Min="@System.UInt16.MinValue"
                                                 Max="@System.UInt16.MaxValue"
                                                 Label="@param.Type"
                                                 ShrinkLabel="true"
                                                 Variant="Variant.Outlined"
                                                 Margin="Margin.Dense" />
                                break;
                            case "System.Int32":
                                <MudNumericField T="int"
                                                 @bind-Value="@param.IntValue"
                                                 Min="@System.Int32.MinValue"
                                                 Max="@System.Int32.MaxValue"
                                                 Label="@param.Type"
                                                 ShrinkLabel="true"
                                                 Variant="Variant.Outlined"
                                                 Margin="Margin.Dense" />
                                break;
                            case "System.UInt32":
                                <MudNumericField T="uint"
                                                 @bind-Value="@param.UIntValue"
                                                 Min="@System.UInt32.MinValue"
                                                 Max="@System.UInt32.MaxValue"
                                                 Label="@param.Type"
                                                 ShrinkLabel="true"
                                                 Variant="Variant.Outlined"
                                                 Margin="Margin.Dense" />
                                break;
                            case "System.Int64":
                                <MudNumericField T="long"
                                                 @bind-Value="@param.LongValue"
                                                 Min="@System.Int64.MinValue"
                                                 Max="@System.Int64.MaxValue"
                                                 Label="@param.Type"
                                                 ShrinkLabel="true"
                                                 Variant="Variant.Outlined"
                                                 Margin="Margin.Dense" />
                                break;
                            case "System.UInt64":
                                <MudNumericField T="ulong"
                                                 @bind-Value="@param.ULongValue"
                                                 Min="@System.UInt64.MinValue"
                                                 Max="@System.UInt64.MaxValue"
                                                 Label="@param.Type"
                                                 ShrinkLabel="true"
                                                 Variant="Variant.Outlined"
                                                 Margin="Margin.Dense" />
                                break;
                            case "System.Single":
                                <MudNumericField T="float"
                                                 @bind-Value="@param.FloatValue"
                                                 Min="@System.Single.MinValue"
                                                 Max="@System.Single.MaxValue"
                                                 Label="@param.Type"
                                                 ShrinkLabel="true"
                                                 Variant="Variant.Outlined"
                                                 Margin="Margin.Dense" />
                                break;
                            case "System.Double":
                                <MudNumericField T="double"
                                                 @bind-Value="@param.DoubleValue"
                                                 Min="@System.Double.MinValue"
                                                 Max="@System.Double.MaxValue"
                                                 Label="@param.Type"
                                                 ShrinkLabel="true"
                                                 Variant="Variant.Outlined"
                                                 Margin="Margin.Dense" />
                                break;
                            case "System.Decimal":
                                <MudNumericField T="decimal"
                                                 @bind-Value="@param.DecimalValue"
                                                 Label="@param.Type"
                                                 ShrinkLabel="true"
                                                 Variant="Variant.Outlined"
                                                 Margin="Margin.Dense" />
                                break;
                            case "System.String":
                                <MudTextField @bind-Value="@param.StringValue"
                                              Label="@param.Type"
                                              ShrinkLabel="true"
                                              Variant="Variant.Outlined"
                                              Margin="Margin.Dense" />
                                break;
                            case "System.Char":
                                <MudTextField @bind-Value="@param.CharValue"
                                              MaxLength="1"
                                              Label="@param.Type"
                                              ShrinkLabel="true"
                                              Variant="Variant.Outlined"
                                              Margin="Margin.Dense" />
                                break;
                            case "System.Threading.CancellationToken":
                                <span>
                                    &lt;CancellationToken&gt;
                                </span>
                                break;
                            default:
                                <MudAlert Severity="Severity.Error" Dense>Unsupport parameter with type @param.Type</MudAlert>
                                break;
                        }
                    </div>
                </div>
            }
        </div>
    </DialogContent>
    <DialogActions>
        <MudButton OnClick="OnCancel">Cancel</MudButton>
        <MudButton Color="Color.Primary" OnClick="Instantiate" Disabled="@IsInstantiating">Instantiate</MudButton>
    </DialogActions>
</MudDialog>

@code {
    [CascadingParameter]
    private IMudDialogInstance Dialog { get; set; } = null!;

    [Parameter, EditorRequired]
    public ScriptMissionModel Model { get; set; } = default!;

    public string Title => $"Instantiate Mission {Model.Name}";
    private HttpClient http = default!;

    private bool IsInstantiating = false;

    protected override void OnInitialized()
    {
        base.OnInitialized();
        http = httpFactory.CreateClient("ScriptManagerAPI");
    }

    private void OnCancel() => Dialog.Cancel();

    private async Task Instantiate()
    {
        if (IsInstantiating) return;
        IsInstantiating = true;
        StateHasChanged(); // Force UI update to reflect instantiation state

        var parameters = Model.Parameters
            .Where(p => p.Type != "RobotNet.Script.IRobot")
            .ToDictionary(p => p.Name, p => p.ToString());

        var result = await http.PostFromJsonAsync<MessageResult<Guid>>("api/ScriptMissions/Runner", new InstanceMissionCreateModel(Model.Name, parameters));
        if (result is null)
        {
            Snackbar.Add("Failed to instantiate mission: server response null", Severity.Error);
        }
        else if (result.IsSuccess)
        {
            Snackbar.Add($"Mission {Model.Name} instantiated successfully with ID: {result.Data}", Severity.Success);
            Dialog.Close(DialogResult.Ok(Model.Name));
        }
        else
        {
            Snackbar.Add($"Failed to instantiate mission: {result.Message}", Severity.Error);
        }
    }
}
