<script setup lang="ts">
import { computed, h, ref, VNodeChild, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import { SelectOption } from 'naive-ui'
import { MultiModelDialogueItem } from '../types'
import { DiversityModeItem, diversityModeList } from '@/data/agent-setting-data'

interface Props {
  modelListOptions: SelectOption[]
  isCurrent: boolean
}

const { t } = useI18n()

const props = defineProps<Props>()

const emit = defineEmits<{
  updateConfig: [modelDialogueItem: MultiModelDialogueItem]
  resetConversation: []
}>()

const modelConfig = defineModel<MultiModelDialogueItem>('modelConfig', { required: true })

const currentDiversityMode = ref('balance')

const currentModelNickName = computed({
  get: () => (modelConfig.value.modelNickName === '' ? undefined : modelConfig.value.modelNickName),
  set: (newValue) => {
    modelConfig.value.modelNickName = newValue || ''
  },
})

const isDisabledModelConfig = computed(() => {
  return currentDiversityMode.value !== 'custom'
})

watch(
  () => modelConfig.value,
  (newVal) => {
    const { temperature, topP } = newVal

    switch (temperature) {
      case 0.1:
        currentDiversityMode.value = topP === 0.1 ? 'accurate' : 'custom'
        break
      case 0.5:
        currentDiversityMode.value = topP === 0.7 ? 'balance' : 'custom'
        break
      case 0.95:
        currentDiversityMode.value = topP === 0.7 ? 'creative' : 'custom'
        break
      default:
        currentDiversityMode.value = 'custom'
    }
  },
  { deep: true, once: true, immediate: true },
)

// 模型列表项渲染
function modelListRenderLabel(option: SelectOption): VNodeChild {
  if (option.type === 'group') return `${option.label}`

  return [
    h('div', { class: 'flex items-center' }, [
      h('div', {
        style: {
          width: '16px',
          height: '16px',
          marginRight: '6px',
          flexShrink: 0,
          background: `url(${option.icon})`,
          backgroundSize: '100% 100%',
        },
      }),
      h('span', {}, { default: () => option.label as string }),
    ]),
  ]
}

// 更新大模型
function handleUpdateLargeModel(_value: string, option: SelectOption) {
  modelConfig.value.icon = option.icon as string
  emit('resetConversation')
  handleUpdateAgentConfig()
}

// 切换生成多样性
function handleDiversityModeChange(diversityModeItem: DiversityModeItem) {
  const { value, topP, temperature } = diversityModeItem
  currentDiversityMode.value = value
  modelConfig.value.topP = topP
  modelConfig.value.temperature = temperature
  handleUpdateAgentConfig()
}

// 更新保存应用配置
function handleUpdateAgentConfig() {
  props.isCurrent && emit('updateConfig', modelConfig.value)
}
</script>

<template>
  <div class="px-1.5 py-1">
    <p class="text-font-color font-600 mb-2 select-none">
      {{ t('multi_model_dialogue_module.model_setting') }}
    </p>
    <n-select
      v-model:value="currentModelNickName"
      :options="modelListOptions"
      :render-label="modelListRenderLabel"
      :placeholder="t('multi_model_dialogue_module.please_select_model')"
      @update:value="handleUpdateLargeModel"
    />

    <p class="text-font-color font-600 mb-2 mt-[14px] select-none">
      {{ t('personal_space_module.agent_module.agent_setting_module.agent_config_module.generate_diversity') }}
    </p>
    <ul class="rounded-theme mt-2 grid grid-cols-4 overflow-hidden">
      <li
        v-for="(diversityModeItem, index) in diversityModeList"
        :key="index"
        class="hover:text-font-color flex h-[34px] w-full cursor-pointer items-center justify-center"
        :class="
          currentDiversityMode === diversityModeItem.value
            ? 'text-font-color bg-active-color'
            : 'text-gray-font-color bg-[#F7F7FA]'
        "
        @click="handleDiversityModeChange(diversityModeItem)"
      >
        {{ t(diversityModeItem.label) }}
      </li>
    </ul>

    <div class="mb-3 mt-[14px] flex h-[34px] items-center justify-between">
      <div class="flex w-[70px] items-center">
        <span class="text-font-color font-600 select-none">
          {{ t('personal_space_module.agent_module.agent_setting_module.agent_config_module.temperature') }}
        </span>
      </div>

      <div class="mx-3 flex flex-1">
        <n-slider
          v-model:value="modelConfig.temperature"
          :default-value="0"
          :step="0.01"
          :min="0.01"
          :max="1"
          :disabled="isDisabledModelConfig"
          @update:value="handleUpdateAgentConfig"
        />
      </div>

      <n-input-number
        v-model:value="modelConfig.temperature"
        :bordered="false"
        :step="0.01"
        :min="0"
        :max="1"
        :disabled="isDisabledModelConfig"
        placeholder=""
        button-placement="both"
        class="w-[100px]! model-config-input-number"
        @update:value="handleUpdateAgentConfig"
      >
        <template #minus-icon>
          <div
            class="border-inactive-border-color h-6! w-6! rounded-theme flex shrink-0 items-center justify-center border"
          >
            <i class="iconfont icon-minus" />
          </div>
        </template>
        <template #add-icon>
          <div
            class="border-inactive-border-color h-6! w-6! rounded-theme flex shrink-0 items-center justify-center border"
          >
            <i class="iconfont icon-add" />
          </div>
        </template>
      </n-input-number>
    </div>

    <div class="mt-4 text-xs">
      <div class="mb-3 flex h-[34px] items-center justify-between">
        <div class="flex w-[70px] items-center">
          <span class="text-font-color font-600 select-none">
            {{ t('personal_space_module.agent_module.agent_setting_module.agent_config_module.topP') }}
          </span>
        </div>

        <div class="mx-3 flex flex-1">
          <n-slider
            v-model:value="modelConfig.topP"
            :default-value="0"
            :step="0.01"
            :min="0"
            :max="1"
            :disabled="isDisabledModelConfig"
            @update:value="handleUpdateAgentConfig"
          />
        </div>

        <n-input-number
          v-model:value="modelConfig.topP"
          :bordered="false"
          :step="0.01"
          :min="0"
          :max="1"
          :disabled="isDisabledModelConfig"
          placeholder=""
          button-placement="both"
          class="w-[100px]! model-config-input-number"
          @update:value="handleUpdateAgentConfig"
        >
          <template #minus-icon>
            <div
              class="border-inactive-border-color h-6! w-6! rounded-theme flex shrink-0 items-center justify-center border"
            >
              <i class="iconfont icon-minus" />
            </div>
          </template>
          <template #add-icon>
            <div
              class="border-inactive-border-color h-6! w-6! rounded-theme flex shrink-0 items-center justify-center border"
            >
              <i class="iconfont icon-add" />
            </div>
          </template>
        </n-input-number>
      </div>
    </div>

    <p class="text-font-color font-600 mb-1.5 select-none">
      {{ t('multi_model_dialogue_module.agent_system') }}
    </p>
    <n-input
      v-model:value="modelConfig.agentSystem"
      type="textarea"
      placeholder=""
      :rows="10"
      class="agent-system-input"
      @update:value="handleUpdateAgentConfig"
    />
  </div>
</template>
