<template>
  <div :class="['address', { identified: Boolean(inferredId) }]" ref="root">
    <hash-badge :address="address" class="hash-badge" />
    <router-link v-if="isFile" :to="{ name: 'file', params: { address } }">
      {{ address }}
    </router-link>
    <template v-else>
      <router-link v-if="link" :to="{ name: 'inspect', params: { address } }">
        {{ inferredId || address }}
      </router-link>
      <template v-else>{{ inferredId || address }}</template>
    </template>
  </div>
</template>

<script lang="ts">
import { ListingResult } from "@/types/base";
import { fetcher } from "@/utils";
import useSWRV from "swrv";
import { computed, defineComponent, onMounted, ref } from "vue";
import HashBadge from "./HashBadge.vue";

export default defineComponent({
  components: { HashBadge },
  name: "Address",
  props: {
    address: {
      type: String,
      required: true,
    },
    link: {
      type: Boolean,
      default: false,
    },
    isFile: {
      type: Boolean,
      default: false,
    },
    resolve: {
      type: Boolean,
      default: true,
    },
  },
  setup(props) {
    const rootEl = ref<HTMLElement | undefined>();
    const visible = ref(false);
    const observer = new IntersectionObserver((entries) => {
      visible.value = entries.some((entry) => entry.isIntersecting);
    });
    onMounted(() => {
      if (rootEl.value) {
        observer.observe(rootEl.value);
      }
    });

    const { data: addressEntries } = useSWRV<ListingResult, unknown>(
      () => (visible.value && `/api/obj/${props.address}`) || null,
      fetcher
    );

    const { data: typeId } = useSWRV<ListingResult, unknown>(() => {
      if (!props.isFile && props.resolve) {
        const entries = Object.values(addressEntries?.value || {});
        const isEntry = entries.find(
          (entry) => entry.entity === props.address && entry.attribute === "IS"
        );
        if (isEntry) {
          return `/api/obj?query=(matches "${isEntry.value.c}" "TYPE_ID" ?)`;
        }
      }
      return null;
    }, fetcher);

    const inferredId = computed(() => {
      const typeIdValue = Object.values(typeId?.value || {})[0];
      if (typeIdValue) {
        return Object.values(addressEntries?.value || []).find(
          (entry) =>
            entry.entity === props.address &&
            entry.attribute === typeIdValue.value.c
        )?.value.c;
      }
    });

    return {
      root: rootEl,
      inferredId,
    };
  },
});
</script>

<style scoped>
.address {
  font-family: var(--monospace-font);
  display: flex;
}

.address.identified {
  font-family: var(--default-font);
  font-size: 0.95em;
}

.hash-badge {
  margin-right: 0.5em;
}
</style>
