<script setup lang="ts">
import {api} from '@/tools/web.js'
import {ref, watch} from 'vue'
import {useRoute} from 'vue-router'
import type {ChatScript} from '@/types/chatroom.js'
import type {ReturnDto} from '@/types/response.js'
import {useMessage} from 'naive-ui'
import XamlModal from '@/components/XamlModal.vue'

const ROUTE = useRoute()
const MESSAGE = useMessage()

const showDrawer = defineModel('showDrawer', {required: true})

const showXamlModal = ref(false)

const {script} = defineProps<{
  script: string
}>()

const scriptForm = ref<ChatScript>({
  main_prompt: '',
  user_prefix: '',
  user_suffix: '',
  world_books: [],
})

function save() {
  const id = Number(ROUTE.params.id)
  api
    .post(`/chatroom/${id}/script/`, JSON.stringify(scriptForm.value))
    .then((res) => res.data as ReturnDto)
    .then((data) => {
      if (data.success) {
        scriptForm.value = data.result as ChatScript
        MESSAGE.success('保存剧本成功~')
      } else {
        throw TypeError('未知原因后端保存剧本失败。')
      }
    })
    .catch((err) => {
      MESSAGE.error(`保存剧本失败：${err}`)
    })
}

watch(
  () => script,
  () => {
    try {
      scriptForm.value = JSON.parse(script) as ChatScript
    } catch {
    }
  },
  {immediate: true},
)
</script>

<template>
  <n-drawer
    v-model:show="showDrawer"
    placement="left"
    default-width="50vw"
    resizable
    native-scrollbar
    @after-leave="showDrawer = false"
    :z-index="20"
    :on-after-leave="
      () => {
        if (showXamlModal) {
          showXamlModal = false
          MESSAGE.info('已关闭 Xaml 可视化工具。')
        }
      }
    "
  >
    <n-drawer-content>
      <template #header>
        <n-h2 prefix="bar" style="margin-bottom: 0">剧本编辑器</n-h2>
      </template>
      <n-flex vertical>
        <n-alert type="info" title="故事设定 · 世界书">
          以下内容会被拼接在提示词以及用户输入中，在向 LLM 发送请求时携带。
        </n-alert>

        <n-button secondary type="warning" @click="showXamlModal = true">Xaml 可视化</n-button>

        <n-card title="全局设定">
          <template #header-extra>
            <n-tag round type="info">这些内容每一轮请求都会被携带</n-tag>
          </template>
          <n-form :model="scriptForm">
            <n-form-item label="提示词（拼接于 Nya 主提示词后）" path="main_prompt">
              <n-input
                type="textarea"
                :rows="8"
                v-model:value="scriptForm.main_prompt"
                show-count
              />
            </n-form-item>
            <n-form-item label="用户输入前置词（拼接于最新一条用户输入前）" path="user_prefix">
              <n-input
                type="textarea"
                :rows="8"
                v-model:value="scriptForm.user_prefix"
                show-count
              />
            </n-form-item>
            <n-form-item label="用户输入后置词（拼接于最新一条用户输入后）" path="user_suffix">
              <n-input
                type="textarea"
                :rows="8"
                v-model:value="scriptForm.user_suffix"
                show-count
              />
            </n-form-item>
          </n-form>
        </n-card>

        <n-card title="世界书">
          <template #header-extra>
            <n-tag round type="info">仅在被提及时才会被动态拼接并携带的细分设定</n-tag>
          </template>
        </n-card>
      </n-flex>
      <template #footer>
        <n-button type="primary" @click="save()">保存</n-button>
      </template>
    </n-drawer-content>

    <xaml-modal v-model:show-modal="showXamlModal"/>
  </n-drawer>
</template>

<style scoped></style>
