<div class="flex h-full min-h-0 flex-col">
  <div class="border-b border-border px-3 py-3">
    <div class="flex flex-col gap-2 md:flex-row md:items-center">
      <div class="relative min-w-0 flex-1">
        <ng-icon
          name="lucideSearch"
          class="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground"
        />
        <input
          type="text"
          aria-label="Search people and servers"
          class="h-10 w-full rounded-lg border border-border bg-secondary py-2 pl-10 pr-3 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary"
          placeholder="Search servers and users..."
          [(ngModel)]="searchQuery"
          (ngModelChange)="onSearchChange($event)"
        />
      </div>

      <div class="flex shrink-0 items-center gap-2">
        <button
          type="button"
          aria-label="Create New Server"
          class="inline-flex h-10 items-center justify-center gap-2 rounded-lg bg-primary px-3 text-sm font-semibold text-primary-foreground transition-colors hover:bg-primary/90"
          (click)="openCreateDialog()"
        >
          <ng-icon
            name="lucidePlus"
            class="h-4 w-4"
          />
          Create
        </button>

        <button
          type="button"
          class="grid h-10 w-10 place-items-center rounded-lg border border-border bg-secondary transition-colors hover:bg-secondary/80"
          title="Settings"
          (click)="openSettings()"
        >
          <ng-icon
            name="lucideSettings"
            class="h-5 w-5 text-muted-foreground"
          />
        </button>
      </div>
    </div>

    @if (savedRooms().length > 0) {
      <div class="mt-2 flex items-center gap-2 overflow-x-auto pb-1">
        <span class="shrink-0 text-xs font-medium text-muted-foreground">My Servers</span>
        @for (room of savedRooms(); track room.id) {
          <button
            type="button"
            class="shrink-0 rounded-md border border-border bg-card px-2.5 py-1.5 text-xs font-medium text-foreground transition-colors hover:bg-secondary"
            (click)="joinSavedRoom(room)"
          >
            {{ room.name }}
          </button>
        }
      </div>
    }
  </div>

  <div class="grid min-h-0 flex-1 grid-cols-1 overflow-hidden lg:grid-cols-[minmax(300px,380px)_1fr]">
    <app-user-search-list
      class="min-h-0 overflow-y-auto border-b border-border lg:border-b-0 lg:border-r"
      [searchQuery]="searchQuery"
    />

    <section class="min-h-0 overflow-y-auto">
      <div class="sticky top-0 z-10 flex items-center justify-between border-b border-border bg-background/95 px-3 py-2 backdrop-blur">
        <div>
          <h3 class="text-sm font-semibold text-foreground">Servers</h3>
          <p class="text-xs text-muted-foreground">{{ searchResults().length }} found</p>
        </div>
      </div>

      @if (isSearching()) {
        <div class="flex items-center justify-center py-8">
          <div class="h-8 w-8 animate-spin rounded-full border-b-2 border-primary"></div>
        </div>
      } @else if (searchResults().length === 0) {
        <div class="flex flex-col items-center justify-center px-4 py-10 text-muted-foreground">
          <ng-icon
            name="lucideSearch"
            class="mb-3 h-10 w-10 opacity-50"
          />
          <p class="text-sm font-medium">No servers found</p>
        </div>
      } @else {
        <div class="space-y-2 p-3">
          @for (server of searchResults(); track server.id) {
            <div
              class="group w-full cursor-pointer rounded-lg border bg-card p-3 text-left transition-colors"
              [class.border-border]="!isServerMarkedBanned(server)"
              [class.hover:border-primary/50]="!isServerMarkedBanned(server)"
              [class.hover:bg-card/80]="!isServerMarkedBanned(server)"
              [class.border-destructive/40]="isServerMarkedBanned(server)"
              [class.bg-destructive/5]="isServerMarkedBanned(server)"
              [class.hover:border-destructive/60]="isServerMarkedBanned(server)"
              [title]="isJoinedServer(server) ? 'Double-click to open ' + server.name : 'Double-click to join ' + server.name"
              (dblclick)="openServerCard(server)"
            >
              <div class="flex min-w-0 items-start gap-3">
                <div class="grid h-10 w-10 shrink-0 place-items-center overflow-hidden rounded-lg bg-secondary text-sm font-semibold text-foreground">
                  @if (server.icon) {
                    <div
                      aria-hidden="true"
                      class="h-full w-full bg-cover bg-center bg-no-repeat"
                      [style.backgroundImage]="'url(' + server.icon + ')'"
                    ></div>
                  } @else {
                    {{ server.name[0] || '?' }}
                  }
                </div>

                <div class="min-w-0 flex-1">
                  <div class="flex min-w-0 flex-wrap items-center gap-2">
                    <h3
                      class="truncate text-sm font-semibold transition-colors"
                      [class.text-foreground]="!isServerMarkedBanned(server)"
                      [class.group-hover:text-primary]="!isServerMarkedBanned(server)"
                      [class.text-destructive]="isServerMarkedBanned(server)"
                    >
                      {{ server.name }}
                    </h3>

                    @if (isServerMarkedBanned(server)) {
                      <span
                        class="inline-flex items-center gap-1 rounded-full bg-destructive/10 px-2 py-0.5 text-[11px] font-medium text-destructive"
                      >
                        <ng-icon
                          name="lucideLock"
                          class="h-3 w-3"
                        />
                        Banned
                      </span>
                    } @else if (server.isPrivate) {
                      <span
                        class="inline-flex items-center gap-1 rounded-full bg-secondary px-2 py-0.5 text-[11px] font-medium text-muted-foreground"
                      >
                        <ng-icon
                          name="lucideLock"
                          class="h-3 w-3"
                        />
                        Private
                      </span>
                    } @else if (server.hasPassword) {
                      <span
                        class="inline-flex items-center gap-1 rounded-full bg-secondary px-2 py-0.5 text-[11px] font-medium text-muted-foreground"
                      >
                        <ng-icon
                          name="lucideLock"
                          class="h-3 w-3"
                        />
                        Password
                      </span>
                    } @else {
                      <ng-icon
                        name="lucideGlobe"
                        class="h-4 w-4 text-muted-foreground"
                      />
                    }
                  </div>

                  @if (server.description) {
                    <p class="mt-1 line-clamp-1 text-xs text-muted-foreground">{{ server.description }}</p>
                  }

                  <div class="mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground">
                    <span class="inline-flex items-center gap-1">
                      <ng-icon
                        name="lucideUsers"
                        class="h-3.5 w-3.5"
                      />
                      {{ getServerUserCount(server) }}/{{ getServerCapacityLabel(server) }}
                    </span>
                    @if (server.topic) {
                      <span class="truncate">{{ server.topic }}</span>
                    }
                    <span class="truncate">Owner: {{ getServerOwnerLabel(server) }}</span>
                    <span class="truncate">{{ server.sourceName || server.hostName || 'Unknown' }}</span>
                  </div>
                </div>

                <div class="relative shrink-0">
                  @if (isJoinedServer(server)) {
                    <div
                      class="flex items-center overflow-hidden rounded-md border border-emerald-500/30 bg-emerald-500/10 text-xs font-semibold text-emerald-500"
                    >
                      <span class="px-2.5 py-1.5">Joined</span>
                      <button
                        type="button"
                        class="grid h-8 w-8 place-items-center border-l border-emerald-500/20 transition-colors hover:bg-emerald-500/15"
                        [attr.aria-label]="'Server actions for ' + server.name"
                        (click)="toggleJoinedServerMenu($event, server)"
                      >
                        <ng-icon
                          name="lucideChevronDown"
                          class="h-4 w-4"
                        />
                      </button>
                    </div>

                    @if (joinedServerMenuId() === server.id) {
                      <div class="absolute right-0 top-full z-20 mt-1 w-36 rounded-md border border-border bg-card py-1 shadow-lg">
                        <button
                          type="button"
                          class="w-full px-3 py-2 text-left text-xs font-medium text-destructive transition-colors hover:bg-destructive/10"
                          (click)="openLeaveDialog($event, server)"
                        >
                          Leave
                        </button>
                      </div>
                    }
                  } @else {
                    <button
                      type="button"
                      class="pointer-events-none scale-95 rounded-md bg-primary px-2.5 py-1.5 text-xs font-semibold text-primary-foreground opacity-0 transition-[opacity,transform] duration-75 ease-out hover:scale-100 hover:opacity-100 group-hover:pointer-events-auto group-hover:scale-100 group-hover:opacity-100 group-focus-within:pointer-events-auto group-focus-within:scale-100 group-focus-within:opacity-100"
                      [attr.aria-label]="'Join ' + server.name"
                      (click)="joinServer(server)"
                    >
                      <span class="sr-only">{{ server.name }}</span>
                      Join
                    </button>
                  }
                </div>
              </div>
            </div>
          }
        </div>
      }
    </section>
  </div>

  @if (joinErrorMessage() || error()) {
    <div class="p-4 bg-destructive/10 border-t border-destructive">
      <p class="text-sm text-destructive">{{ joinErrorMessage() || error() }}</p>
    </div>
  }
