<script setup lang="ts">
// forgot to import t 💀
const { t } = useI18n();

// Vars for translating stuff
interface translateInterfaceText {
  translateText: string;
}
const translateItem: Record<string, translateInterfaceText> = {};

const translateLoading = ref(false);
const displayTranslateContent = ref(false);
const traslateFailed = ref(false);
const translatedBefore = ref(false);

// Imports
import { ScanEyeIcon, RefreshCcwIcon } from "lucide-vue-next";
import {
  Tooltip,
  TooltipContent,
  TooltipProvider,
  TooltipTrigger,
} from "@/components/ui/tooltip";
import { AhoCorasick } from "@monyone/aho-corasick";
import translate from "translate";

async function CheckKidUnfriendlyContent(title: string, words: any[]) {
  try {
    const ac = new AhoCorasick(words);
    const kidfriendly = ac.hasKeywordInText(title);
    return kidfriendly;
  } catch (e) {
    console.log(e);
  }
}

const emit = defineEmits([
  "openArticles",
  "openNewsSourcePage",
  "windowopener",
]);

const props = defineProps<{
  applyForTranslation: Boolean;
  windowTranslateState: Boolean;
}>();

const openNewWindow = (itemId: string) => {
  emit("windowopener", "aboutNewsOrg");
};

const contentArray = ref([]);
const errorr = ref(false);
const switchTabs = ref(false);
const tabs = ref([]);
const primary = ref<string>("domestic"); // Hard code default value as top is just pure garbage.
const canNotLoadTabUI = ref(false);
const isDataCached = ref(false);
const pullTabsData = async () => {
  try {
    const req = await fetch("/api/tabs");
    const data = await req.json();
    if (data.error) {
      canNotLoadTabUI.value = true;
      return;
    }
    return data.data;
  } catch (e) {
    canNotLoadTabUI.value = true;
    return;
  }
};

const updateContent = async (url: string, tabAction: boolean) => {
  contentArray.value = [];
  if (tabAction === true) {
    primary.value = url;
    switchTabs.value = true;
  }
  try {
    const req = await fetch(`/api/home/lt?query=${url.trim()}`);
    const data = await req.json();
    if (data) {
      // Made by coderabbit: https://github.com/hpware/news-analyze/pull/6#discussion_r2144713017
      const coolArray = [
        ...(data.uuidData ?? []),
        ...(data.nuuiddata?.items ?? []),
      ];
      contentArray.value =
        coolArray.sort(
          (title1, title2) => title2.publishTimeUnix - title1.publishTimeUnix,
        ) || [];
      switchTabs.value = false;
      isDataCached.value = data.cached || false;
      displayTranslateContent.value = false;
      translatedBefore.value = false;
    }
  } catch (e) {
    console.log(e);
    errorr.value = true;
  }

  return;
};

const isPrimary = (url: string, defaultAction: boolean) => {
  if (primary.value === url) {
    return true;
  }
  return false;
};

onMounted(async () => {
  tabs.value = await pullTabsData();
  primary.value =
    tabs.value.find((tab) => tab.default === true)?.url || "domestic";
  await updateContent(primary.value, false);
});
const checkResults = ref(new Map());
var words = <any[]>[];
const pullWord = async () => {
  if (words.length === 0) {
    const req = await fetch("/api/contentcheck/kidunfriendlycontent");
    const res = await req.json();
    words = res.words;
    return res.words;
  }
  return pullWord;
};
const checks = async (title: string) => {
  const wordss = await pullWord();
  const result = await CheckKidUnfriendlyContent(title, wordss);
  checkResults.value.set(title, result);
  console.log(title);
  return result;
};
const getCheckResult = (title: string) => {
  return checkResults.value.get(title);
};
watch(
  contentArray,
  async (newContent) => {
    for (const item of newContent) {
      if (item.title && !switchTabs.value && item.contentType === "GENERAL") {
        checks(item.title);
      }
    }
  },
  { immediate: true },
);

const tf = (text: string) => {
  const words = text.toLowerCase().match(/[\u4e00-\u9fff]|[a-zA-Z0-9]+/g) || [];

  const freqMap = new Map();

  for (const word of words) {
    if (word.trim()) {
      freqMap.set(word, (freqMap.get(word) || 0) + 1);
    }
  }

  const tfVector = <any>{};
  for (const [term, count] of freqMap) {
    tfVector[term] = count / words.length;
  }

  return tfVector;
};

const jaccardSimilarity = (v1: any, v2: any) => {
  const k1 = new Set(Object.keys(v1));
  const k2 = new Set(Object.keys(v2));
  const intersection = new Set([...k1].filter((x) => k2.has(x)));
  const union = new Set([...k1, ...k2]);
  return intersection.size / union.size;
};

