<template>
  <NModal
    :show="show"
    preset="card"
    title="新建对话"
    style="width: 600px"
    @update:show="update"
  >
    <NForm>
      <NFormItem label="模型">
        <ModelSelector v-model="form.model_id" />
      </NFormItem>
      <NFormItem label="System Prompt 模板">
        <NSelect
          v-model:value="form.template_id"
          :options="templateOptions"
          clearable
          placeholder="可选；不选时使用下方自定义"
        />
      </NFormItem>
      <NFormItem label="自定义 System Prompt">
        <NInput
          v-model:value="form.system_prompt"
          type="textarea"
          :rows="4"
          placeholder="（可选）覆盖模板内容"
        />
      </NFormItem>
      <NFormItem label="挂载到（可选）">
        <div class="flex flex-col gap-2 w-full">
          <NSelect
            v-model:value="mountKind"
            :options="mountKindOptions"
            clearable
          />
          <NInput
            v-if="mountKind"
            v-model:value="mountID"
            placeholder="UUID"
          />
        </div>
      </NFormItem>
    </NForm>
    <template #footer>
      <div class="flex justify-end gap-2">
        <NButton @click="update(false)">
          取消
        </NButton>
        <NButton
          type="primary"
          :loading="submitting"
          :disabled="!form.model_id"
          @click="submit"
        >
          创建
        </NButton>
      </div>
    </template>
  </NModal>
</template>

<script setup lang="ts">
import { computed, onMounted, ref, watch } from 'vue'
import { NButton, NForm, NFormItem, NInput, NModal, NSelect } from 'naive-ui'

import ModelSelector from './components/ModelSelector.vue'
import { chatApi, type CreateConversationBody } from '@/api/chat'

type MountKind = 'project' | 'workspace' | 'issue'

const props = defineProps<{ show: boolean; projectId?: string }>()
const emit = defineEmits<{
  'update:show': [v: boolean]
  created: [conversationId: string]
}>()

const show = computed(() => props.show)

const form = ref<{
  model_id: string
  template_id: string | null
  system_prompt: string
}>({
  model_id: '',
  template_id: null,
  system_prompt: '',
})

const mountKind = ref<MountKind | null>(null)
const mountID = ref('')
const templates = ref<{ label: string; value: string }[]>([])
const templateOptions = computed(() => templates.value)
const mountKindOptions: { label: string; value: MountKind }[] = [
  { label: 'Project', value: 'project' },
  { label: 'Workspace', value: 'workspace' },
  { label: 'Issue', value: 'issue' },
]
const submitting = ref(false)

onMounted(async () => {
  const tpls = await chatApi.listTemplates()
  templates.value = tpls.map((t) => ({
    label: `[${t.scope}] ${t.name}`,
    value: t.id,
  }))
})

watch(
  () => props.projectId,
  (v) => {
    if (v) {
      mountKind.value = 'project'
      mountID.value = v
    }
  },
  { immediate: true },
)

function update(v: boolean) {
  emit('update:show', v)
}

async function submit() {
  if (!form.value.model_id) return
  submitting.value = true
  try {
    const body: CreateConversationBody = { model_id: form.value.model_id }
    if (form.value.template_id) body.template_id = form.value.template_id
    if (form.value.system_prompt) body.system_prompt = form.value.system_prompt
    if (mountKind.value && mountID.value) {
      if (mountKind.value === 'project') body.project_id = mountID.value
      else if (mountKind.value === 'workspace') body.workspace_id = mountID.value
      else if (mountKind.value === 'issue') body.issue_id = mountID.value
    }
    const conv = await chatApi.createConversation(body)
    emit('created', conv.id)
    update(false)
  } finally {
    submitting.value = false
  }
}
</script>
