<div class="relative">
  @if (compact()) {
    <div class="flex gap-1 rounded-lg border border-border bg-card p-2 shadow-lg">
      @for (entry of shortcuts(); track entry.key) {
        <button
          type="button"
          class="grid h-10 w-10 place-items-center rounded transition-colors hover:bg-secondary"
          [attr.aria-label]="entry.label"
          [title]="entry.label"
          (click)="selectShortcut(entry)"
        >
          @if (entry.kind === 'custom') {
            <img
              [src]="entry.emoji.dataUrl"
              [alt]="entry.emoji.name"
              class="h-10 w-10 object-contain"
            />
          } @else {
            <span class="text-[2rem] leading-none">{{ entry.emoji }}</span>
          }
        </button>
      }
      <button
        type="button"
        class="grid h-10 w-10 place-items-center rounded text-muted-foreground transition-colors hover:bg-secondary hover:text-foreground"
        aria-label="{{ 'emoji.picker.openAria' | translate }}"
        title="{{ 'emoji.picker.openAria' | translate }}"
        (click)="openModal()"
      >
        <ng-icon
          name="lucideSmile"
          class="h-5 w-5"
        />
      </button>
    </div>
  }

  @if (!compact() || modalOpen()) {
    <div
      class="rounded-lg border border-border bg-card p-3 shadow-xl"
      [class.absolute]="!inline()"
      [class.bottom-full]="!inline()"
      [class.right-0]="!inline()"
      [class.z-20]="!inline()"
      [class.mb-2]="!inline()"
      [class.w-72]="!inline()"
      [class.w-full]="inline()"
    >
      @if (!inline()) {
        <div class="mb-2 flex items-center justify-between gap-2">
          <p class="text-sm font-semibold text-foreground">{{ 'emoji.picker.title' | translate }}</p>
          @if (compact()) {
            <button
              type="button"
              class="grid h-7 w-7 place-items-center rounded hover:bg-secondary"
              aria-label="Close emoji selector"
              (click)="closeModal()"
            >
              <ng-icon
                name="lucideX"
                class="h-4 w-4 text-muted-foreground"
              />
            </button>
          }
        </div>
      }

      <label class="relative mb-3 block">
        <ng-icon
          name="lucideSearch"
          class="pointer-events-none absolute left-2.5 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground"
        />
        <input
          type="search"
          appAutoFocus
          appSelectOnFocus
          class="w-full rounded-md border border-border bg-background py-2 pl-8 pr-3 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary"
          placeholder="{{ 'emoji.picker.searchPlaceholder' | translate }}"
          aria-label="{{ 'emoji.picker.searchAria' | translate }}"
          [value]="searchQuery()"
          (input)="onSearchInput($event)"
        />
      </label>

      <label
        class="mb-3 flex cursor-pointer items-center justify-center gap-2 rounded-md border border-dashed border-border px-3 py-2 text-xs font-medium text-muted-foreground transition-colors hover:border-primary/50 hover:text-foreground"
      >
        <ng-icon
          name="lucideUpload"
          class="h-4 w-4"
        />
        <span>{{ uploading() ? ('emoji.picker.uploading' | translate) : ('emoji.picker.upload' | translate) }}</span>
        <input
          type="file"
          class="hidden"
          [accept]="acceptAttribute"
          [disabled]="uploading()"
          (change)="uploadEmoji($event)"
        />
      </label>

      @if (uploadError()) {
        <div class="mb-3 rounded-md border border-destructive/30 bg-destructive/10 px-2 py-1.5 text-xs text-destructive">
          {{ uploadError() }}
        </div>
      }

      @if (showEmptySearchState()) {
        <div class="mb-3 rounded-md border border-border/70 bg-secondary/20 px-3 py-4 text-center text-xs text-muted-foreground">
          {{ 'emoji.picker.emptySearch' | translate }}
        </div>
      }

      @if (filteredUnicodeEntries().length > 0) {
        <div class="mb-3 grid grid-cols-6 gap-1">
          @for (entry of filteredUnicodeEntries(); track entry.emoji) {
            <button
              type="button"
              class="grid h-10 w-10 place-items-center rounded transition-colors hover:bg-secondary"
              (click)="selectUnicode(entry.emoji)"
            >
              <span class="text-[2rem] leading-none">{{ entry.emoji }}</span>
            </button>
          }
        </div>
      }

      @if (filteredCustomEmojis().length > 0) {
        <div class="grid max-h-44 grid-cols-6 gap-1 overflow-y-auto pr-1">
          @for (emoji of filteredCustomEmojis(); track emoji.id) {
            <button
              type="button"
              class="grid h-10 w-10 place-items-center rounded transition-colors hover:bg-secondary"
              [title]="emoji.name"
              data-custom-emoji-library
              [attr.data-custom-emoji-id]="emoji.id"
              (click)="selectCustom(emoji)"
            >
              <img
                [src]="emoji.dataUrl"
                [alt]="emoji.name"
                class="h-10 w-10 object-contain"
              />
            </button>
          }
        </div>
      }
    </div>
  }
</div>