</div>

@if (leaveDialogRoom()) {
  <app-leave-server-dialog
    [room]="leaveDialogRoom()!"
    [currentUser]="currentUser() ?? null"
    (confirmed)="confirmLeaveServer($event)"
    (cancelled)="closeLeaveDialog()"
  />
}

@if (showBannedDialog()) {
  <app-confirm-dialog
    title="Banned"
    confirmLabel="OK"
    cancelLabel="Close"
    variant="danger"
    [widthClass]="'w-96 max-w-[90vw]'"
    (confirmed)="closeBannedDialog()"
    (cancelled)="closeBannedDialog()"
  >
    <p>You are banned from {{ bannedServerName() || 'this server' }}.</p>
  </app-confirm-dialog>
}

@if (showPasswordDialog() && passwordPromptServer()) {
  <app-confirm-dialog
    title="Password required"
    confirmLabel="Join server"
    cancelLabel="Cancel"
    [widthClass]="'w-[420px] max-w-[92vw]'"
    (confirmed)="confirmPasswordJoin()"
    (cancelled)="closePasswordDialog()"
  >
    <div class="space-y-3">
      <p>Enter the password to join {{ passwordPromptServer()!.name }}.</p>

      <div>
        <label
          for="join-server-password"
          class="mb-1 block text-xs font-medium uppercase tracking-wide text-muted-foreground"
        >
          Server password
        </label>
        <input
          id="join-server-password"
          type="password"
          [(ngModel)]="joinPassword"
          placeholder="Enter password"
          class="w-full rounded-lg border border-border bg-secondary px-3 py-2 text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary"
        />
      </div>

      @if (joinPasswordError()) {
        <p class="text-sm text-destructive">{{ joinPasswordError() }}</p>
      }
    </div>
  </app-confirm-dialog>
}