/*
const findRel =
async (title: string) => {
  const req = await fetch("/api/sort");
};*/

// Check words
const checkIfEmptyArray = [];
const useArgFindRel = (title, newsOrg) => {
  const targetVector = tf(title);
  const similarities = [];

  for (const item of contentArray.value) {
    if (
      item.title !== title &&
      item.contentType === "GENERAL" &&
      item.publisher !== newsOrg
    ) {
      const itemVector = tf(item.title);
      const similarity = jaccardSimilarity(targetVector, itemVector);
      if (similarity > 0.1) {
        similarities.push({
          title: item.title,
          similarity: similarity,
          item: item,
        });
      }
    }
  }
  const idx = checkIfEmptyArray.findIndex((x) => x.title === title);
  if (idx !== -1) checkIfEmptyArray.splice(idx, 1);
  checkIfEmptyArray.push({
    title: title,
    contains: similarities.length === 0,
  });
  return similarities.sort((a, b) => b.similarity - a.similarity).slice(0, 3);
};

const checkIfEmpty = (item) => {
  const found = checkIfEmptyArray.find((key) => key.title === item);
  return found ? found.contains : false;
};

const openNews = (url: string, titleName: string) => {
  emit("openArticles", url, titleName);
};

const openPublisher = (slug: string, title: string) => {
  emit("openNewsSourcePage", slug, title);
};
const isLoading = computed(() => contentArray.value.length === 0);
const shouldHideItem = (item) => {
  return (
    item.contentType !== "GENERAL" ||
    item.publisher?.toLowerCase().includes("line")
  );
};

