@attribute [Route(Routes.ASSISTANT_DYNAMIC)]
@using AIStudio.Agents.AssistantAudit
@using AIStudio.Tools.PluginSystem.Assistants.DataModel
@using AIStudio.Tools.PluginSystem.Assistants.DataModel.Layout
@inherits AssistantBaseCore<AIStudio.Dialogs.Settings.NoSettingsPanel>

@if (!string.IsNullOrWhiteSpace(this.securityMessage))
{
    <MudPaper Class="pa-4 ma-4" Elevation="0">
        <MudAlert Severity="Severity.Error" Variant="Variant.Filled" Square="false" Elevation="6" Class="pa-4">
            @this.securityMessage
        </MudAlert>
        @if (this.assistantPlugin is not null)
        {
            <div class="mt-4">
                <AssistantPluginSecurityCard Plugin="@this.assistantPlugin"/>
            </div>
        }
    </MudPaper>
}
else if (this.RootComponent is null)
{
    <MudAlert Severity="Severity.Warning">
        @this.T("No assistant plugin are currently installed.")
    </MudAlert>
}
else
{
    @if (this.audit is not null && this.audit.Level is not AssistantAuditLevel.SAFE)
    {
        <MudPaper Class="pa-4 ma-4" Elevation="0">
            <MudAlert Severity="@this.audit.Level.GetSeverity()" Variant="Variant.Filled" Square="false" Elevation="6" Class="pa-4">
                <strong>@this.audit.Level.GetName().ToUpperInvariant(): </strong>@this.audit.Summary
            </MudAlert>
        </MudPaper>
    }

    @foreach (var component in this.RootComponent.Children)
    {
        @this.RenderComponent(component)
    }
}

@code {
    private protected override RenderFragment? HeaderActions => this.CanReviseCurrentAssistant
        ? @<MudTooltip Text="@T("Revise assistant")">
              <MudIconButton Variant="Variant.Text" Icon="@Icons.Material.Filled.AutoMode" OnClick="@(async () => await this.OpenRevisionDialogAsync())"/>
          </MudTooltip>
        : null;

    private RenderFragment RenderSwitch(AssistantSwitch assistantSwitch) => @<MudSwitch T="bool"
                Value="@this.assistantState.Booleans[assistantSwitch.Name]"
                ValueChanged="@(value => this.ExecuteSwitchChangedAsync(assistantSwitch, value))"
                LabelPlacement="@assistantSwitch.GetLabelPlacement()"
                Color="@AssistantSwitch.GetColor(assistantSwitch.CheckedColor)"
                UncheckedColor="@AssistantSwitch.GetColor(assistantSwitch.UncheckedColor)"
                ThumbIcon="@assistantSwitch.GetIconSvg()"
                ThumbIconColor="@AssistantSwitch.GetColor(assistantSwitch.IconColor)"
                Disabled="@(assistantSwitch.Disabled || this.IsSwitchActionRunning(assistantSwitch.Name))"
                Class="@assistantSwitch.Class"
                Style="@GetOptionalStyle(assistantSwitch.Style)">
        @(this.assistantState.Booleans[assistantSwitch.Name] ? assistantSwitch.LabelOn : assistantSwitch.LabelOff)
    </MudSwitch>;
}