@if (pluginConsentDialog(); as dialog) {
  <div
    class="fixed inset-0 z-50 bg-black/50"
    role="presentation"
  ></div>
  <section
    class="fixed left-1/2 top-1/2 z-[51] flex max-h-[min(42rem,calc(100vh-2rem))] w-[min(34rem,calc(100vw-2rem))] -translate-x-1/2 -translate-y-1/2 flex-col overflow-hidden rounded-lg border border-border bg-card text-foreground shadow-2xl"
    role="dialog"
    aria-modal="true"
    aria-labelledby="join-plugin-consent-title"
  >
    <header class="border-b border-border p-4">
      <p class="text-sm text-muted-foreground">Plugin downloads</p>
      <h2
        id="join-plugin-consent-title"
        class="mt-1 text-lg font-semibold"
      >
        {{ dialog.server.name }} uses plugins
      </h2>
    </header>

    <div class="grid min-h-0 gap-4 overflow-auto p-4">
      @if (dialog.required.length > 0) {
        <section class="grid gap-2">
          <h3 class="text-sm font-semibold">Required before joining</h3>
          @for (requirement of dialog.required; track requirement.pluginId) {
            <div class="rounded-lg border border-border bg-background/50 px-3 py-2">
              <div class="flex items-start justify-between gap-3">
                <div class="min-w-0">
                  <p class="truncate text-sm font-semibold">{{ requirement.manifest?.title || requirement.pluginId }}</p>
                  @if (requirement.reason) {
                    <p class="mt-1 text-xs text-muted-foreground">{{ requirement.reason }}</p>
                  }
                </div>
                <span class="shrink-0 rounded-full bg-primary/10 px-2 py-0.5 text-xs font-semibold text-primary">Required</span>
              </div>
            </div>
          }
        </section>
      }

      @if (dialog.optional.length > 0) {
        <section class="grid gap-2">
          <h3 class="text-sm font-semibold">Optional plugins</h3>
          @for (requirement of dialog.optional; track requirement.pluginId) {
            <label class="flex items-start gap-3 rounded-lg border border-border bg-background/50 px-3 py-2">
              <input
                type="checkbox"
                class="mt-1 h-4 w-4 rounded border-border bg-secondary"
                [checked]="selectedOptionalPluginIds().has(requirement.pluginId)"
                [disabled]="pluginConsentBusy()"
                (change)="toggleOptionalPluginInstall(requirement.pluginId, $any($event.target).checked)"
              />
              <span class="min-w-0 flex-1">
                <span class="block truncate text-sm font-semibold">{{ requirement.manifest?.title || requirement.pluginId }}</span>
                @if (requirement.reason) {
                  <span class="mt-1 block text-xs text-muted-foreground">{{ requirement.reason }}</span>
                }
              </span>
            </label>
          }
        </section>
      }

      @if (pluginConsentError()) {
        <p class="rounded-lg border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive">{{ pluginConsentError() }}</p>
      }
    </div>

    <footer class="flex justify-end gap-2 border-t border-border p-4">
      <button
        type="button"
        (click)="closePluginConsentDialog()"
        [disabled]="pluginConsentBusy()"
        class="inline-flex min-h-8 items-center justify-center rounded-lg border border-border bg-card px-3 py-1.5 text-sm font-semibold transition-colors hover:bg-secondary disabled:cursor-not-allowed disabled:opacity-55"
      >
        Cancel join
      </button>
      <button
        type="button"
        (click)="confirmPluginConsent()"
        [disabled]="pluginConsentBusy()"
        class="inline-flex min-h-8 items-center justify-center rounded-lg border border-primary bg-primary px-3 py-1.5 text-sm font-semibold text-primary-foreground transition-colors hover:bg-primary/90 disabled:cursor-not-allowed disabled:opacity-55"
      >
        {{ pluginConsentBusy() ? 'Downloading' : dialog.required.length > 0 ? 'Accept and join' : 'Join' }}
      </button>
    </footer>
  </section>
}

