<script lang="ts" setup>
import { uuidv4 } from "@uniiem/uuid";
import type { IWorkflowResponse, LocalMessage, VisitorRole } from "~/types";

const gstate = useGState();
const runtimeConfig = useRuntimeConfig();

const getPopularInquiriesByRole = () => {
  return {
    stu: [
      {
        label: "物联网基础",
        inquiries: [
          {
            question: "物联网的定义是什么",
          },
          {
            question: "物联网与互联网的关系与区别",
          },
          {
            question: "物联网有哪些典型应用场景",
          },
          {
            question: "物联网系统的四层结构是什么",
          },
          {
            question: "物联网的本质是什么",
          },
          {
            question: "新基建和物联网的关系",
          },
          {
            question: "物联网工程的生命周期包括哪些阶段",
          },
        ],
      },
      {
        label: "智慧工地",
        inquiries: [
          {
            question: "智慧工地的概念与核心目标",
          },
          {
            question: "智慧工地系统的四层架构是什么",
          },
          {
            question: "施工场地工人健康检测系统包括哪些功能",
          },
          {
            question: "施工场地工人健康检测系统的作用是什么",
          },
          {
            question: "智慧工地中常用的传感器有哪些",
          },
          {
            question: "选择传感器需要考虑哪些特性参数",
          },
          {
            question: "传感器安装调试的主要步骤有哪些",
          },
        ],
      },
      {
        label: "智能交通",
        inquiries: [
          {
            question: "智能交通系统的定义和主要目标是什么",
          },
          {
            question: "智能交通系统的四层结构及其功能",
          },
          {
            question: "我国智能交通的发展现状如何",
          },
          {
            question: "国外智能交通发展的主要特点是什么",
          },
          {
            question: "智能交通系统中常用的感知技术有哪些",
          },
          {
            question: "射频识别技术在智能交通中的应用有哪些",
          },
          {
            question: "自动识别技术包括哪些分类",
          },
          {
            question: "交通卡口监控系统需求分析包含哪些方面",
          },
        ],
      },
    ],
    tea: [
      {
        label: "教师日常",
        inquiries: [
          {
            question: "如何申请借用公共教室",
          },
          {
            question: "教师每年最低教学学时要求是多少",
          },
          {
            question: "出差北京的住宿标准是什么",
          },
          {
            question: "副教授评审的基本条件是什么",
          },
        ],
      },
      {
        label: "教研活动",
        inquiries: [
          {
            question: "“挑战杯”国赛一等奖的奖励政策",
          },
          {
            question: "教学能力大赛的参赛规程是怎样的",
          },
          {
            question: "校级精品课程项目结题的要求",
          },
        ],
      },
      {
        label: "科研活动",
        inquiries: [
          {
            question: "横向项目合同签订的流程是怎样的",
          },
          {
            question: "成果转化中经费是如何使用的",
          },
          {
            question: "项目课题中团队占比的排序",
          },
        ],
      },
    ],
    fans: [
      {
        label: "校园概况",
        inquiries: [
          {
            question: "学校的发展历程是怎样的",
          },
          {
            question: "入校预约的流程",
          },
          {
            question: "学校有哪些专业",
          },
          {
            question: "学校主要的教学成果",
          },
        ],
      },
      {
        label: "招生就业",
        inquiries: [
          {
            question: "数字媒体专业历年的招生分数",
          },
          {
            question: "学校招收外地学生的比例",
          },
          {
            question: "学校近三年各个专业就业的情况",
          },
        ],
      },
    ],
  } as Record<
    VisitorRole,
    { label: string; inquiries?: Array<{ question: string }> }[]
  >;
};

const scrollArea = ref<HTMLDivElement | null>(null);
const regex = /<\/think>\n\n([\s\S]*)/m;

// 常见问题
const inquiries = computed(
  () => getPopularInquiriesByRole()[gstate.currentRole]
);

