<script setup lang="ts">
import { computed, h, onMounted, reactive, ref } 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, communicationTurnOptions } from '@/data/agent-setting-data'
import { fetchGetLargeModelInfo, fetchGetLargeModelList } from '@/apis/agent-application'

interface LargeModelItem {
  owner: string
  models: { modelNickName: string; points: number }[]
  icon: string
}

const { t } = useI18n()

const systemLanguageStore = useSystemLanguageStore()

let modalListOptions = reactive<SelectOption[]>([])

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

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

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

const totalConsumePoints = computed(() => (communicationTurn: number) => {
  if (!modelConsumePoints.value) {
    return t('common_module.free')
  }

  switch (communicationTurn) {
    case 1:
      return t('common_module.points_per_time', { count: (modelConsumePoints.value * 1).toFixed(1) })
    case 5:
      return t('common_module.points_per_time', { count: (modelConsumePoints.value * 1).toFixed(1) })
    case 10:
      return t('common_module.points_per_time', { count: (modelConsumePoints.value * 2).toFixed(1) })
    case 15:
      return t('common_module.points_per_time', { count: (modelConsumePoints.value * 3).toFixed(1) })
  }

  return t('common_module.points_per_time', { count: modelConsumePoints.value.toFixed(1) })
})

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<LargeModelItem[]>()

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

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

  if (res.code === 0) {
    currentLargeModelIcon.value = res.data.icon
    modelConsumePoints.value = res.data.models?.[0].points || 0
  }
}

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

function handleDiversityModeChange(diversityModeItem: DiversityModeItem) {
  const { value, topP, temperature } = diversityModeItem
  currentDiversityMode.value = value
  commModelConfig.value.topP = topP
  commModelConfig.value.temperature = temperature
}

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

  return [
    h('div', { class: 'flex items-center w-full' }, [
      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 }),
    ]),
    h(
      'span',
      { class: 'text-[12px] text-[#0B7DFF]' },
      {
        default: () =>
          option.points
            ? t('common_module.points_per_time', { count: (option.points as number).toFixed(1) })
            : t('common_module.free'),
      },
    ),
  ]
}

// 模型选择项渲染
function modalListRenderTag({ option }: { option: SelectOption }) {
  return h('div', { class: 'flex justify-between' }, [
    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 renderCommunicationTurnLabel(option: SelectOption) {
  return h('div', { class: 'flex justify-between w-full text-xs' }, [
    h('span', {}, option.label as string),
    h('span', { class: 'text-[#0B7DFF]' }, totalConsumePoints.value(option.value as number)),
  ])
}

// 轮次选择项渲染
function renderSelectCommunicationTurn({ option }: { option: SelectOption }) {
  return h('span', { class: 'text-xs' }, { default: () => option.label })
}
</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"
        :show-checkmark="false"
        :render-label="modalListRenderLabel"
        :render-tag="modalListRenderTag"
        @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="ml-5 flex flex-1">
            <n-select
              v-model:value="commModelConfig.communicationTurn"
              :show-checkmark="false"
              :options="communicationTurnOptions"
              :render-label="renderCommunicationTurnLabel"
              :render-tag="renderSelectCommunicationTurn"
            />
          </div>
        </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>

<style lang="scss">
.n-base-select-option__content {
  display: flex;
  align-items: center;
  width: 100%;
}
</style>
