<script setup lang="ts">
import { computed, h, onMounted, reactive, ref, VNodeChild } from 'vue'
import { SelectOption } from 'naive-ui'
import { useI18n } from 'vue-i18n'
import { Help, Down } from '@icon-park/vue-next'
import { PersonalAppConfigState } from '@/store/types/personal-app-config'
import { useSystemLanguageStore } from '@/store/modules/system-language'
import { DiversityModeItem, diversityModeList } from '@/data/agent-setting-data'
import { fetchGetLargeModelInfo, fetchGetLargeModelList } from '@/apis/agent-application'

const { t } = useI18n()

const systemLanguageStore = useSystemLanguageStore()

let modalListOptions = reactive<SelectOption[]>([])
let modalListRenderLabel: (option: SelectOption) => VNodeChild

const commModelConfig = defineModel<PersonalAppConfigState['commModelConfig']>('commModelConfig', { required: true })

const currentLargeModelIcon = ref('')
const currentDiversityMode = ref('balance')

const modelSettingWidth = ref(systemLanguageStore.currentLanguageInfo.key === 'en' ? '508px' : '420px')
const sliderLabelWidth = ref(systemLanguageStore.currentLanguageInfo.key === 'en' ? '158px' : '105px')

const isEnLanguage = computed(() => {
  return systemLanguageStore.currentLanguageInfo.key === 'en'
})

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

onMounted(() => {
  handleGetLargeModelList()
  handleGetLargeModelInfo()

  const { temperature, topP } = commModelConfig.value

  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'
  }
})

// 获取大模型列表
async function handleGetLargeModelList() {
  modalListOptions = []
  const res = await fetchGetLargeModelList<{ owner: string; models: string[]; icon: string }[]>()

  res.data.forEach((item) => {
    modalListOptions.push({
      type: 'group',
      label: item.owner,
      key: item.owner,
      children: item.models.map((model) => ({
        label: model,
        value: model,
        style: { fontSize: '12px' },
        icon: item.icon,
      })),
    })
  })

  modalListRenderLabel = (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 }),
      ]),
    ]
  }
}

// 获取当前大模型信息
async function handleGetLargeModelInfo() {
  const res = await fetchGetLargeModelInfo<{ icon: string }>(commModelConfig.value.largeModel)

  if (res.code === 0) {
    currentLargeModelIcon.value = res.data.icon
  }
}

// 更换大模型
function handleUpdateLargeModel(_value: string, option: SelectOption) {
  currentLargeModelIcon.value = option.icon as string
}

function handleDiversityModeChange(diversityModeItem: DiversityModeItem) {
  const { value, topP, temperature, communicationTurn } = diversityModeItem
  currentDiversityMode.value = value
  commModelConfig.value.topP = topP
  commModelConfig.value.temperature = temperature
  commModelConfig.value.communicationTurn = communicationTurn
}
</script>

