<UserControl xmlns="https://github.com/avaloniaui"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:vm="using:DodoSSH.Client.Shell.ViewModels"
             x:Class="DodoSSH.Client.App.Views.SnippetsScreen"
             x:DataType="vm:SnippetsViewModel">

  <!--
    Commands somebody has saved, and how to get one into a terminal.

    The list and the writing belong to the vault, as every other item kind's do; this screen is the filter,
    the editor and the insert over the top. See SnippetsViewModel.

    The two buttons at the bottom right of the detail pane are the whole safety design, and their wording is
    load-bearing. A terminal is one input stream with no notion of being at a prompt — the remote may be
    inside vi, or at a sudo password prompt with echo off — so this application cannot say "run this
    command", only "type this into whatever is there". RUN appears solely for a snippet whose own flag says
    it runs, which makes that a decision taken once while writing it rather than a button beside every one
    of them.

    ── v5b — Snippets.dc.html ──────────────────────────────────────────────────────────────────────────────
    A fidelity pass, not a new shape. What moved:

    ◆ THE SCREEN'S OWN TITLE. The design renames this screen "Snips" — adopted here on screen, matching the
    nav rail, which already says Snips (see NavRail.axaml's own remark on the mock's wording for this
    destination).

    ◆ THE HEADER. "Snips" 33 bold, a count chip, the existing filter box restyled to 280px, and a
    "+ New snip" accent button in place of the old ghost "+ NEW SNIPPET" — same NewCommand.

    ◆ THE LIST. Card rows rather than a flat list — radius 10, Track fill and an accent ring on the selected
    one, Track on hover — with a { } glyph, the mono name, the "runs immediately" chip (real: it is
    RunsOnInsert, already tracked per snippet), the vault chip, and the mono command preview beneath. No
    modified date: SnippetSecret carries none, and neither does any other item kind — VaultItem is (id,
    secret, version, three sync flags) and nothing else; see docs/design-import-gaps.md. The bottom action
    row keeps EDIT / MOVE TO VAULT… / DELETE, restyled and DELETE now danger-coloured to match.

    ◆ THE DETAIL/EDITOR SIDEBAR, widened to 340px per the design. Two modes exist as they always have — the
    editor while IsEditing, the selected snippet's own facts and its insert controls otherwise — because the
    two are genuinely different forms doing different things, not a cosmetic split; merging them would let
    somebody fixing a typo re-file a snippet by leaving a vault picker where they found it. VAULT draws a
    lock glyph beside the vault name, per the design. "Runs on insert"/"runs immediately" keeps this screen's
    own longer caption rather than the design's shorter one — it states the operational consequence
    ("typed at the prompt and waits for you") where the design's states only the rationale for having the
    setting once; both are true, the existing one is more actionable. The insert button keeps its own dynamic
    label — "TYPE INTO {tab}" or "NO TERMINAL OPEN" — over the design's static "Type into terminal", because
    naming the destination tab is a fact the design's caption does not carry and this screen already had.
    Its own caption similarly stays: it names vi and a sudo prompt with echo off as the two ways "at a
    prompt" can be wrong, which is more than the design's own sentence says.

    ◆ THE DELETE CONFIRMATION. Snippets.dc.html's own modal — vault-wide reach, a tombstone, no undo — is
    exactly what VaultViewModel.HowFarADeletionGoes already says for every other kind of item, so
    SnippetsViewModel.RequestDelete/ConfirmDelete/CancelDelete say it in the same words. Additive next to the
    existing uncounted DeleteCommand rather than a change to it — that command is what the phone's own DELETE
    row still calls, with no confirmation card on that screen to answer one; see SnippetsViewModel's own
    remarks on both commands.
  -->

  <UserControl.Styles>
    <!--
      A card, not a full-bleed row: Track fill on hover, Track fill plus an accent ring on the selected one,
      matching the design's own "selected = Track bg + accent ring, hover Track" — distinct from
      ListBox.filerows, which draws no ring, because a snippet card is chosen for one editor at a time rather
      than opened directly.
    -->
    <Style Selector="ListBox.snipcards > ListBoxItem /template/ ContentPresenter#PART_ContentPresenter">
      <Setter Property="CornerRadius" Value="10" />
      <Setter Property="BorderThickness" Value="1" />
      <Setter Property="BorderBrush" Value="Transparent" />
    </Style>
    <Style Selector="ListBox.snipcards > ListBoxItem:pointerover /template/ ContentPresenter#PART_ContentPresenter">
      <Setter Property="Background" Value="{StaticResource Track}" />
    </Style>
    <Style Selector="ListBox.snipcards > ListBoxItem:selected /template/ ContentPresenter#PART_ContentPresenter">
      <Setter Property="Background" Value="{StaticResource Track}" />
      <Setter Property="BorderBrush" Value="{StaticResource Accent}" />
    </Style>
    <Style Selector="ListBox.snipcards > ListBoxItem:selected:pointerover /template/ ContentPresenter#PART_ContentPresenter">
      <Setter Property="Background" Value="{StaticResource Track}" />
      <Setter Property="BorderBrush" Value="{StaticResource Accent}" />
    </Style>
  </UserControl.Styles>

  <Grid RowDefinitions="Auto,*" Margin="26">

    <!-- ============ THE HEADER ============ -->
    <Grid Grid.Row="0" Margin="0,0,0,20" ColumnDefinitions="Auto,Auto,*,Auto,Auto">

      <TextBlock Grid.Column="0" Text="Snips" FontSize="33" FontWeight="Bold" LetterSpacing="-0.5"
                 Foreground="{StaticResource Text}" VerticalAlignment="Center" />

      <Border Grid.Column="1" Margin="12,0,0,0" MinWidth="34" Height="30" CornerRadius="9" Padding="8,0"
              Background="{StaticResource Chip}" VerticalAlignment="Center">
        <TextBlock Classes="mono" Text="{Binding Visible.Count}" FontSize="12.5"
                   Foreground="{StaticResource TextDim}" HorizontalAlignment="Center"
                   VerticalAlignment="Center" />
      </Border>

      <!--
        The command is searched as well as the name: half of what anybody remembers about a saved command is
        a word that was inside it.
      -->
      <TextBox Grid.Column="3" x:Name="SnippetFilter" Text="{Binding Filter}" Width="280" Height="40"
               CornerRadius="10" Margin="0,0,10,0"
               PlaceholderText="filter by name or command" VerticalAlignment="Center" />

      <Button Grid.Column="4" Classes="accent" Height="40" FontSize="13.5" Content="+ New snip"
              Command="{Binding NewCommand}" />

    </Grid>

    <!-- ============ THE BORDERED BODY ============ -->
    <Border Grid.Row="1" BorderBrush="{StaticResource Border}" BorderThickness="1" CornerRadius="12"
            ClipToBounds="True">
      <Grid ColumnDefinitions="*,340">

        <Grid Grid.Column="0" RowDefinitions="*,Auto" Background="{StaticResource Pane}">

          <ListBox Grid.Row="0" x:Name="SnippetList" Classes="snipcards" Focusable="True"
                   ItemsSource="{Binding Visible}"
                   SelectedItem="{Binding Selected}"
                   Margin="10,10,10,4">
            <ListBox.ItemTemplate>
              <DataTemplate x:DataType="vm:SnippetRowViewModel">
                <StackPanel Margin="6,7" Spacing="6">
                  <StackPanel Orientation="Horizontal" Spacing="8">
                    <TextBlock Classes="mono" Text="{}{ }" FontSize="11" FontWeight="Bold"
                               Foreground="{StaticResource AccentText}" VerticalAlignment="Center" />
                    <TextBlock Classes="mono" Text="{Binding Label}" FontSize="13" FontWeight="Medium"
                               Foreground="{StaticResource Text}" VerticalAlignment="Center"
                               TextTrimming="CharacterEllipsis" />
                    <!--
                      The flag, where the decision is made. A snippet that presses Enter for you is not the
                      same kind of thing as one that does not, and the list is where somebody chooses between
                      them.
                    -->
                    <Border Classes="chip warn" Padding="7,0" Height="18" VerticalAlignment="Center"
                            IsVisible="{Binding RunsOnInsert}">
                      <TextBlock Text="runs immediately" FontSize="9.5" />
                    </Border>
                    <Border Classes="chip warn" Padding="7,0" Height="18" VerticalAlignment="Center"
                            IsVisible="{Binding Badge, Converter={x:Static StringConverters.IsNotNullOrEmpty}}">
                      <TextBlock Text="{Binding Badge}" FontSize="9.5" />
                    </Border>
                    <!--
                      Which vault this one is in, drawn only where there is more than one to be in. A shared
                      snippet is a command the rest of a team can read and insert; the row is where somebody
                      decides whether the thing they are about to edit is theirs alone.
                    -->
                    <Border Classes="chip" Padding="7,0" Height="18" VerticalAlignment="Center"
                            IsVisible="{Binding HasVaultBadge}">
                      <TextBlock Text="{Binding VaultBadge}" FontSize="9.5" />
                    </Border>
                  </StackPanel>
                  <!--
                    Newlines shown as ⏎ rather than dropped. A three-line snippet flattened into one run of
                    text reads as a single command, which is the thing being decided about on this row.
                  -->
                  <TextBlock Classes="mono" Text="{Binding Preview}" FontSize="11.5"
                             Foreground="{StaticResource TextFaint}" TextTrimming="CharacterEllipsis" />
                </StackPanel>
              </DataTemplate>
            </ListBox.ItemTemplate>
          </ListBox>

          <TextBlock Grid.Row="0" Classes="hint" Text="{Binding EmptyMessage}" FontSize="12"
                     Margin="24" HorizontalAlignment="Center" VerticalAlignment="Center"
                     TextAlignment="Center" MaxWidth="360"
                     IsVisible="{Binding !HasVisible}" />

          <Border Grid.Row="1" Padding="16,10" BorderBrush="{StaticResource BorderSubtle}"
                  BorderThickness="0,1,0,0">
            <StackPanel Orientation="Horizontal" Spacing="8">
              <Button Classes="ghost" Content="Edit" Command="{Binding EditCommand}"
                      IsEnabled="{Binding HasSelection}" />
              <!--
                Sharing a snippet, which is what moving one into a team's vault is. Beside EDIT rather than
                inside it: the two vaults are encrypted under different keys, so this is a re-seal into one
                and a tombstone in the other — nothing a SAVE could do — and a picker inside the form would
                let somebody correcting a typo hand a command to a team by leaving it where they found it.
                The picker itself opens beside the snippet, in the pane on the right.
              -->
              <Button Classes="ghost" Content="Move to vault…" Command="{Binding MoveCommand}"
                      IsEnabled="{Binding CanMove}"
                      ToolTip.Tip="Re-encrypts this snippet with another vault's key. Everybody who holds that key can then read and insert it." />
              <Button Classes="danger" Content="Delete" Command="{Binding RequestDeleteCommand}"
                      IsEnabled="{Binding HasSelection}" />
            </StackPanel>
          </Border>

        </Grid>

        <Border Grid.Column="1" Background="{StaticResource Sidebar}"
                BorderBrush="{StaticResource Border}" BorderThickness="1,0,0,0">
          <ScrollViewer>
            <StackPanel Margin="18,20" Spacing="10">

              <!-- ============ The editor ============ -->
              <StackPanel Spacing="8" IsVisible="{Binding IsEditing}">
                <TextBlock Classes="label" Text="NAME" FontSize="10" />
                <TextBox Text="{Binding EditorLabel}" PlaceholderText="name" FontFamily="{StaticResource MonoFont}" />

                <!--
                  Which vault a *new* snippet is filed into, asked on the form it is being typed into rather
                  than through a standing preference elsewhere. Not drawn for an existing snippet — its vault
                  is not a field of this form, and changing it is MOVE — and not drawn at all where there is
                  only one vault to choose between, because a control offering one option is a question
                  nobody asked.
                -->
                <StackPanel Spacing="4" IsVisible="{Binding ShowsEditorVaultChoice}">
                  <TextBlock Classes="label" Text="VAULT" FontSize="10" />
                  <ComboBox HorizontalAlignment="Stretch" ItemsSource="{Binding EditorVaultChoices}"
                            SelectedItem="{Binding EditorSelectedVault}">
                    <ComboBox.ItemTemplate>
                      <DataTemplate x:DataType="vm:VaultChoiceViewModel">
                        <TextBlock Text="{Binding Display}" FontSize="12" />
                      </DataTemplate>
                    </ComboBox.ItemTemplate>
                  </ComboBox>
                  <TextBlock Classes="hint" FontSize="10.5" TextWrapping="Wrap"
                             Text="A shared vault means everybody holding its key can read this command and insert it into their own terminals." />
                </StackPanel>

                <TextBlock Classes="label" Text="COMMAND" FontSize="10" />
                <!--
                  Stored exactly as typed — no trimming, no newline normalisation. A here-document's
                  terminator has to arrive on a line of its own, and tidying the trailing newline off it
                  leaves the shell waiting for one that never comes.
                -->
                <TextBox Text="{Binding EditorCommand}" PlaceholderText="the command" AcceptsReturn="True"
                         Height="140" TextWrapping="NoWrap" FontFamily="{StaticResource MonoFont}"
                         FontSize="12" />
                <TextBox Text="{Binding EditorNotes}" PlaceholderText="notes" AcceptsReturn="True"
                         Height="48" TextWrapping="Wrap" />

                <Grid ColumnDefinitions="*,Auto" Margin="0,4,0,0">
                  <StackPanel Grid.Column="0" Spacing="3">
                    <TextBlock Text="Runs on insert" FontSize="12.5" FontWeight="SemiBold"
                               Foreground="{StaticResource TextDim}" />
                    <TextBlock Classes="hint" FontSize="10.5" TextWrapping="Wrap"
                               Text="Off means the command is typed at the prompt and waits for you. That single Enter is the only thing standing between a saved command and a running one, so leave it off unless you meant it." />
                  </StackPanel>
                  <CheckBox Grid.Column="1" IsChecked="{Binding EditorRunsOnInsert}"
                            VerticalAlignment="Top" Margin="10,0,0,0" />
                </Grid>

                <StackPanel Orientation="Horizontal" Spacing="6" Margin="0,6,0,0">
                  <Button Classes="accent" Content="Save" Command="{Binding SaveCommand}" />
                  <Button Classes="ghost" Content="Cancel" Command="{Binding CancelCommand}" />
                </StackPanel>
              </StackPanel>

              <!-- ============ The selected snippet ============ -->
              <StackPanel Spacing="10" IsVisible="{Binding !IsEditing}">

                <TextBlock Classes="hint" FontSize="12"
                           Text="Choose a snippet to see it in full and put it into a terminal."
                           IsVisible="{Binding !HasSelection}" />

                <StackPanel Spacing="10" IsVisible="{Binding HasSelection}">
                  <TextBlock Classes="mono" Text="{Binding Selected.Label}" FontSize="15"
                             FontWeight="Bold" Foreground="{StaticResource Text}" TextWrapping="Wrap" />

                  <TextBlock Classes="label" Text="COMMAND" FontSize="10" />
                  <Border CornerRadius="10" Background="{StaticResource Pane}"
                          BorderBrush="{StaticResource BorderMid}" BorderThickness="1" Padding="12">
                    <SelectableTextBlock Classes="mono" Text="{Binding Selected.Snippet.Command}"
                                         FontSize="11.5" LineHeight="19"
                                         Foreground="{StaticResource TextFaint}" TextWrapping="Wrap" />
                  </Border>

                  <TextBlock Classes="mono" Text="{Binding Selected.Snippet.Notes}" FontSize="11"
                             Foreground="{StaticResource TextFaint}" TextWrapping="Wrap"
                             IsVisible="{Binding Selected.Snippet.Notes, Converter={x:Static StringConverters.IsNotNullOrEmpty}}" />

                  <!--
                    VAULT, with the design's own lock glyph. Named here as well as on the row, because this
                    pane is where somebody decides to put a command into a production terminal, and who else
                    holds a key to it is part of that decision.
                  -->
                  <StackPanel Spacing="4" IsVisible="{Binding HasSelectionVaultBadge}">
                    <TextBlock Classes="label" Text="VAULT" FontSize="10" />
                    <Border Height="38" CornerRadius="10" Background="{StaticResource Pane}"
                            BorderBrush="{StaticResource BorderMid}" BorderThickness="1" Padding="12,0">
                      <Grid ColumnDefinitions="*,Auto">
                        <TextBlock Grid.Column="0" Classes="mono" Text="{Binding SelectionVaultBadge}"
                                   FontSize="11.5" Foreground="{StaticResource TextDim}"
                                   VerticalAlignment="Center" />
                        <TextBlock Grid.Column="1" FontFamily="{StaticResource IconFont}" Text="&#xE897;"
                                   FontSize="14" Foreground="{StaticResource TextFaint}"
                                   VerticalAlignment="Center" />
                      </Grid>
                    </Border>
                  </StackPanel>

                  <!--
                    The button names the tab it will type into, over the design's static "Type into
                    terminal" — see the file-level remark above for why the dynamic label is the truer one.
                  -->
                  <StackPanel Spacing="6" IsVisible="{Binding ShowsSelectionActions}">
                    <Button Classes="accent" Content="{Binding InsertLabel}" HorizontalAlignment="Stretch"
                            HorizontalContentAlignment="Center"
                            Command="{Binding InsertCommand}" IsEnabled="{Binding CanInsert}"
                            ToolTip.Tip="Types the command at the prompt and stops. Nothing runs until you press Enter there." />

                    <Button Classes="danger" Content="{Binding RunLabel}" HorizontalAlignment="Stretch"
                            HorizontalContentAlignment="Center"
                            Command="{Binding RunCommand}"
                            IsVisible="{Binding SelectionRuns}" IsEnabled="{Binding CanInsert}"
                            ToolTip.Tip="Types the command and presses Enter. Offered because this snippet is marked as one that runs." />

                    <TextBlock Classes="hint" FontSize="10.5" TextWrapping="Wrap" TextAlignment="Center"
                               Text="Whatever is in the terminal receives this. Nothing here can tell whether that is a shell prompt, an editor, or a password prompt with the echo off — so check the tab before you insert." />
                  </StackPanel>

                  <!--
                    ◆ SHARING THE SNIPPET, which is what moving it into a team's vault amounts to. A picker
                    and two buttons, not a question with a yes.
                  -->
                  <StackPanel Spacing="8" IsVisible="{Binding IsMoving}">
                    <TextBlock Classes="label" Text="MOVE TO VAULT" FontSize="10" />
                    <ComboBox HorizontalAlignment="Stretch" ItemsSource="{Binding MoveVaultChoices}"
                              SelectedItem="{Binding SelectedMoveVault}">
                      <ComboBox.ItemTemplate>
                        <DataTemplate x:DataType="vm:VaultChoiceViewModel">
                          <TextBlock Text="{Binding Display}" FontSize="12" />
                        </DataTemplate>
                      </ComboBox.ItemTemplate>
                    </ComboBox>
                    <TextBlock Classes="hint" FontSize="10.5" TextWrapping="Wrap"
                               Text="The snippet is re-encrypted with the other vault's key, so everybody who holds that key can read this command and insert it — and nobody else can. Nothing else about it changes." />
                    <StackPanel Orientation="Horizontal" Spacing="6">
                      <Button Classes="accent" Content="Move" Command="{Binding ConfirmMoveCommand}" />
                      <Button Classes="ghost" Content="Cancel" Command="{Binding CancelMoveCommand}" />
                    </StackPanel>
                  </StackPanel>

                  <!--
                    ◆ THE DELETE CONFIRMATION. See RequestDelete's own remarks for why this is additive
                    beside DeleteCommand rather than a change to it.
                  -->
                  <Border Background="{StaticResource DangerWash}" BorderBrush="{StaticResource DangerSoft}"
                          BorderThickness="1" CornerRadius="10" Padding="12"
                          IsVisible="{Binding IsConfirmingDelete}">
                    <StackPanel Spacing="8">
                      <TextBlock Classes="heading" FontSize="14" TextWrapping="Wrap"
                                 Text="{Binding DeleteQuestion}" />
                      <TextBlock Foreground="{StaticResource WarnText}" FontSize="12" TextWrapping="Wrap"
                                 Text="{Binding DeleteConsequence}" />
                      <StackPanel Orientation="Horizontal" Spacing="6">
                        <Button Classes="danger" Content="Delete snippet"
                                Command="{Binding ConfirmDeleteCommand}" />
                        <Button Classes="ghost" Content="Cancel" Command="{Binding CancelDeleteCommand}" />
                      </StackPanel>
                    </StackPanel>
                  </Border>
                </StackPanel>
              </StackPanel>

            </StackPanel>
          </ScrollViewer>
        </Border>

      </Grid>
    </Border>

  </Grid>

</UserControl>
