@if (isMobile()) {
  <swiper-container
    class="block h-full min-h-0 w-full"
    direction="vertical"
    slides-per-view="1"
    space-between="0"
    initial-slide="1"
    threshold="10"
    resistance-ratio="0"
    (swiperslidechange)="onMobileCallSlideChange($event)"
  >
    <swiper-slide class="block h-full w-full" />
    <swiper-slide class="block h-full w-full">
      <ng-container *ngTemplateOutlet="privateCallSurface" />
    </swiper-slide>
  </swiper-container>
} @else {
  <ng-container *ngTemplateOutlet="privateCallSurface" />
}

<ng-template #privateCallSurface>
  <section
    class="grid h-full min-h-0 bg-background lg:grid-cols-[minmax(0,1fr)_var(--private-call-chat-width)]"
    [style.--private-call-chat-width]="chatWidthPx() + 'px'"
  >
    <main class="flex min-h-0 min-w-0 flex-col overflow-hidden bg-[radial-gradient(circle_at_top,rgba(16,185,129,0.10),transparent_34rem)]">
      <header class="flex min-h-16 shrink-0 items-center justify-between gap-3 border-b border-border/70 bg-background/80 px-3 backdrop-blur sm:px-5">
        <div class="flex min-w-0 items-center gap-3">
          <div class="grid h-10 w-10 shrink-0 place-items-center rounded-2xl bg-emerald-500/10 text-emerald-500">
            <ng-icon
              name="lucidePhone"
              class="h-5 w-5"
            />
          </div>

          <div class="min-w-0">
            <h1 class="truncate text-base font-semibold text-foreground">{{ 'call.private.title' | translate }}</h1>
            <p class="truncate text-xs text-muted-foreground">
              @if (session()) {
                {{ 'call.private.participants' | translate: { count: participantUsers().length } }}
              } @else {
                {{ 'call.private.notFound' | translate }}
              }
            </p>
          </div>
        </div>

        @if (session()) {
          <div class="flex items-center gap-2">
            @if (isMobile()) {
              <button
                type="button"
                class="grid h-10 w-10 place-items-center rounded-full bg-secondary text-foreground transition-colors hover:bg-secondary/80"
                (click)="minimizeCall()"
                [attr.aria-label]="'call.private.minimize' | translate"
                [title]="'call.private.minimize' | translate"
              >
                <ng-icon
                  name="lucideX"
                  class="h-5 w-5"
                />
              </button>
            }
            <select
              class="hidden h-9 max-w-44 rounded-md border border-border bg-secondary px-2 text-sm text-foreground sm:block"
              [ngModel]="inviteUserId()"
              (ngModelChange)="inviteUserId.set($event)"
              [attr.aria-label]="'call.private.addUserAria' | translate"
            >
              <option value="">{{ 'call.private.addUser' | translate }}</option>
              @for (user of inviteCandidates(); track userKey(user)) {
                <option [value]="userKey(user)">{{ user.displayName }}</option>
              }
            </select>
            <button
              type="button"
              class="hidden h-9 w-9 place-items-center rounded-md bg-secondary text-foreground transition-colors hover:bg-secondary/80 disabled:opacity-50 sm:grid"
              [disabled]="!inviteUserId()"
              (click)="inviteSelectedUser()"
              [attr.aria-label]="'call.private.addUserButton' | translate"
              [title]="'call.private.addUserButton' | translate"
            >
              <ng-icon
                name="lucideUserPlus"
                class="h-4 w-4"
              />
            </button>
          </div>
        }
      </header>

      @if (session()) {
        <div class="flex min-h-0 flex-1 flex-col overflow-hidden px-3 py-3 sm:px-5 sm:py-4">
          <div class="relative min-h-0 flex-1 overflow-hidden">
            @if (activeShares().length > 0) {
              @if (focusedShare()) {
                @if (hasMultipleShares()) {
                  <div class="absolute right-3 top-3 z-10 sm:right-4 sm:top-4">
                    <button
                      type="button"
                      data-testid="private-call-show-all-streams"
                      class="inline-flex h-10 items-center gap-2 rounded-full border border-white/10 bg-black/45 px-3 text-xs font-medium text-white/80 backdrop-blur transition hover:bg-black/65 hover:text-white"
                      [title]="'call.private.showAllStreams' | translate"
                      (click)="showAllStreams()"
                    >
                      <ng-icon
                        name="lucideUsers"
                        class="h-3.5 w-3.5"
                      />
                      {{ 'call.private.allStreams' | translate }}
                    </button>
                  </div>
                }

                <app-voice-workspace-stream-tile
                  [item]="focusedShare()!"
                  [featured]="true"
                  [focused]="true"
                  data-testid="private-call-focused-stream"
                  [immersive]="true"
                  (focusRequested)="focusShare($event)"
                />
              } @else if (hasMultipleShares()) {
                <div
                  class="grid h-full min-h-0 auto-rows-[minmax(12rem,1fr)] grid-cols-1 gap-3 p-3 sm:grid-cols-2 sm:gap-4 sm:p-4"
                  [ngClass]="{ '2xl:grid-cols-3': activeShares().length > 2 }"
                  data-testid="private-call-stream-grid"
                >
                  @for (share of activeShares(); track share.id) {
                    <div class="min-h-0 overflow-hidden rounded-2xl bg-black">
                      <app-voice-workspace-stream-tile
                        [item]="share"
                        [focused]="false"
                        (focusRequested)="focusShare($event)"
                      />
                    </div>
                  }
                </div>
              }
            } @else {
              <div class="flex h-full min-h-0 items-center justify-center p-1 sm:p-5">
                <div
                  class="grid w-full max-w-7xl grid-cols-[repeat(auto-fit,minmax(min(11rem,100%),1fr))] items-stretch justify-center gap-3 sm:grid-cols-[repeat(auto-fit,minmax(min(16rem,100%),1fr))] sm:gap-5 lg:gap-7"
                >
                  @for (user of participantUsers(); track trackUserKey($index, user)) {
                    <app-private-call-participant-card
                      [user]="user"
                      [connected]="isParticipantConnected(user)"
                      [speaking]="isSpeaking(user)"
                      [issueLabel]="participantIssueLabel(user)"
                      [passive]="isPassiveCallParticipant(user)"
                    />
                  }
                </div>
              </div>
            }
          </div>

          @if (activeShares().length > 0) {
            <div class="shrink-0 pt-4">
              <div class="flex w-full items-stretch gap-3 overflow-x-auto pb-1">
                @for (user of participantUsers(); track trackUserKey($index, user)) {
                  <app-private-call-participant-card
                    [user]="user"
                    [connected]="isParticipantConnected(user)"
                    [speaking]="isSpeaking(user)"
                    [issueLabel]="participantIssueLabel(user)"
                    [passive]="isPassiveCallParticipant(user)"
                    [compact]="true"
                  />
                }

                @if (hasMultipleShares()) {
                  @for (share of focusedShare() ? thumbnailShares() : activeShares(); track share.id) {
                    <article
                      class="flex min-h-[8.75rem] w-[11rem] shrink-0 flex-col overflow-hidden rounded-2xl border border-border/80 bg-black shadow-sm sm:w-[12.5rem]"
                    >
                      <div class="min-h-0 flex-1">
                        <app-voice-workspace-stream-tile
                          [item]="share"
                          [mini]="true"
                          [focused]="false"
                          (focusRequested)="focusShare($event)"
                        />
                      </div>
                      <div class="shrink-0 bg-black/80 px-3 py-2 text-xs font-semibold text-white/75">
                        {{ streamLabel(share) }}
                      </div>
                    </article>
                  }
                }
              </div>
            </div>
          }

          <div class="shrink-0 pt-3">
            <app-private-call-controls
              class="mx-auto block w-full max-w-5xl"
              [connected]="isConnected()"
              [muted]="isMuted()"
              [deafened]="isDeafened()"
              [cameraEnabled]="isCameraEnabled()"
              [screenSharing]="isScreenSharing()"
              [showSpeakerphoneButton]="showSpeakerphoneButton()"
              [speakerphoneEnabled]="speakerphoneEnabled()"
              (joinRequested)="join()"
              (muteToggled)="toggleMute()"
              (deafenToggled)="toggleDeafen()"
              (cameraToggled)="toggleCamera()"
              (screenShareToggled)="toggleScreenShare()"
              (speakerphoneToggled)="toggleSpeakerphone()"
              (leaveRequested)="leave()"
            />
          </div>
        </div>
      } @else {
        <div class="flex flex-1 items-center justify-center px-6 text-sm text-muted-foreground">{{ 'call.private.noActiveCall' | translate }}</div>
      }
    </main>

    <aside class="relative hidden min-h-0 border-l border-border bg-card lg:block">
      <div
        class="group absolute inset-y-0 left-0 z-10 w-3 -translate-x-1/2 cursor-col-resize bg-transparent"
        role="separator"
        aria-orientation="vertical"
        [title]="'call.private.resizeChat' | translate"
        data-testid="private-call-chat-resizer"
        (mousedown)="startChatResize($event)"
      >
        <div class="mx-auto h-full w-px bg-border transition group-hover:bg-primary"></div>
      </div>
      <app-dm-chat
        [conversationId]="session()?.conversationId ?? null"
        [showCallButton]="false"
      />
    </aside>
  </section>
</ng-template>

@if (showScreenShareQualityDialog()) {
  <app-screen-share-quality-dialog
    [selectedQuality]="screenShareQuality()"
    [includeSystemAudio]="includeSystemAudio()"
    (cancelled)="onScreenShareQualityCancelled()"
    (confirmed)="onScreenShareQualityConfirmed($event)"
  />
}