<template>
  <div>
    <NPopover placement="bottom" trigger="click" :style="{ width: modelSettingWidth }">
      <template #trigger>
        <div
          class="hover:border-theme-color flex cursor-pointer items-center justify-between rounded-md border border-[#d4d6d9] px-3 py-[7px]"
        >
          <img :src="currentLargeModelIcon || '@/assets/images/lingjing-icon.png'" class="mr-1 h-4 w-4" />
          <span class="line-clamp-1 w-[100px] text-xs text-[#5c5f66]">
            {{ commModelConfig.largeModel }}
          </span>
          <Down theme="outline" size="16" fill="#333" class="ml-1.5 text-base outline-none" />
        </div>
      </template>
      <div class="flex items-center" :class="isEnLanguage ? 'my-[18px] justify-between' : 'mb-2 mt-1.5 justify-start'">
        <span class="font-500 mr-3 text-sm text-[#151b26]">
          {{ t('personal_space_module.agent_module.agent_setting_module.agent_config_module.question_answer_model') }}
        </span>
        <span
          class="rounded-theme bg-[#f2f5f9] text-xs text-[#5c5f66]"
          :class="isEnLanguage ? 'px-[13px] py-2' : 'px-1'"
        >
          {{
            t('personal_space_module.agent_module.agent_setting_module.agent_config_module.question_answer_model_desc')
          }}
        </span>
      </div>
      <NSelect
        v-model:value="commModelConfig.largeModel"
        class="model-select"
        :options="modalListOptions"
        :render-label="modalListRenderLabel"
        @update:value="handleUpdateLargeModel"
      />

      <div class="mt-4">
        <span>
          {{ t('personal_space_module.agent_module.agent_setting_module.agent_config_module.generate_diversity') }}
        </span>
        <ul class="rounded-theme grid grid-cols-4 overflow-hidden" :class="isEnLanguage ? 'mt-3' : 'mt-2'">
          <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 text-xs"
            :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>

      <div class="mt-4 text-xs">
        <div class="flex h-[34px] items-center justify-between" :class="isEnLanguage ? 'mb-3.5' : 'mb-2.5'">
          <div class="flex items-center" :style="{ width: sliderLabelWidth }">
            <span>
              {{ t('personal_space_module.agent_module.agent_setting_module.agent_config_module.topP') }}
            </span>
            <NPopover trigger="hover">
              <template #trigger>
                <Help
                  theme="outline"
                  size="15"
                  fill="#333"
                  :stroke-width="3"
                  class="ml-1 cursor-pointer text-base text-[#999] outline-none"
                />
              </template>
              <span class="text-xs">
                {{
                  t('personal_space_module.agent_module.agent_setting_module.agent_config_module.topP_popover_message')
                }}
              </span>
            </NPopover>
          </div>

          <div class="mx-5 flex flex-1">
            <NSlider
              v-model:value="commModelConfig.topP"
              :default-value="0"
              :step="0.01"
              :min="0"
              :max="1"
              :disabled="isDisabledCommModelConfig"
            />
            <span class="ml-4 w-8">{{ commModelConfig.topP }}</span>
          </div>

          <NInputNumber
            v-model:value="commModelConfig.topP"
            placeholder=""
            :step="0.01"
            :min="0"
            :max="1"
            :disabled="isDisabledCommModelConfig"
            size="small"
            class="common-model-config-input-number w-[90px]!"
          />
        </div>

        <div class="flex h-[34px] items-center justify-between" :class="isEnLanguage ? 'mb-3.5' : 'mb-2.5'">
          <div class="flex items-center" :style="{ width: sliderLabelWidth }">
            <span>
              {{ t('personal_space_module.agent_module.agent_setting_module.agent_config_module.temperature') }}
            </span>
            <NPopover trigger="hover">
              <template #trigger>
                <Help
                  theme="outline"
                  size="15"
                  fill="#333"
                  :stroke-width="3"
                  class="ml-1 cursor-pointer text-base text-[#999] outline-none"
                />
              </template>
              <span class="text-xs">
                {{
                  t(
                    'personal_space_module.agent_module.agent_setting_module.agent_config_module.temperature_popover_message',
                  )
                }}
              </span>
            </NPopover>
          </div>

          <div class="mx-5 flex flex-1">
            <NSlider
              v-model:value="commModelConfig.temperature"
              :default-value="0"
              :step="0.01"
              :min="0.01"
              :max="1"
              :disabled="isDisabledCommModelConfig"
            />
            <span class="ml-4 w-[32px]">{{ commModelConfig.temperature }}</span>
          </div>

          <NInputNumber
            v-model:value="commModelConfig.temperature"
            placeholder=""
            :step="0.01"
            :min="0"
            :max="1"
            :disabled="isDisabledCommModelConfig"
            size="small"
            class="common-model-config-input-number w-[90px]!"
          />
        </div>

        <div class="flex h-[34px] items-center justify-between" :class="isEnLanguage ? 'mb-3.5' : 'mb-2.5'">
          <div class="flex items-center" :style="{ width: sliderLabelWidth }">
            <span>
              {{ t('personal_space_module.agent_module.agent_setting_module.agent_config_module.communication_turn') }}
            </span>
            <NPopover trigger="hover">
              <template #trigger>
                <Help
                  theme="outline"
                  size="15"
                  fill="#333"
                  :stroke-width="3"
                  class="ml-1 cursor-pointer text-base text-[#999] outline-none"
                />
              </template>
              <span class="text-xs">
                {{
                  t(
                    'personal_space_module.agent_module.agent_setting_module.agent_config_module.communication_turn_popover_message',
                  )
                }}
              </span>
            </NPopover>
          </div>

          <div class="mx-5 flex flex-1">
            <NSlider
              v-model:value="commModelConfig.communicationTurn"
              :default-value="3"
              :step="1"
              :min="0"
              :max="100"
            />
            <span class="ml-4 w-8">{{ commModelConfig.communicationTurn }}</span>
          </div>
          <NInputNumber
            v-model:value="commModelConfig.communicationTurn"
            :step="1"
            :min="0"
            :max="100"
            size="small"
            class="common-model-config-input-number w-[90px]!"
            placeholder=""
          />
        </div>
      </div>
    </NPopover>
  </div>
</template>

<style lang="scss" scoped>
.model-select {
  :deep(.n-base-selection) {
    font-size: 12px;
    border-radius: 6px;
  }
}

.common-model-config-input-number {
  :deep(.n-input__input) {
    font-size: 12px;
  }
}
</style>