const responding = ref(false);
const inquiryInput = ref("");
const onInquirySubmit = async () => {
  if (inquiryInput.value) {
    gstate.insertOrUpdateMessage({
      id: uuidv4(),
      role: "user",
      message: inquiryInput.value,
    });
    responding.value = true;

    scrollLastMessageIntoView();

    let botMessageId = uuidv4();
    gstate.insertOrUpdateMessage({
      id: botMessageId,
      role: "bot",
    });

    try {
      // const resp = await useFetch<IWorkflowResponse>(
      //   `${runtimeConfig.public.DifyBaseURL}/workflows/run`,
      //   {
      //     method: "post",
      //     headers: {
      //       Authorization: `Bearer ${runtimeConfig.public.DifyApiKey}`,
      //     },
      //     body: JSON.stringify({
      //       inputs: {
      //         query: inquiryInput.value,
      //       },
      //       response_mode: "blocking",
      //       user: "xsh",
      //     }),
      //   }
      // );
      // gstate.insertOrUpdateMessage({
      //   id: botMessageId,
      //   role: "bot",
      //   message:
      //     resp.data.value?.data.outputs.message.match(regex)?.[1] ||
      //     "网络繁忙，请稍后再试",
      // });
      http_stream<{
        query: string
        response_mode: "blocking" | "streaming"
        user: string
        conversation_id: string
        inputs: Record<string, any>
      }>(`${runtimeConfig.public.DifyBaseURL}/chat-messages`, {
        query: inquiryInput.value,
        response_mode: "streaming",
        user: "xsh",
        conversation_id: "",
        inputs: {}
      }, {
        onStart: () => {
          responding.value = true;
          gstate.insertOrUpdateMessage({
            id: botMessageId,
            role: "bot",
            message: "",
          });
        },
        onTextChunk: (message: string) => {
          gstate.insertOrUpdateMessage({
            id: botMessageId,
            role: "bot",
            message: gstate.messages.find(m => m.id === botMessageId)?.message + message,
          });
        },
        onComplete: (id, finished_at, messageId) => {
          responding.value = false;
          gstate.insertOrUpdateMessage({
            id: botMessageId,
            role: "bot",
            message: gstate.messages.find(m => m.id === botMessageId)?.message || "网络繁忙，请稍后再试",
          });
          scrollLastMessageIntoView();
          fetch(
            `${runtimeConfig.public.DifyBaseURL}/messages/${messageId}/suggested?user=xsh`,
            {
              method: "GET",
              headers: {
                Authorization: `Bearer ${runtimeConfig.public.DifyApiKey}`,
              },
            }
          ).then(res => res.json()).then(data => {
            if (data?.data?.length) {
              gstate.insertOrUpdateMessage({
                id: uuidv4(),
                role: "suggestion",
                suggestions: data.data,
              });
            }
          })
        },
      })
    } catch (error) {
      gstate.insertOrUpdateMessage({
        id: botMessageId,
        role: "bot",
        message: "网络繁忙，请稍后再试",
      });
    }
    inquiryInput.value = "";

    responding.value = false;
    scrollLastMessageIntoView();
  }
};

const scrollLastMessageIntoView = () => {
  nextTick(() => {
    scrollArea.value?.scrollTo({
      top: scrollArea.value?.scrollHeight,
      behavior: "smooth",
    });
  });
};
</script>

<template>
  <div ref="scrollArea" class="h-full overflow-auto overflow-x-hidden mb-20">
    <div class="p-4 h-full flex flex-col gap-4">
      <PopularInquiries
        :inquiries-list="inquiries"
        @select-inquiry="
          (inquiry) => {
            if (responding) return;
            inquiryInput = inquiry;
            onInquirySubmit();
          }
        "
      />

      <ChatMessage
        v-for="message in gstate.messages"
        :name="gstate.botName"
        :key="message.id"
        :message="message"
        @select-suggestion="
          (suggestion) => {
            if (responding) return;
            inquiryInput = suggestion;
            onInquirySubmit();
          }"
      />
    </div>
    <div
      class="fixed inset-x-0 bottom-0 p-4 bg-white/90 rounded-t-2xl shadow-2xl dark:bg-neutral-800/90 backdrop-blur-2xl"
    >
      <img
        src="~/assets/image/pattern/ai_glow.png"
        class="absolute top-0 inset-x-0 opacity-50 pointer-events-none"
      />
      <div class="w-full flex justify-between items-center gap-2">
        <UInput
          placeholder="请输入问题"
          class="flex-1"
          size="xl"
          v-model="inquiryInput"
        />
        <UButton
          color="primary"
          variant="solid"
          size="xl"
          trailing
          trailing-icon="tabler:send-2"
          :loading="responding"
          loading-icon="svg-spinners:tadpole"
          @click="onInquirySubmit"
          >提问</UButton
        >
      </div>
    </div>
  </div>
</template>

<style scoped></style>
