<script setup lang="ts">
import { type SelectOption, useMessage } from 'naive-ui'
import { computed, onMounted, ref, watch } from 'vue'

import AiiProviderAddModal from '@/components/aii/AiiProviderAddModal.vue'
import { aiiModelRules, check_remote_model } from '@/tools/avaliable-check.ts'
import { api } from '@/tools/web.js'
import type { AiiModelPublic, AiiProviderPublicWithoutKey } from '@/types/aii.js'
import type { ReturnDto } from '@/types/response.js'

const MESSAGE = useMessage()

const showModal = defineModel<boolean>('showModal', { required: true })

const { reload } = defineProps<{
  noAddProvider?: boolean
  reload?: () => void
}>()

const showAddProviderModal = ref(false)
const selectProvider = ref<number | null>(null)
const providers = ref<AiiProviderPublicWithoutKey[]>([])
const remoteModels = ref<string[]>([])

const addModelForm = ref({
  id: 0,
  model_name: '',
  max_context_length: 0,
  reasonable: false,
  aii_provider_id: selectProvider.value,
})

watch(selectProvider, (newValue) => {
  addModelForm.value.aii_provider_id = newValue
})

function loadProviders() {
  api
    .get('/aii/provider/')
    .then((res) => res.data as AiiProviderPublicWithoutKey[])
    .then((result) => {
      providers.value = result
      MESSAGE.success(`成功加载了 ${result.length} 个模型提供商。`)
    })
    .catch((err) => {
      MESSAGE.error(`获取模型提供商列表失败：${err}`)
    })
}

const providerOptions = computed<SelectOption[]>(() => {
  const options = [] as SelectOption[]
  for (const ap of providers.value) {
    options.push({
      label: `[${ap.id}] [ ${ap.name} ] ( ${ap.base_url} )`,
      value: ap.id,
    })
  }
  return options
})

onMounted(() => {
  loadProviders()
})

function onGetRemoteModels() {
  api
    .get(`/aii/provider/${selectProvider.value}/remote/models/`)
    .then((res) => res.data as ReturnDto)
    .then((data) => {
      if (data.success) {
        return data.result as string[]
      } else {
        throw TypeError('由于未知原因，后端业务错误。')
      }
    })
    .then((models) => {
      remoteModels.value = models
      MESSAGE.success(`成功获取模型提供商 ${selectProvider.value} 的 ${models.length} 个模型。`)
    })
    .catch((err) => {
      MESSAGE.error(`获取提供商的模型列表失败：${err}`)
    })
}

async function onCheck() {
  if (selectProvider.value) {
    if (await check_remote_model(selectProvider.value, addModelForm.value.model_name)) {
      MESSAGE.success(`提供商的模型 ${addModelForm.value.model_name} 可用。`)
    } else {
      MESSAGE.warning(`提供商的模型 ${addModelForm.value.model_name} 不可用。`)
    }
  } else {
    MESSAGE.warning('请选择模型提供商。')
  }
}

function onConfirm() {
  api
    .post('/aii/model/', JSON.stringify(addModelForm.value))
    .then((res) => res.data as AiiModelPublic)
    .then(() => {
      MESSAGE.success(`模型 ${addModelForm.value.model_name} 成功添加。`)
      showModal.value = false
      if (reload) reload()
    })
    .catch((err) => {
      MESSAGE.error(`添加模型失败：${err}`)
    })
}
</script>

<template>
  <n-modal v-model:show="showModal" preset="card" title="添加模型">
    <n-form
      :model="addModelForm"
      label-placement="left"
      label-width="auto"
      label-align="right"
      :rules="aiiModelRules"
    >
      <n-form-item label="模型提供商" path="aii_provider_id">
        <n-flex style="width: 100%" justify="right" align="center">
          <n-select v-model:value="selectProvider" :options="providerOptions" />
          <n-tag round type="info" v-if="!noAddProvider">修改已添加的提供商？请前往管理中心</n-tag>
          <n-button
            secondary
            type="success"
            size="small"
            round
            @click="loadProviders()"
            v-if="!noAddProvider"
          >
            刷新
          </n-button>
          <n-button
            secondary
            type="warning"
            size="small"
            round
            @click="showAddProviderModal = true"
            v-if="!noAddProvider"
          >
            添加
          </n-button>
        </n-flex>
      </n-form-item>
      <n-form-item label="模型名称" path="model_name">
        <n-flex style="width: 100%" justify="right" align="center">
          <n-input v-model:value="addModelForm.model_name" />
          <n-flex style="overflow: auto">
            <n-button
              secondary
              type="info"
              size="small"
              round
              v-for="m in remoteModels"
              v-bind:key="m"
              @click="addModelForm.model_name = m"
              >{{ m }}
            </n-button>
          </n-flex>
          <n-button secondary type="success" size="small" round @click="onGetRemoteModels()"
            >获取模型列表
          </n-button>
        </n-flex>
      </n-form-item>
      <n-form-item label="最大上下文" path="max_context_length">
        <n-input-number v-model:value="addModelForm.max_context_length">
          <template #suffix>K</template>
        </n-input-number>
      </n-form-item>
      <n-form-item label="支持思考">
        <n-switch v-model:value="addModelForm.reasonable" />
      </n-form-item>
      <n-form-item label="添加完成">
        <n-flex>
          <n-button secondary type="info" @click="onCheck()">检测</n-button>
          <n-button secondary type="primary" @click="onConfirm()">确认</n-button>
        </n-flex>
      </n-form-item>
    </n-form>
    <aii-provider-add-modal v-model:show-modal="showAddProviderModal" />
  </n-modal>
</template>

<style scoped></style>
