<template>
  <div
    class="dropdown dropdown-hover absolute -left-2 z-10 font-sans"
    :class="shouldShowBelow ? 'dropdown-right' : 'dropdown-right dropdown-end'"
    v-show="container"
    ref="dropdownRef"
    @mouseenter="checkDropdownPosition"
  >
    <router-link
      v-if="isSearching"
      @click="resetSearch()"
      tabindex="0"
      class="btn btn-square btn-xs border-base-content/20 bg-base-100 pointer-events-auto! opacity-0 shadow-sm group-hover/entry:opacity-90"
      :to="{
        name: '/container/[id].time.[datetime]',
        params: { id: container.id, datetime: logEntry.date.toISOString() },
        query: { logId: logEntry.id },
      }"
    >
      <material-symbols:eye-tracking />
    </router-link>
    <button
      tabindex="0"
      class="btn btn-square btn-xs border-base-content/20 bg-base-100 border opacity-0 shadow-sm group-hover/entry:opacity-90"
      v-else
    >
      <ion:ellipsis-vertical />
    </button>
    <ul
      tabindex="0"
      class="menu dropdown-content rounded-box bg-base-200 border-base-content/20 z-50 w-52 border p-1 text-sm shadow-sm"
      @click="hideMenu"
    >
      <li v-if="isSearching">
        <router-link
          @click="resetSearch()"
          :to="{
            name: '/container/[id].time.[datetime]',
            params: { id: container.id, datetime: logEntry.date.toISOString() },
            query: { logId: logEntry.id },
          }"
        >
          <material-symbols:eye-tracking />
          {{ $t("action.see-in-context") }}
        </router-link>
      </li>
      <li>
        <a
          @click="copyLogMessage()"
          :disabled="!isSupported"
          :title="!isSupported ? $t('error.copy-not-supported') : ''"
          :class="{ 'cursor-not-allowed opacity-50': !isSupported }"
        >
          <material-symbols:content-copy />
          {{ $t("action.copy-log") }}
        </a>
      </li>
      <li>
        <a
          @click="copyPermalink()"
          :disabled="!isSupported"
          :title="!isSupported ? $t('error.copy-not-supported') : ''"
          :class="{ 'cursor-not-allowed opacity-50': !isSupported }"
        >
          <material-symbols:link />
          {{ $t("action.copy-link") }}
        </a>
      </li>

      <li v-if="logEntry instanceof ComplexLogEntry">
        <a @click="showDrawer(LogDetails, { entry: logEntry })">
          <material-symbols:code-blocks-rounded />
          {{ $t("action.show-details") }}
        </a>
      </li>
      <li>
        <a @click="createAlert()">
          <mdi:bell />
          {{ $t("action.create-alert") }}
        </a>
      </li>
    </ul>
  </div>
</template>

<script lang="ts" setup>
import stripAnsi from "strip-ansi";
import { Container } from "@/models/Container";
import { LogEntry, SimpleLogEntry, ComplexLogEntry, GroupedLogEntry, JSONObject } from "@/models/LogEntry";
import LogDetails from "./LogDetails.vue";
import AlertForm from "@/components/Notification/AlertForm.vue";

const { logEntry, container } = defineProps<{
  logEntry: LogEntry<string | JSONObject>;
  container: Container;
}>();

const { showToast } = useToast();
const showDrawer = useDrawer();
const router = useRouter();
const { isSearching, resetSearch } = useSearchFilter();

const { copy, isSupported, copied } = useClipboard();
const { t } = useI18n();

async function copyLogMessage() {
  if (!isSupported.value) {
    return;
  }

  if (logEntry instanceof ComplexLogEntry) {
    await copy(stripAnsi(logEntry.rawMessage));
  } else if (logEntry instanceof SimpleLogEntry) {
    await copy(stripAnsi(logEntry.rawMessage));
  } else if (logEntry instanceof GroupedLogEntry) {
    await copy(stripAnsi(logEntry.message.join("\n")));
  }

  if (copied.value) {
    showToast(
      {
        title: t("toasts.copied.title"),
        message: t("toasts.copied.message"),
        type: "info",
      },
      { expire: 2000 },
    );
  }
}

async function copyPermalink() {
  if (!isSupported.value) {
    return;
  }
  const url = router.resolve({
    name: "/container/[id].time.[datetime]",
    params: { id: container.id, datetime: logEntry.date.toISOString() },
    query: { logId: logEntry.id },
  }).href;

  const resolved = new URL(url, window.location.origin);

  await copy(resolved.href);

  if (copied.value) {
    showToast(
      {
        title: t("toasts.copied.title"),
        message: t("toasts.copied.message"),
        type: "info",
      },
      { expire: 2000 },
    );
  }
}

function createAlert() {
  const containerExpr = `name contains "${container.name}"`;
  let logExpr = "";
  if (logEntry.level && logEntry.level !== "unknown") {
    logExpr = `level == "${logEntry.level}"`;
  }

  const nameParts = [container.name];
  if (logEntry.level && logEntry.level !== "unknown") {
    nameParts.push(logEntry.level);
  }
  const name = nameParts.join(" ");

  showDrawer(AlertForm, { prefill: { name, containerExpression: containerExpr, logExpression: logExpr } }, "lg");
}

function hideMenu(e: MouseEvent) {
  if (e.target instanceof HTMLAnchorElement) {
    setTimeout(() => {
      if (document.activeElement instanceof HTMLElement) {
        document.activeElement.blur();
      }
    }, 50);
  }
}

const dropdownRef = useTemplateRef<HTMLDivElement>("dropdownRef");
const shouldShowBelow = ref(false);

function checkDropdownPosition() {
  if (!dropdownRef.value) return;

  const rect = dropdownRef.value.getBoundingClientRect();
  shouldShowBelow.value = rect.top < 150;
}
</script>
