<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, communicationTurnOptions } from '@/data/agent-setting-data'
import { useSystemLanguageStore } from '@/store/modules/system-language'

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

const { t } = useI18n()

const props = defineProps<Props>()

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

const systemLanguageStore = useSystemLanguageStore()

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

const currentDiversityMode = ref('balance')
const modelConsumePoints = ref(props.modelPoints || 0)

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

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

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

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

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

// 模型选择项渲染
function modelListRenderTag({ option }: { option: SelectOption }) {
  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
  modelConsumePoints.value = (option.points || 0) as number
  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 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', {}, { default: () => option.label })
}

// 更新保存应用配置
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"
      :show-checkmark="false"
      :render-label="modelListRenderLabel"
      :render-tag="modelListRenderTag"
      :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 items-center" :class="isEnLanguage ? 'w-[90px]' : 'w-[84px]'">
        <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">
      <div class="mb-3 flex h-[34px] items-center justify-between">
        <div class="flex items-center" :class="isEnLanguage ? 'w-[90px]' : 'w-[84px]'">
          <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>

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

        <div class="ml-3 flex flex-1">
          <n-select
            v-model:value="modelConfig.communicationTurn"
            :show-checkmark="false"
            :disabled="!modelConfig.modelNickName"
            :options="communicationTurnOptions"
            :render-label="renderCommunicationTurnLabel"
            :render-tag="renderSelectCommunicationTurn"
            @update:value="handleUpdateAgentConfig"
          />
        </div>
      </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>

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