@code {private RenderFragment RenderChildren(IEnumerable<IAssistantComponent> children) => @<text>
        @foreach (var child in children)
        {
            @this.RenderComponent(child)
        }
    </text>;

    private RenderFragment RenderComponent(IAssistantComponent component) => @<text>
        @switch (component.Type)
        {
            case AssistantComponentType.TEXT_AREA:
                if (component is AssistantTextArea textArea)
                {
                    var lines = textArea.IsSingleLine ? 1 : 6;
                    var autoGrow = !textArea.IsSingleLine;

                    <MudTextField T="string"
                                  UserAttributes="@SPELLCHECK_ATTRIBUTES"
                                  Text="@this.assistantState.Text[textArea.Name]"
                                  TextChanged="@(value => this.assistantState.Text[textArea.Name] = value)"
                                  Label="@textArea.Label"
                                  HelperText="@textArea.HelperText"
                                  HelperTextOnFocus="@textArea.HelperTextOnFocus"
                                  ReadOnly="@textArea.ReadOnly"
                                  Counter="@textArea.Counter"
                                  MaxLength="@textArea.MaxLength"
                                  Immediate="@textArea.IsImmediate"
                                  Adornment="@textArea.GetAdornmentPos()"
                                  AdornmentIcon="@AssistantComponentPropHelper.GetIconSvg(textArea.AdornmentIcon)"
                                  AdornmentText="@textArea.AdornmentText"
                                  AdornmentColor="@textArea.GetAdornmentColor()"
                                  Variant="Variant.Outlined"
                                  Lines="@lines"
                                  AutoGrow="@autoGrow"
                                  MaxLines="12"
                                  Class='@MergeClass(textArea.Class, "mb-3")'
                                  Style="@GetOptionalStyle(textArea.Style)" />
                }
                break;
                
            case AssistantComponentType.IMAGE:
                if (component is AssistantImage assistantImage)
                {
                    var resolvedSource = this.ResolveImageSource(assistantImage);
                    if (!string.IsNullOrWhiteSpace(resolvedSource))
                    {
                        var image = assistantImage;
                        <div Class="mb-4">
                            <MudImage Fluid="true" Src="@resolvedSource" Alt="@image.Alt" Class='@MergeClass(image.Class, "rounded-lg mb-2")' Style="@GetOptionalStyle(image.Style)" Elevation="20" />
                            @if (!string.IsNullOrWhiteSpace(image.Caption))
                            {
                                <MudText Typo="Typo.caption" Align="Align.Center">@image.Caption</MudText>
                            }
                        </div>
                    }
                }
                break;
                
            case AssistantComponentType.WEB_CONTENT_READER:
                if (component is AssistantWebContentReader webContent)
                {
                    var webState = this.assistantState.WebContent[webContent.Name];
                    <div class="@webContent.Class" style="@GetOptionalStyle(webContent.Style)">
                        <ReadWebContent @bind-Content="@webState.Content"
                                        ProviderSettings="@this.ProviderSettings"
                                        @bind-AgentIsRunning="@webState.AgentIsRunning"
                                        @bind-Preselect="@webState.Preselect"
                                        @bind-PreselectContentCleanerAgent="@webState.PreselectContentCleanerAgent" />
                    </div>
                }
                break;
                
            case AssistantComponentType.FILE_CONTENT_READER:
                if (component is AssistantFileContentReader fileContent)
                {
                    var fileState = this.assistantState.FileContent[fileContent.Name];
                    <div class="@fileContent.Class" style="@GetOptionalStyle(fileContent.Style)">
                        <ReadFileContent @bind-FileContent="@fileState.Content" MediaImportTargetId="@fileContent.Name" EnableDragDrop="true" Layer="@DropLayers.ASSISTANTS" CatchAllDocuments="true" ShowAttachedDocumentState="@fileContent.ShowAttachedDocumentState" />
                    </div>
                }
                break;
                
            case AssistantComponentType.FILE_ATTACHMENTS:
                if (component is AssistantFileAttachment fileAttachment)
                {
                    var fileState = this.assistantState.FileAttachments[fileAttachment.Name];
                    <div class="@fileAttachment.Class mb-3" style="@GetOptionalStyle(fileAttachment.Style)">
                        @if (!string.IsNullOrWhiteSpace(fileAttachment.Heading))
                        {
                            <MudText Typo="Typo.h6" Class="mb-2">@fileAttachment.Heading</MudText>
                        }
                        <div class="px-4">
                            <AttachDocuments Name="@fileAttachment.Name"
                                             Layer="@DropLayers.ASSISTANTS"
                                             @bind-DocumentPaths="@fileState.DocumentPaths"
                                             CatchAllDocuments="@fileAttachment.CatchAllDocuments"
                                             UseSmallForm="@fileAttachment.UseSmallForm"
                                             Provider="@this.ProviderSettings"/>
                            </div>
                    </div>
                }
                break;

            case AssistantComponentType.DROPDOWN:
                if (component is AssistantDropdown assistantDropdown)
                {
                    if (assistantDropdown.IsMultiselect)
                    {
                        <DynamicAssistantDropdown Items="@assistantDropdown.Items"
                                                  SelectedValues="@this.assistantState.MultiSelect[assistantDropdown.Name]"
                                                  SelectedValuesChanged="@this.CreateMultiselectDropdownChangedCallback(assistantDropdown.Name)"
                                                  Default="@assistantDropdown.Default"
                                                  Label="@assistantDropdown.Label"
                                                  HelperText="@assistantDropdown.HelperText"
                                                  OpenIcon="@AssistantComponentPropHelper.GetIconSvg(assistantDropdown.OpenIcon)"
                                                  CloseIcon="@AssistantComponentPropHelper.GetIconSvg(assistantDropdown.CloseIcon)"
                                                  IconColor="@AssistantComponentPropHelper.GetColor(assistantDropdown.IconColor, Color.Default)"
                                                  IconPosition="@AssistantComponentPropHelper.GetAdornment(assistantDropdown.IconPositon, Adornment.End)"
                                                  Variant="@AssistantComponentPropHelper.GetVariant(assistantDropdown.Variant, Variant.Outlined)"
                                                  IsMultiselect="@true"
                                                  HasSelectAll="@assistantDropdown.HasSelectAll"
                                                  SelectAllText="@assistantDropdown.SelectAllText"
                                                  Class="@assistantDropdown.Class"
                                                  Style="@GetOptionalStyle(assistantDropdown.Style)" />
                    }
                    else
                    {
                        <DynamicAssistantDropdown Items="@assistantDropdown.Items"
                                                  Value="@this.assistantState.SingleSelect[assistantDropdown.Name]"
                                                  ValueChanged="@(value => this.assistantState.SingleSelect[assistantDropdown.Name] = value)"
                                                  Default="@assistantDropdown.Default"
                                                  Label="@assistantDropdown.Label"
                                                  HelperText="@assistantDropdown.HelperText"
                                                  OpenIcon="@AssistantComponentPropHelper.GetIconSvg(assistantDropdown.OpenIcon)"
                                                  CloseIcon="@AssistantComponentPropHelper.GetIconSvg(assistantDropdown.CloseIcon)"
                                                  IconColor="@AssistantComponentPropHelper.GetColor(assistantDropdown.IconColor, Color.Default)"
                                                  IconPosition="@AssistantComponentPropHelper.GetAdornment(assistantDropdown.IconPositon, Adornment.End)"
                                                  Variant="@AssistantComponentPropHelper.GetVariant(assistantDropdown.Variant, Variant.Outlined)"
                                                  HasSelectAll="@assistantDropdown.HasSelectAll"
                                                  SelectAllText="@assistantDropdown.SelectAllText"
                                                  Class="@assistantDropdown.Class"
                                                  Style="@GetOptionalStyle(assistantDropdown.Style)" />
                    }
                }
                break;
                
            case AssistantComponentType.BUTTON:
                if (component is AssistantButton assistantButton)
                {
                    var button = assistantButton;
                    var icon = AssistantComponentPropHelper.GetIconSvg(button.StartIcon);
                    var iconColor = AssistantComponentPropHelper.GetColor(button.IconColor, Color.Inherit);
                    var color = AssistantComponentPropHelper.GetColor(button.Color, Color.Default);
                    var size = AssistantComponentPropHelper.GetComponentSize(button.Size, Size.Medium);
                    var iconSize = AssistantComponentPropHelper.GetComponentSize(button.IconSize, Size.Medium);
                    var variant = button.GetButtonVariant();
                    var disabled = this.IsButtonActionRunning(button.Name);
                    var buttonClass = MergeClass(button.Class, "");
                    var style = GetOptionalStyle(button.Style);
                    
                    if (!button.IsIconButton)
                    {
                            <MudButton Variant="@variant"
                                       Color="@color"
                                       OnClick="@(() => this.ExecuteButtonActionAsync(button))"
                                       Size="@size"
                                       FullWidth="@button.IsFullWidth"
                                       StartIcon="@icon"
                                       EndIcon="@AssistantComponentPropHelper.GetIconSvg(button.EndIcon)"
                                       IconColor="@iconColor"
                                       IconSize="@iconSize"
                                       Disabled="@disabled"
                                       Class="@buttonClass"
                                       Style="@style">
                                @button.Text
                            </MudButton>
                    }
                    else
                    {
                        <MudIconButton Icon="@icon"
                                       Color="@color"
                                       Variant="@variant"
                                       Size="@size"
                                       OnClick="@(() => this.ExecuteButtonActionAsync(button))"
                                       Disabled="@disabled"
                                       Class="@buttonClass"
                                       Style="@style" />
                    }
                }
                break;
                
            case AssistantComponentType.BUTTON_GROUP:
                if (component is AssistantButtonGroup assistantButtonGroup)
                {
                    var buttonGroup = assistantButtonGroup;
                    <MudButtonGroup Variant="@buttonGroup.GetVariant()"
                                    Color="@AssistantComponentPropHelper.GetColor(buttonGroup.Color, Color.Default)"
                                    Size="@AssistantComponentPropHelper.GetComponentSize(buttonGroup.Size, Size.Medium)"
                                    OverrideStyles="@buttonGroup.OverrideStyles"
                                    Vertical="@buttonGroup.Vertical"
                                    DropShadow="@buttonGroup.DropShadow"
                                    Class='@MergeClass(buttonGroup.Class, "mb-3")'
                                    Style="@GetOptionalStyle(buttonGroup.Style)">
                        @this.RenderChildren(buttonGroup.Children)
                    </MudButtonGroup>
                }
                break;
                
            case AssistantComponentType.LAYOUT_GRID:
                if (component is AssistantGrid assistantGrid)
                {
                    var grid = assistantGrid;
                    <MudGrid Justify="@(AssistantComponentPropHelper.GetJustify(grid.Justify) ?? Justify.FlexStart)"
                             Spacing="@grid.Spacing"
                             Class="@grid.Class"
                             Style="@GetOptionalStyle(grid.Style)">
                        @this.RenderChildren(grid.Children)
                    </MudGrid>
                }
                break;
                
            case AssistantComponentType.LAYOUT_ITEM:
                if (component is AssistantItem assistantItem)
                {
                    @this.RenderLayoutItem(assistantItem)
                }
                break;
                
            case AssistantComponentType.LAYOUT_PAPER:
                if (component is AssistantPaper assistantPaper)
                {
                    var paper = assistantPaper;
                    <MudPaper Elevation="@paper.Elevation"
                              Outlined="@paper.IsOutlined"
                              Square="@paper.IsSquare"
                              Class="@paper.Class"
                              Style="@this.BuildPaperStyle(paper)">
                        @this.RenderChildren(paper.Children)
                    </MudPaper>
                }
                break;
                
            case AssistantComponentType.LAYOUT_STACK:
                if (component is AssistantStack assistantStack)
                {
                    var stack = assistantStack;
                    <MudStack Row="@stack.IsRow"
                              Reverse="@stack.IsReverse"
                              Breakpoint="@AssistantComponentPropHelper.GetBreakpoint(stack.Breakpoint, Breakpoint.None)"
                              AlignItems="@(AssistantComponentPropHelper.GetItemsAlignment(stack.Align) ?? AlignItems.Stretch)"
                              Justify="@(AssistantComponentPropHelper.GetJustify(stack.Justify) ?? Justify.FlexStart)"
                              StretchItems="@(AssistantComponentPropHelper.GetStretching(stack.Stretch) ?? StretchItems.None)"
                              Wrap="@(AssistantComponentPropHelper.GetWrap(stack.Wrap) ?? Wrap.Wrap)"
                              Spacing="@stack.Spacing"
                              Class="@stack.Class"
                              Style="@GetOptionalStyle(stack.Style)">
                        @this.RenderChildren(stack.Children)
                    </MudStack>
                }
                break;
                
            case AssistantComponentType.LAYOUT_ACCORDION:
                if (component is AssistantAccordion assistantAccordion)
                {
                    var accordion = assistantAccordion;
                    <MudExpansionPanels MultiExpansion="@accordion.AllowMultiSelection"
                                        Dense="@accordion.IsDense"
                                        Outlined="@accordion.HasOutline"
                                        Square="@accordion.IsSquare"
                                        Elevation="@accordion.Elevation"
                                        Gutters="@accordion.HasSectionPaddings"
                                        Class="@MergeClass(accordion.Class, "my-6")"
                                        Style="@GetOptionalStyle(accordion.Style)">
                        @this.RenderChildren(accordion.Children)
                    </MudExpansionPanels>
                }
                break;
                
            case AssistantComponentType.LAYOUT_ACCORDION_SECTION:
                if (component is AssistantAccordionSection assistantAccordionSection)
                {
                    var accordionSection = assistantAccordionSection;
                    var textColor = accordionSection.IsDisabled ? Color.Info : AssistantComponentPropHelper.GetColor(accordionSection.HeaderColor, Color.Inherit);
                    <MudExpansionPanel KeepContentAlive="@accordionSection.KeepContentAlive"
                                       disabled="@accordionSection.IsDisabled"
                                       Expanded="@accordionSection.IsExpanded"
                                       Dense="@accordionSection.IsDense"
                                       Gutters="@accordionSection.HasInnerPadding"
                                       HideIcon="@accordionSection.HideIcon"
                                       Icon="@AssistantComponentPropHelper.GetIconSvg(accordionSection.ExpandIcon)"
                                       MaxHeight="@accordionSection.MaxHeight"
                                       Class="@accordionSection.Class"
                                       Style="@GetOptionalStyle(accordionSection.Style)">
                        <TitleContent>
                            <div class="d-flex">
                                <MudIcon Icon="@AssistantComponentPropHelper.GetIconSvg(accordionSection.HeaderIcon)" class="mr-3"></MudIcon>
                                <MudText Align="@AssistantComponentPropHelper.GetAlignment(accordionSection.HeaderAlign)" 
                                         Color="@textColor"
                                         Typo="@AssistantComponentPropHelper.GetTypography(accordionSection.HeaderTypo)">
                                    @accordionSection.HeaderText
                                </MudText>
                            </div>
                        </TitleContent>
                        <ChildContent>
                            @this.RenderChildren(accordionSection.Children)
                        </ChildContent>
                    </MudExpansionPanel>
                }
            break;
                
            case AssistantComponentType.PROVIDER_SELECTION:
                if (component is AssistantProviderSelection providerSelection)
                {
                    <div class="@providerSelection.Class" style="@GetOptionalStyle(providerSelection.Style)">
                        <ProviderSelection @bind-ProviderSettings="@this.ProviderSettings" ValidateProvider="@this.ValidatingProvider" />
                    </div>
                }
                break;
                
            case AssistantComponentType.PROFILE_SELECTION:
                if (component is AssistantProfileSelection profileSelection)
                {
                    var selection = profileSelection;
                    <div class="@selection.Class" style="@GetOptionalStyle(selection.Style)">
                        <ProfileFormSelection Validation="@(profile => this.ValidateProfileSelection(selection, profile))" @bind-Profile="@this.CurrentProfile" />
                    </div>
                }
                break;
                
            case AssistantComponentType.SWITCH:
                if (component is AssistantSwitch switchComponent)
                {
                    var assistantSwitch = switchComponent;
                    
                    if (string.IsNullOrEmpty(assistantSwitch.Label))
                    {
                        @this.RenderSwitch(assistantSwitch)
                    }
                    else
                    {
                        <MudField Label="@assistantSwitch.Label" Variant="Variant.Outlined" Class="mb-3" Disabled="@assistantSwitch.Disabled">
                            @this.RenderSwitch(assistantSwitch)
                        </MudField> 
                    }
                }
                break;
                
            case AssistantComponentType.HEADING:
                if (component is AssistantHeading assistantHeading)
                {
                    var heading = assistantHeading;
                    var typo = heading.Level switch
                    {
                        1 => Typo.h4,
                        2 => Typo.h5,
                        3 => Typo.h6,
                        _ => Typo.h5
                    };

                    <MudText Typo="@typo" Class="@heading.Class" Style="@GetOptionalStyle(heading.Style)">@heading.Text</MudText>
                }
                break;
                
            case AssistantComponentType.TEXT:
                if (component is AssistantText assistantText)
                {
                    var text = assistantText;
                    <MudText Typo="Typo.body1" Class='@MergeClass(text.Class, "mb-3")' Style="@GetOptionalStyle(text.Style)">@text.Content</MudText>
                }
                break;
                
            case AssistantComponentType.LIST:
                if (component is AssistantList assistantList)
                {
                    var list = assistantList;
                    <MudList T="string" Class='@MergeClass(list.Class, "mb-6")' Style="@GetOptionalStyle(list.Style)">
                        @foreach (var item in list.Items)
                        {
                            var iconColor = AssistantComponentPropHelper.GetColor(item.IconColor, Color.Default);
                            
                            @if (item.Type == "LINK")
                            {
                                <MudListItem T="string" Icon="@Icons.Material.Filled.Link" IconColor="@iconColor" Target="_blank" Href="@item.Href">@item.Text</MudListItem>
                            }
                            else
                            {
                                var icon = !string.IsNullOrEmpty(item.Icon) ? AssistantComponentPropHelper.GetIconSvg(item.Icon) : string.Empty;
                                <MudListItem T="string" Icon="@icon" IconColor="@iconColor">@item.Text</MudListItem>
                            }
                        }
                    </MudList>
                }
                break;
                
            case AssistantComponentType.COLOR_PICKER:
                if (component is AssistantColorPicker assistantColorPicker)
                {
                    var colorPicker = assistantColorPicker;
                    var variant = colorPicker.GetPickerVariant();
                    var rounded = variant == PickerVariant.Static;

                    <MudItem Class="d-flex">
                        <MudColorPicker Text="@this.assistantState.Colors[colorPicker.Name]"
                                        TextChanged="@(value => this.assistantState.Colors[colorPicker.Name] = value)"
                                        Label="@colorPicker.Label"
                                        Placeholder="@colorPicker.Placeholder"
                                        ShowAlpha="@colorPicker.ShowAlpha"
                                        ShowToolbar="@colorPicker.ShowToolbar"
                                        ShowModeSwitch="@colorPicker.ShowModeSwitch"
                                        PickerVariant="@variant"
                                        Rounded="@rounded"
                                        Elevation="@colorPicker.Elevation"
                                        Style="@($"color: {this.assistantState.Colors[colorPicker.Name]};{colorPicker.Style}")"
                                        Class="@MergeClass(colorPicker.Class, "mb-3")" />
                    </MudItem>
                }
                break;
                
            case AssistantComponentType.DATE_PICKER:
                if (component is AssistantDatePicker assistantDatePicker)
                {
                    var datePicker = assistantDatePicker;
                    var format = datePicker.GetDateFormat();

                    <MudPaper Class="d-flex" Elevation="0">
                        <MudDatePicker Date="@datePicker.ParseValue(this.assistantState.Dates[datePicker.Name])"
                                       DateChanged="@(value => this.assistantState.Dates[datePicker.Name] = datePicker.FormatValue(value))"
                                       Label="@datePicker.Label"
                                       Color="@AssistantComponentPropHelper.GetColor(datePicker.Color, Color.Primary)"
                                       Placeholder="@datePicker.Placeholder"
                                       HelperText="@datePicker.HelperText"
                                       DateFormat="@format"
                                       Elevation="@datePicker.Elevation"
                                       PickerVariant="@AssistantComponentPropHelper.GetPickerVariant(datePicker.PickerVariant, PickerVariant.Static)"
                                       Variant="Variant.Outlined"
                                       Class='@MergeClass(datePicker.Class, "mb-3")'
                                       Style="@GetOptionalStyle(datePicker.Style)"
                                       />
                        </MudPaper>
                }
                break;
                
            case AssistantComponentType.DATE_RANGE_PICKER:
                if (component is AssistantDateRangePicker assistantDateRangePicker)
                {
                    var dateRangePicker = assistantDateRangePicker;
                    var format = dateRangePicker.GetDateFormat();

                    <MudPaper Class="d-flex" Elevation="0">
                        @* ReSharper disable CSharpWarnings::CS8619 *@
                        <MudDateRangePicker DateRange="@dateRangePicker.ParseValue(this.assistantState.DateRanges[dateRangePicker.Name])"
                                            DateRangeChanged="@(value => this.assistantState.DateRanges[dateRangePicker.Name] = dateRangePicker.FormatValue(value))"
                                            Label="@dateRangePicker.Label"
                                            Color="@AssistantComponentPropHelper.GetColor(dateRangePicker.Color, Color.Primary)"
                                            PlaceholderStart="@dateRangePicker.PlaceholderStart"
                                            PlaceholderEnd="@dateRangePicker.PlaceholderEnd"
                                            HelperText="@dateRangePicker.HelperText"
                                            DateFormat="@format"
                                            PickerVariant="@AssistantComponentPropHelper.GetPickerVariant(dateRangePicker.PickerVariant, PickerVariant.Static)"
                                            Elevation="@dateRangePicker.Elevation"
                                            Variant="Variant.Outlined"
                                            Class='@MergeClass(dateRangePicker.Class, "mb-3")'
                                            Style="@GetOptionalStyle(dateRangePicker.Style)"
                                            />
                                            @* ReSharper restore CSharpWarnings::CS8619 *@
                    </MudPaper>
                }
                break;
                
            case AssistantComponentType.TIME_PICKER:
                if (component is AssistantTimePicker assistantTimePicker)
                {
                    var timePicker = assistantTimePicker;
                    var format = timePicker.GetTimeFormat();

                    <MudPaper Class="d-flex" Elevation="0">
                        <MudTimePicker Time="@timePicker.ParseValue(this.assistantState.Times[timePicker.Name])"
                                       TimeChanged="@(value => this.assistantState.Times[timePicker.Name] = timePicker.FormatValue(value))"
                                       Label="@timePicker.Label"
                                       Color="@AssistantComponentPropHelper.GetColor(timePicker.Color, Color.Primary)"
                                       Placeholder="@timePicker.Placeholder"
                                       HelperText="@timePicker.HelperText"
                                       TimeFormat="@format"
                                       AmPm="@timePicker.AmPm"
                                       PickerVariant="@AssistantComponentPropHelper.GetPickerVariant(timePicker.PickerVariant, PickerVariant.Static)"
                                       Elevation="@timePicker.Elevation"
                                       Variant="Variant.Outlined"
                                       Class='@MergeClass(timePicker.Class, "mb-3")'
                                       Style="@GetOptionalStyle(timePicker.Style)"/>
                        </MudPaper>
                }
                break;
        }
    </text>;

    private string? BuildPaperStyle(AssistantPaper paper)
    {
        List<string> styles = [];

        this.AddStyle(styles, "height", paper.Height);
        this.AddStyle(styles, "max-height", paper.MaxHeight);
        this.AddStyle(styles, "min-height", paper.MinHeight);
        this.AddStyle(styles, "width", paper.Width);
        this.AddStyle(styles, "max-width", paper.MaxWidth);
        this.AddStyle(styles, "min-width", paper.MinWidth);

        var customStyle = paper.Style;
        if (!string.IsNullOrWhiteSpace(customStyle))
            styles.Add(customStyle.Trim().TrimEnd(';'));

        return styles.Count == 0 ? null : string.Join("; ", styles);
    }

    private RenderFragment RenderLayoutItem(AssistantItem item) => builder =>
    {
        builder.OpenComponent<MudItem>(0);

        if (item.Xs.HasValue)
            builder.AddAttribute(1, "xs", item.Xs.Value);

        if (item.Sm.HasValue)
            builder.AddAttribute(2, "sm", item.Sm.Value);

        if (item.Md.HasValue)
            builder.AddAttribute(3, "md", item.Md.Value);

        if (item.Lg.HasValue)
            builder.AddAttribute(4, "lg", item.Lg.Value);

        if (item.Xl.HasValue)
            builder.AddAttribute(5, "xl", item.Xl.Value);

        if (item.Xxl.HasValue)
            builder.AddAttribute(6, "xxl", item.Xxl.Value);

        var itemClass = item.Class;
        if (!string.IsNullOrWhiteSpace(itemClass))
            builder.AddAttribute(7, nameof(MudItem.Class), itemClass);

        var itemStyle = GetOptionalStyle(item.Style);
        if (!string.IsNullOrWhiteSpace(itemStyle))
            builder.AddAttribute(8, nameof(MudItem.Style), itemStyle);

        builder.AddAttribute(9, nameof(MudItem.ChildContent), this.RenderChildren(item.Children));
        builder.CloseComponent();
    };

    private void AddStyle(List<string> styles, string key, string value)
    {
        if (!string.IsNullOrWhiteSpace(value))
            styles.Add($"{key}: {value.Trim().TrimEnd(';')}");
    }
}
