<script setup>
// The server picker in the app rail. It names the server you are reading right
// now — which matters most when two sites hold different cars and the pages
// otherwise look identical — and switches between them in one click once each
// has been signed into.
import { ref, computed } from "vue";
import { servers, activeServer, displayName, isConnected, setActive } from "../servers";
import { t } from "../i18n";
import ServerConnectModal from "./ServerConnectModal.vue";

const open = ref(false);
// The server the dialog is working on: an existing entry to edit/connect, or
// null with `adding` set for a new one.
const editing = ref(null);
const adding = ref(false);

const current = computed(() => activeServer.value);
const showModal = computed(() => adding.value || !!editing.value);

// Only worth showing the rail entry once there is a choice to make, or a second
// server has been added and is waiting to be signed into.
const hasChoice = computed(() => servers.list.length > 1);

function choose(server) {
  if (isConnected(server.id)) {
    setActive(server.id);
    open.value = false;
    return;
  }
  // No session for it yet — the same dialog that adds a server signs you in.
  editing.value = server;
  open.value = false;
}

function edit(server) {
  editing.value = server;
  open.value = false;
}

function add() {
  adding.value = true;
  open.value = false;
}

function closeModal() {
  editing.value = null;
  adding.value = false;
}
</script>

<template>
  <div class="relative">
    <!-- One rail entry either way: it names the active server once there is a
         choice, and offers to add the second one when there isn't. -->
    <button
      class="flex w-full items-center gap-3 rounded-control px-2.5 py-2 text-left text-[15px] font-medium text-white/60 transition-colors hover:bg-white/5 hover:text-white md:px-3"
      :title="hasChoice ? t('servers.switchHint') : t('servers.add')"
      @click="hasChoice ? (open = !open) : add()"
    >
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" class="h-5 w-5 shrink-0">
        <rect x="3" y="4" width="18" height="7" rx="1.5" />
        <rect x="3" y="13" width="18" height="7" rx="1.5" />
        <path stroke-linecap="round" d="M7 7.5h.01M7 16.5h.01" />
      </svg>
      <span class="hidden min-w-0 flex-1 truncate md:inline">
        {{ hasChoice ? displayName(current) : t("servers.add") }}
      </span>
      <svg v-if="hasChoice" viewBox="0 0 20 20" fill="currentColor" class="hidden h-4 w-4 shrink-0 md:block">
        <path fill-rule="evenodd" d="M10 3a.75.75 0 0 1 .55.24l3.25 3.5a.75.75 0 1 1-1.1 1.02L10 4.852 7.3 7.76a.75.75 0 0 1-1.1-1.02l3.25-3.5A.75.75 0 0 1 10 3Zm-3.8 9.24a.75.75 0 0 1 1.06-.04l2.74 2.908 2.7-2.908a.75.75 0 1 1 1.1 1.02l-3.25 3.5a.75.75 0 0 1-1.1 0l-3.25-3.5a.75.75 0 0 1 .04-1.06Z" clip-rule="evenodd" />
      </svg>
    </button>

    <!-- Click-away backdrop, behind the menu but over everything else. -->
    <div v-if="open" class="fixed inset-0 z-20" @click="open = false"></div>

    <div v-if="open" class="dh-card absolute bottom-full left-0 z-30 mb-2 w-64 overflow-hidden p-1.5 shadow-pop">
      <p class="eyebrow px-2 pb-1 pt-1.5">{{ t("servers.title") }}</p>

      <div
        v-for="s in servers.list"
        :key="s.id"
        role="button"
        tabindex="0"
        class="flex w-full cursor-pointer items-center gap-2 rounded-control px-2 py-2 text-left transition-colors hover:bg-sunken"
        @click="choose(s)"
        @keydown.enter="choose(s)"
      >
        <!-- Green once this server has a session of its own; grey means picking
             it will ask for credentials rather than switch. -->
        <span
          class="h-2 w-2 flex-none rounded-full"
          :class="isConnected(s.id) ? 'bg-success' : 'bg-muted/40'"
          :title="isConnected(s.id) ? t('servers.connected') : t('servers.notConnected')"
        ></span>
        <span class="min-w-0 flex-1">
          <span class="block truncate text-sm font-medium text-strong">{{ displayName(s) }}</span>
          <span class="data block truncate text-[11px] text-muted">{{ s.url || t("servers.sameOrigin") }}</span>
        </span>
        <svg
          v-if="s.id === servers.activeId"
          viewBox="0 0 20 20"
          fill="currentColor"
          class="h-4 w-4 flex-none text-brand-600"
        >
          <path fill-rule="evenodd" d="M16.7 5.3a1 1 0 0 1 0 1.4l-7.5 7.5a1 1 0 0 1-1.4 0l-3.5-3.5a1 1 0 1 1 1.4-1.4l2.8 2.8 6.8-6.8a1 1 0 0 1 1.4 0Z" clip-rule="evenodd" />
        </svg>
        <button
          type="button"
          class="flex-none rounded p-1 text-muted transition-colors hover:bg-page hover:text-strong"
          :title="t('common.edit')"
          @click.stop="edit(s)"
        >
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" class="h-3.5 w-3.5">
            <path stroke-linecap="round" stroke-linejoin="round" d="m16.5 3.5 4 4L8 20H4v-4z" />
          </svg>
        </button>
      </div>

      <button
        type="button"
        class="mt-1 flex w-full items-center gap-2 border-t border-subtle px-2 pb-1 pt-2.5 text-left text-sm font-medium text-muted transition-colors hover:text-strong"
        @click="add"
      >
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" class="h-4 w-4">
          <path stroke-linecap="round" d="M12 5v14M5 12h14" />
        </svg>
        {{ t("servers.add") }}
      </button>
    </div>

    <ServerConnectModal v-if="showModal" :server="editing" @done="closeModal" @close="closeModal" />
  </div>
</template>