<!-- Create Server Dialog -->
@if (showCreateDialog()) {
  <div
    class="fixed inset-0 bg-black/50 flex items-center justify-center z-50"
    (click)="closeCreateDialog()"
    (keydown.enter)="closeCreateDialog()"
    (keydown.space)="closeCreateDialog()"
    role="button"
    tabindex="0"
    aria-label="Close create server dialog"
  >
    <div
      class="bg-card border border-border rounded-lg p-6 w-full max-w-md m-4"
      (click)="$event.stopPropagation()"
      (keydown.enter)="$event.stopPropagation()"
      (keydown.space)="$event.stopPropagation()"
      role="dialog"
      aria-modal="true"
      tabindex="-1"
    >
      <h2 class="text-xl font-semibold text-foreground mb-4">Create Server</h2>

      <div class="space-y-4">
        <div>
          <label
            for="create-server-name"
            class="block text-sm font-medium text-foreground mb-1"
            >Server Name</label
          >
          <input
            type="text"
            [(ngModel)]="newServerName"
            placeholder="My Awesome Server"
            id="create-server-name"
            class="w-full px-3 py-2 bg-secondary rounded-lg border border-border text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary"
          />
        </div>

        <div>
          <label
            for="create-server-description"
            class="block text-sm font-medium text-foreground mb-1"
            >Description (optional)</label
          >
          <textarea
            [(ngModel)]="newServerDescription"
            placeholder="What's your server about?"
            rows="3"
            id="create-server-description"
            class="w-full px-3 py-2 bg-secondary rounded-lg border border-border text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary resize-none"
          ></textarea>
        </div>

        <div>
          <label
            for="create-server-topic"
            class="block text-sm font-medium text-foreground mb-1"
            >Topic (optional)</label
          >
          <input
            type="text"
            [(ngModel)]="newServerTopic"
            placeholder="gaming, music, coding..."
            id="create-server-topic"
            class="w-full px-3 py-2 bg-secondary rounded-lg border border-border text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary"
          />
        </div>

        <div>
          <label
            for="create-server-signal-endpoint"
            class="block text-sm font-medium text-foreground mb-1"
            >Signal Server Endpoint</label
          >
          <select
            id="create-server-signal-endpoint"
            [(ngModel)]="newServerSourceId"
            class="w-full px-3 py-2 bg-secondary rounded-lg border border-border text-foreground focus:outline-none focus:ring-2 focus:ring-primary"
          >
            @for (endpoint of activeEndpoints(); track endpoint.id) {
              <option [value]="endpoint.id">{{ endpoint.name }} ({{ endpoint.url }})</option>
            }
          </select>
          <p class="mt-1 text-xs text-muted-foreground">This endpoint handles all signaling for this chat server.</p>
        </div>

        <div class="flex items-center gap-2">
          <input
            type="checkbox"
            [(ngModel)]="newServerPrivate"
            id="private"
            class="w-4 h-4 rounded border-border bg-secondary"
          />
          <label
            for="private"
            class="text-sm text-foreground"
            >Private server</label
          >
        </div>

        <div>
          <label
            for="create-server-password"
            class="block text-sm font-medium text-foreground mb-1"
            >Password (optional)</label
          >
          <input
            type="password"
            [(ngModel)]="newServerPassword"
            placeholder="Leave blank to allow joining without a password"
            id="create-server-password"
            class="w-full px-3 py-2 bg-secondary rounded-lg border border-border text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary"
          />
          <p class="mt-1 text-xs text-muted-foreground">Users who already joined keep access even if you change the password later.</p>
        </div>
      </div>

      <div class="flex gap-3 mt-6">
        <button
          (click)="closeCreateDialog()"
          type="button"
          class="flex-1 px-4 py-2 bg-secondary text-foreground rounded-lg hover:bg-secondary/80 transition-colors"
        >
          Cancel
        </button>
        <button
          (click)="createServer()"
          [disabled]="!newServerName() || !newServerSourceId"
          type="button"
          class="flex-1 px-4 py-2 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
        >
          Create
        </button>
      </div>
    </div>
  </div>
}