// Translate (Selective content)
const startTranslating = async (text: string) => {
  try {
    translateItem[text] = {
      translateText: await translate(text, { from: "zh", to: "en" }),
    };
    console.log(translateItem[text]);
  } catch (error) {
    console.error("Translation failed:", error);
    traslateFailed.value = true;
    translateItem[text] = { translateText: text }; // fallback
  }
};
watch(
  () => props.applyForTranslation,
  (value) => {
    if (value === true || translatedBefore.value === false) {
      if (translatedBefore.value === true) {
        displayTranslateContent.value = true;
        return;
      }
      translateFunction();
      // NOT retranslating AGAIN when disabling the feat
      translatedBefore.value = true;
    } else {
      displayTranslateContent.value = false;
    }
  },
);
const translateFunction = () => {
  if (canNotLoadTabUI.value) {
    return;
  }
  translateLoading.value = true;
  // Translate tabs
  for (const tab of tabs.value) {
    startTranslating(tab.text);
  }
  // Translate news titles & news org
  for (const articleBlock of contentArray.value) {
    startTranslating(articleBlock.title);
    startTranslating(articleBlock.publisher);
  }
  setTimeout(() => {
    displayTranslateContent.value = true;
    translateLoading.value = false;
  }, 3000);
};
</script>
<template>
  <div v-if="translateLoading">Loading...</div>
  <div class="justify-center align-center text-center">
    <!--Tabs-->
    <div
      class="sticky inset-x-0 top-0 bg-gray-300/90 backdrop-blur-xl border shadow-lg rounded-xl p-1 m-1 mt-0 justify-center align-center text-center z-[50] overflow-x-auto scrollbar-xl min-w-min whitespace-nowrap px-2"
    >
      <div class="gap-2 flex flex-row justify-center align-center text-center">
        <!-- Tabs Loading State -->
        <template v-if="canNotLoadTabUI">
          <div
            v-for="n in 5"
            :key="n"
            class="h-8 w-20 bg-gray-400/50 animate-pulse rounded mx-1"
          ></div>
        </template>

        <!-- Actual Tabs -->
        <template v-else>
          <button
            v-for="item in tabs"
            @click="updateContent(item.url, true)"
            :class="
              isPrimary(item.url, true)
                ? 'text-sky-600 text-bold'
                : 'text-black'
            "
            class="disabled:cursor-not-allowed"
            :disabled="isPrimary(item.url, true) || switchTabs"
          >
            <span>{{
              displayTranslateContent
                ? translateItem[item.text].translateText
                : item.text
            }}</span>
          </button>
        </template>
        <button v-if="canNotLoadTabUI"><RefreshCcwIcon /></button>
      </div>
    </div>
    <!-- Content Area -->
    <div>
      <!-- Loading State -->
      <template v-if="isLoading">
        <div v-for="n in 7" :key="n" class="p-2 bg-gray-200 rounded m-1">
          <!-- Title Skeleton -->
          <div
            class="h-8 bg-gray-300 animate-pulse rounded-lg w-3/4 mx-auto mb-2"
          ></div>

          <!-- Publisher and Date Skeleton -->
          <div class="flex items-center justify-center gap-2 mb-2">
            <div class="h-4 w-24 bg-gray-300 animate-pulse rounded"></div>
            <div class="h-4 w-4 animate-pulse">--</div>
            <div class="h-4 w-32 bg-gray-300 animate-pulse rounded"></div>
          </div>

          <!-- Action Button Skeleton -->
          <div class="flex justify-center mb-2">
            <div class="h-8 w-24 bg-gray-300 animate-pulse rounded"></div>
          </div>

          <!-- Similar Articles Skeleton -->
          <div class="mt-4">
            <div
              class="h-6 w-20 bg-gray-300 animate-pulse rounded mb-2 mx-auto"
            ></div>
            <div class="space-y-2">
              <div
                v-for="i in 2"
                :key="i"
                class="p-2 bg-gray-300 animate-pulse rounded"
              >
                <div
                  class="h-4 w-3/4 bg-gray-400/50 animate-pulse rounded mb-1"
                ></div>
                <div
                  class="h-3 w-1/2 bg-gray-400/50 animate-pulse rounded"
                ></div>
              </div>
            </div>
          </div>
        </div>
      </template>

      <!-- Actual Content -->
      <template v-else>
        <div
          v-for="item in contentArray"
          :key="item.id"
          :class="shouldHideItem(item) && 'hidden'"
        >
          <div class="p-2 bg-gray-200 rounded m-1">
            <h1
              class="text-2xl text-bold"
              :class="getCheckResult(item.title) ? 'text-red-600' : ''"
            >
              {{
                displayTranslateContent
                  ? translateItem[item.title].translateText
                  : item.title
              }}
            </h1>
            <p class="m-0 text-gray-600">
              <TooltipProvider>
                <Tooltip>
                  <TooltipTrigger>
                    <button
                      @click="openPublisher(item.publisherId, item.publisher)"
                    >
                      {{
                        displayTranslateContent
                          ? translateItem[item.publisher].translateText
                          : item.publisher
                      }}
                    </button>
                  </TooltipTrigger>
                  <TooltipContent class="rounded">
                    {{ t("news.articleopenpart1") }}({{
                      displayTranslateContent
                        ? translateItem[item.publisher].translateText
                        : item.publisher
                    }}){{ t("news.articleopenpart2") }}
                  </TooltipContent>
                </Tooltip>
              </TooltipProvider>
              --
              {{
                new Date(item.publishTimeUnix).toLocaleString("zh-TW", {
                  year: "numeric",
                  month: "2-digit",
                  day: "2-digit",
                  hour: "2-digit",
                  minute: "2-digit",
                  hour12: false,
                })
              }}
            </p>
            <div
              class="justify-center align-center text-center flex flex-row p-1"
            >
              <TooltipProvider>
                <Tooltip>
                  <TooltipTrigger>
                    <button
                      @click="openNews(item.url.hash, item.title)"
                      class="flex flex-row p-1 bg-sky-300/50 hover:bg-sky-400/50 shadow-lg backdrop-blur-sm rounded transition-all duration-200"
                    >
                      <ScanEyeIcon class="w-6 h-6 p-1" /><span>{{
                        t("news.open")
                      }}</span>
                    </button>
                  </TooltipTrigger>
                  <TooltipContent class="rounded">
                    {{ t("news.opennewwindow") }}
                  </TooltipContent>
                </Tooltip>
              </TooltipProvider>
            </div>
            <div>
              <div>
                <h3 class="text-lg">{{ t("news.similararticles") }}</h3>
                <div class="space-y-2">
                  <div
                    v-for="similar in useArgFindRel(item.title, item.publisher)"
                    :key="similar.item.id"
                    class="p-2 bg-gray-100 rounded text-sm cursor-pointer hover:bg-gray-200"
                    @click="openNews(similar.item.url.hash, item.title)"
                  >
                    <div class="font-medium">{{ similar.title }}</div>
                    <div class="text-gray-500 text-xs">
                      {{ t("news.similarity") }}:
                      {{ (similar.similarity * 100).toFixed(1) }}% |
                      {{
                        displayTranslateContent
                          ? translateItem[similar.item.publisher].translateText
                          : similar.item.publisher
                      }}
                    </div>
                  </div>
                </div>
                <div
                  v-if="checkIfEmpty(item.title)"
                  class="text-gray-500 text-sm"
                >
                  {{ t("news.nosimilararticles") }}
                </div>
              </div>
            </div>
          </div>
        </div>
      </template>
    </div>
  </div>
</template>

<style scoped>
.animate-pulse {
  animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

@keyframes pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.5;
  }
}
</style>