<script lang="ts" setup>
import {
  Dialog,
  IconExternalLinkLine,
  IconEye,
  IconEyeOff,
  Toast,
  VAvatar,
  VDropdownItem,
  VEntity,
  VEntityField,
  VSpace,
  VStatusDot,
} from "@halo-dev/components";
import type { ListedPost } from "@halo-dev/api-client";
import { computed } from "vue";
import { postLabels } from "@/constants/labels";
import PostTag from "@console/modules/contents/posts/tags/components/PostTag.vue";
import { formatDatetime } from "@/utils/date";
import StatusDotField from "@/components/entity-fields/StatusDotField.vue";
import { useI18n } from "vue-i18n";
import HasPermission from "@/components/permission/HasPermission.vue";
import { apiClient } from "@/utils/api-client";
import { useQueryClient } from "@tanstack/vue-query";

const { t } = useI18n();
const queryClient = useQueryClient();

const props = withDefaults(
  defineProps<{
    post: ListedPost;
  }>(),
  {}
);

const externalUrl = computed(() => {
  const { status, metadata } = props.post.post;
  if (metadata.labels?.[postLabels.PUBLISHED] === "true") {
    return status?.permalink;
  }
  return `/preview/posts/${metadata.name}`;
});

const publishStatus = computed(() => {
  const { labels } = props.post.post.metadata;
  return labels?.[postLabels.PUBLISHED] === "true"
    ? t("core.post.filters.status.items.published")
    : t("core.post.filters.status.items.draft");
});

const isPublishing = computed(() => {
  const { spec, status, metadata } = props.post.post;
  return (
    (spec.publish && metadata.labels?.[postLabels.PUBLISHED] !== "true") ||
    (spec.releaseSnapshot === spec.headSnapshot && status?.inProgress)
  );
});

async function handlePublish() {
  await apiClient.uc.post.publishMyPost({
    name: props.post.post.metadata.name,
  });

  Toast.success(t("core.common.toast.publish_success"));
  queryClient.invalidateQueries({ queryKey: ["my-posts"] });
}

function handleUnpublish() {
  Dialog.warning({
    title: "取消发布",
    description: "确定要取消发布吗？",
    async onConfirm() {
      await apiClient.uc.post.unpublishMyPost({
        name: props.post.post.metadata.name,
      });

      Toast.success(t("core.common.toast.cancel_publish_success"));
      queryClient.invalidateQueries({ queryKey: ["my-posts"] });
    },
  });
}
</script>

<template>
  <VEntity>
    <template #start>
      <VEntityField
        :title="post.post.spec.title"
        :route="{
          name: 'PostEditor',
          query: { name: post.post.metadata.name },
        }"
        width="27rem"
      >
        <template #extra>
          <VSpace class="mt-1 sm:mt-0">
            <RouterLink
              v-if="post.post.status?.inProgress"
              v-tooltip="$t('core.common.tooltips.unpublished_content_tip')"
              class="flex items-center"
              :to="{
                name: 'PostEditor',
                query: { name: post.post.metadata.name },
              }"
            >
              <VStatusDot state="success" animate />
            </RouterLink>
            <a
              target="_blank"
              :href="externalUrl"
              class="hidden text-gray-600 transition-all hover:text-gray-900 group-hover:inline-block"
            >
              <IconExternalLinkLine class="h-3.5 w-3.5" />
            </a>
          </VSpace>
        </template>
        <template #description>
          <div class="flex flex-col gap-1.5">
            <VSpace class="flex-wrap !gap-y-1">
              <p
                v-if="post.categories.length"
                class="inline-flex flex-wrap gap-1 text-xs text-gray-500"
              >
                {{ $t("core.post.list.fields.categories") }}
                <a
                  v-for="(category, categoryIndex) in post.categories"
                  :key="categoryIndex"
                  :href="category.status?.permalink"
                  :title="category.status?.permalink"
                  target="_blank"
                  class="cursor-pointer hover:text-gray-900"
                >
                  {{ category.spec.displayName }}
                </a>
              </p>
              <span class="text-xs text-gray-500">
                {{
                  $t("core.post.list.fields.visits", {
                    visits: post.stats.visit,
                  })
                }}
              </span>
              <span class="text-xs text-gray-500">
                {{
                  $t("core.post.list.fields.comments", {
                    comments: post.stats.totalComment || 0,
                  })
                }}
              </span>
              <span v-if="post.post.spec.pinned" class="text-xs text-gray-500">
                {{ $t("core.post.list.fields.pinned") }}
              </span>
            </VSpace>
            <VSpace v-if="post.tags.length" class="flex-wrap">
              <PostTag
                v-for="(tag, tagIndex) in post.tags"
                :key="tagIndex"
                :tag="tag"
                route
              ></PostTag>
            </VSpace>
          </div>
        </template>
      </VEntityField>
    </template>
    <template #end>
      <VEntityField>
        <template #description>
          <VAvatar
            v-for="{ name, avatar, displayName } in post.contributors"
            :key="name"
            v-tooltip="displayName"
            size="xs"
            :src="avatar"
            :alt="displayName"
            circle
          ></VAvatar>
        </template>
      </VEntityField>
      <VEntityField :description="publishStatus">
        <template v-if="isPublishing" #description>
          <VStatusDot :text="$t('core.common.tooltips.publishing')" animate />
        </template>
      </VEntityField>
      <VEntityField>
        <template #description>
          <IconEye
            v-if="post.post.spec.visible === 'PUBLIC'"
            v-tooltip="$t('core.post.filters.visible.items.public')"
            class="cursor-pointer text-sm transition-all hover:text-blue-600"
          />
          <IconEyeOff
            v-if="post.post.spec.visible === 'PRIVATE'"
            v-tooltip="$t('core.post.filters.visible.items.private')"
            class="cursor-pointer text-sm transition-all hover:text-blue-600"
          />
        </template>
      </VEntityField>
      <StatusDotField
        v-if="props.post.post.spec.deleted"
        :tooltip="$t('core.common.status.deleting')"
        state="warning"
        animate
      />
      <VEntityField
        v-if="post.post.spec.publishTime"
        :description="formatDatetime(post.post.spec.publishTime)"
      ></VEntityField>
    </template>
    <template #dropdownItems>
      <VDropdownItem
        @click="
          $router.push({
            name: 'PostEditor',
            query: { name: post.post.metadata.name },
          })
        "
      >
        编辑
      </VDropdownItem>
      <HasPermission :permissions="['uc:posts:publish']">
        <VDropdownItem
          v-if="post.post.metadata.labels?.[postLabels.PUBLISHED] === 'false'"
          @click="handlePublish"
        >
          发布
        </VDropdownItem>
        <VDropdownItem v-else type="danger" @click="handleUnpublish">
          取消发布
        </VDropdownItem>
      </HasPermission>
    </template>
  </VEntity>
</template>
