<template>
  <Transition name="slide-up">
    <div class="input-container" :class="{ generate : !props.isGenerate }" @click="handleContainerClick">
      <div v-if="!props.isGenerate && props.type === 'Painting'" class="title">AI绘画2026</div>
      <div v-if="!props.isGenerate && props.type === 'Video'" class="title">AI视频2026</div>

      <div class="sender-top">
        <div v-if="useDisplay.Sender_variant === 'default'" class="scroll-to-bottom-text" @click.stop="handleScrollToBottom">回到底部<img src="@/assets/dialog/ArrowDown.svg"></div>

        <div v-show="showImageUploader" class="upload-img-container">
          <div class="reference-diagram">
            <ImageUploader
              v-if="props.type === 'Painting'"
              ref="referenceDiagramRef"
              v-model="referenceImages"
              :limit="imageUploadLimit"
              @open-canvas="handleOpenCanvas"
            />
            <VideoImageUploader 
              v-else-if="props.type === 'Video'" 
              ref="referenceDiagramRef" 
              v-model="referenceImages" 
              :model-type="modelType"
              :images-count="modelDisplayConfig?.display?.images || 1" 
            />
          </div>
        </div>
      </div>

      <Sender :key="useDisplay.Sender_variant" v-model="prompt" :variant="useDisplay.Sender_variant" :placeholder="promptPlaceholder" :submit-btn-disabled="isgerenate.value" :auto-size="autoSizeConfig">
        <template #prefix>
          <div v-if="useDisplay.Sender_variant !== 'default' && props.type === 'Painting'" class="prefix-self-wrap">
            <paintingModel v-model="model" v-model:typeValue="modelType" />
            <template v-for="param in visibleParams" :key="param.name">
              <ProportionSelect v-if="param.ui === 'proportion'" v-model="paramValues[param.name]" :param="param" />
              <ResolutionSelect v-if="param.ui === 'resolution'" v-model="paramValues[param.name]" :param="param" />
              <SelectInput v-if="param.ui === 'select'" v-model="paramValues[param.name]" :param="param" />
              <NumberInput v-if="param.ui === 'number'" v-model="paramValues[param.name]" :param="param" />
              <SwitchInput v-if="param.ui === 'switch'" v-model="paramValues[param.name]" :param="param" />
            </template>
          </div>

          <div v-if="useDisplay.Sender_variant !== 'default' && props.type === 'Video'" class="prefix-self-wrap">
            <Pattern v-model="videoPattern" />
            <videoModel v-model="model" v-model:typeValue="modelType" :video-pattern="videoPattern" />
            
            <videoProportion 
              v-model="proportion" 
              v-model:resolution="resolution" 
              :proportion-options="proportionOptions"
              :resolution-options="resolutionOptions"
            />
            <Time v-model="duration" :options="durationOptions" />
          </div>
        </template>

        <template #action-list>
          <div style="display: flex; align-items: center; gap: 8px; height: 100%;">
            <el-button v-if="isgerenate" round color="#626aef">
              <i-ep-loading style="animation: spin 1s linear infinite;"  />
            </el-button>
            <div v-else class="gerenate" :class="{ isprompt: prompt }" @click="handleStart">
              <img v-if="!prompt" src="@/assets/dialog/darkArrow.svg" alt="" />
              <img v-else src="@/assets/dialog/writerArrow.svg" alt="" />
              <div v-show="useDisplay.Sender_variant !== 'default'">发送</div>
            </div>
          </div>
        </template>
      </Sender>

    </div>
  </Transition>
</template>

<script setup>
import videoProportion from './proportion/video.vue'
import paintingModel from './model/painting.vue'
import videoModel from './model/video.vue'
import Pattern from './pattern/index.vue'
import ImageUploader from './imageUploader/index.vue'
import VideoImageUploader from './videoImageUploader/index.vue'
import Time from './Time/index.vue'
import ProportionSelect from './params/ProportionSelect.vue'
import ResolutionSelect from './params/ResolutionSelect.vue'
import SelectInput from './params/SelectInput.vue'
import NumberInput from './params/NumberInput.vue'
import SwitchInput from './params/SwitchInput.vue'
import { Sender } from 'vue-element-plus-x'
import { useDisplayStore } from '@/stores'
import { generate } from '@/utils/websocket'
import { useRouter } from 'vue-router'
import { getModelId, fetchPlatformModels, getPlatformCode } from '@/utils/modelApi'
import { fetchModelConfig } from '@/utils/modelConfig'
import { getModelConfig } from '@/config/models/index.js'

const props = defineProps({
  isGenerate: {
    type: Boolean,
    default: false
  },
  generate: {
    type: Boolean,
    default: false
  },
  type: {
    type: String,
    default: 'Painting'
  }
})

const router = useRouter()
const useDisplay = useDisplayStore()
const isgerenate = ref(false)

const model = ref() // 模型
const modelType = ref('text')

// 当前模型配置
const modelConfig = computed(() => {
  return props.type === 'Painting' ? getModelConfig(model.value) : null
})

// 模型参数值
const paramValues = reactive({})

// 同步模型默认值到 paramValues
watch(modelConfig, (config) => {
  if (!config) return
  config.params.forEach(p => {
    if (!(p.name in paramValues)) {
      paramValues[p.name] = p.default ?? ''
    }
  })
}, { immediate: true })

// 需要显示的参数控件（排除 textarea 和 imageUpload 类型，由 Sender 和独立上传组件处理）
const visibleParams = computed(() => {
  if (!modelConfig.value) return []
  return modelConfig.value.params.filter(p => {
    // 条件显示
    if (p.showWhen) {
      for (const [key, val] of Object.entries(p.showWhen)) {
        if (paramValues[key] !== val) return false
      }
    }
    // textarea 由 Sender 承载，imageUpload 由独立上传组件处理
    return p.ui !== 'textarea' && p.ui !== 'imageUpload'
  })
})

const showImageUploader = computed(() => {
  if (props.type === 'Video') return modelType.value !== 'text'
  return modelConfig.value?.inputType === 'image' || modelConfig.value?.inputType === 'both'
})

const imageUploadLimit = computed(() => {
  if (!modelConfig.value) return 4
  const imageParam = modelConfig.value.params.find(p => p.ui === 'imageUpload')
  return imageParam?.maxCount || modelConfig.value.maxImages || 4
})

const promptPlaceholder = ref('描述你想生成的画面和动作。') // 提示词占位符

const prompt = ref('') // 提示词
const proportion = ref('16:9') // 比例（Video 用）
const resolution = ref('1k') // 分辨率（Video 用）
const referenceImages = ref([])

// 绘画
const quantity = ref(1) // 生成数量

// 视频
const duration = ref(5) // 时间
const videoPattern = ref('文生视频') // 视频模式下，默认值为'文生视频'

const resolutionOptions = ref([])
const proportionOptions = ref([])
const durationOptions = ref([])

const isInitialized = ref(false)

const autoSizeConfig = computed(() => {
  if (useDisplay.Sender_variant !== 'default') {
    return { minRows: 5, maxRows: 9 }
  } else {
    return { minRows: 1, maxRows: 1 }
  }
})

const modelDisplayConfig = ref(null)

// Painting: 从本地配置加载模型参数 schema
const loadPaintingModelConfig = (modelName) => {
  const config = getModelConfig(modelName)
  if (config?.params) {
    config.params.forEach(p => {
      if (!(p.name in paramValues)) {
        paramValues[p.name] = p.default ?? ''
      }
    })
  }
}

// Video: 从远程加载 workflow 配置（保留旧逻辑）
const loadVideoModelConfig = async (modelName, currentModelType) => {
  try {
    const config = await fetchModelConfig(props.type, modelName, currentModelType)
    modelDisplayConfig.value = config

    if (config.display) {
      const display = config.display
      if (display.promptPlaceholder) {
        promptPlaceholder.value = display.promptPlaceholder.default || '描述你想生成的画面和动作。'
      }
      if (display.prompt && !isInitialized.value) {
        prompt.value = display.prompt.default || ''
      }
      if (display.resolution) {
        resolution.value = display.resolution.default || '1k'
        resolutionOptions.value = display.resolution.options || []
      }
      if (display.proportion) {
        proportion.value = display.proportion.default || '16:9'
        proportionOptions.value = display.proportion.options || []
      }
      if (display.duration) {
        duration.value = display.duration.default || 5
        durationOptions.value = display.duration.options || []
      }
    }
    isInitialized.value = true
  } catch (error) {
    console.error('加载视频模型配置失败:', error)
  }
}

const handleStart = async () => {
  const currentType = props.type
  let currentModelType = modelType.value

  if(model.value === 'Seedance 2.0') {
    ElMessage.primary('敬请期待 Seedance 2.0')
    return
  }

  if (!props.isGenerate) {
    router.push({ name: 'home', query: { loading: false, Generate: true, type: currentType } })
  }
  if (!prompt.value) {
    // eslint-disable-next-line no-undef
    ElMessage.error('请输入提示词')
    return
  }
  if (showImageUploader.value && !referenceImages.value.length){
    ElMessage.warning('请上传图片')
    return
  }

  isgerenate.value = true
  console.log('生成开始', isgerenate.value)
  const imgs = []
  referenceImages.value.forEach((img, index) => {
    imgs.push({ name: `image_${index + 1}`, url: img.url })
  })

  // 构建模型参数（Painting 用）
  const modelParams = { ...paramValues }
  if (prompt.value) modelParams.prompt = prompt.value

  const generateData = {
    model: model.value,
    modelType: currentModelType,
    prompt: prompt.value,
    proportion: proportion.value,
    referenceImages: referenceImages.value,
    quantity: quantity.value,
    resolution: resolution.value,
    duration: duration.value,
    videoPattern: videoPattern.value,
    modelParams,
  }

  const modelId = await getModelId(currentType, model.value)

  // Painting 用新架构扁平参数，Video 保留旧 params 数组
  const isPainting = currentType === 'Painting'
  const data = {
    type: currentType,
    modelType: currentModelType,
    AIGC: currentType,
    platform: 'runninghub',
    modelName: model.value,
    modelId: modelId || '',
    modelParams: isPainting ? modelParams : {},
    params: isPainting ? [] : [
      { name: 'prompt', data: prompt.value },
      { name: 'quantity', data: quantity.value },
      { name: 'proportion', data: proportion.value },
      { name: 'resolution', data: resolution.value },
      { name: 'duration', data: duration.value },
    ],
    imgs,
    request: JSON.stringify(generateData)
  }
  await generate(data, generateData)
  console.log('生成中', isgerenate.value)
}

const fillParamsFromResult = (resultData) => {
  if (!resultData) return

  if (resultData.model !== undefined) model.value = resultData.model
  if (resultData.modelType !== undefined) modelType.value = resultData.modelType
  if (resultData.prompt !== undefined) prompt.value = resultData.prompt
  if (resultData.proportion !== undefined) proportion.value = resultData.proportion
  if (resultData.referenceImages !== undefined) referenceImages.value = resultData.referenceImages
  if (resultData.quantity !== undefined) quantity.value = resultData.quantity
  if (resultData.resolution !== undefined) resolution.value = resultData.resolution
  if (resultData.duration !== undefined) duration.value = resultData.duration
  if (resultData.videoPattern !== undefined) videoPattern.value = resultData.videoPattern
  if (resultData.modelParams !== undefined) Object.assign(paramValues, resultData.modelParams)
}

defineExpose({
  fillParamsFromResult,
  handleStart
})

const handleContainerClick = () => {
  if (useDisplay.Sender_variant === 'default') {
    useDisplay.Sender_variant = 'updown'
  }
}

const handleScrollToBottom = () => {
  console.log('点击回到底部按钮')
  useDisplay.scrollToBottom()
}

const handleOpenCanvas = (data) => {
  useDisplay.openCanvas(data)
}

watch(() => useDisplay.isSubGerenate, (newValue) => {
  console.log('生成状态', newValue)
  isgerenate.value = newValue
}, { immediate: true })

watch([() => model.value, () => modelType.value], async ([newModel, newModelType]) => {
  console.log('模型或类型改变:', newModel, newModelType)
  if (!newModel) return
  if (props.type === 'Painting') {
    loadPaintingModelConfig(newModel)
  } else {
    await loadVideoModelConfig(newModel, newModelType)
  }
})

// 预加载平台模型列表，避免首次点击"发送"时才请求接口
const prefetchModels = () => {
  const code = getPlatformCode(props.type)
  fetchPlatformModels(code)
}

watch(() => props.type, (newType) => {
  if (newType === 'Video') {
    model.value = 'LTX2.0'
  } else {
    model.value = 'flux'
  }
  prefetchModels()
}, { immediate: true })

onMounted(() => {
  prefetchModels()
})

</script>

<style lang="less" scoped>
/* 输入区域 */
.input-container {
  width: 50%;
  max-width: 880px;
  position: absolute;
  bottom: 30px;
  z-index: 100;
  left: 50%;
  transform: translateX(-50%);
  border-radius: 10px;
  transition: all 0.3s ease;
}

.sender-top {
  width: 100%;
  display: flex;
  justify-content: flex-end;
  cursor: pointer;
  transition: all 0.3s ease;
  z-index: 101;
  margin-bottom: 10px;
  position: relative;

  .scroll-to-bottom-text {
    position: absolute;
    bottom: 0;
    right: 0;
    z-index: 2;
    padding: 10px;
    border-radius: 10px;
    background-color: #F8F9FA;
    color: #666;
    font-size: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 5px;

    &:active {
      transform: scale(0.95);
    }
    &:hover {
      background-color: #F0F1F2;
    }
  }

    // 上传图片
  .upload-img-container{
    position: absolute;
    bottom: 0;
    left: 0;
    width: 80%;
    width: 100%;
    display: flex;
    justify-content: start;
    align-items: center;
    z-index: 1;
    gap: 16px;
    padding-left: 20px;

    .reference-diagram {
      display: flex;
      align-items: center;
    }
  }
}

.generate{
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  // gap: 40px;
  position: relative;
  border: none;
  box-shadow: none;
  
  :deep(.el-sender){
    border: none;
    box-shadow: none;
  }
}
.prefix-self-wrap{
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;

  img{
    height: 50px;
    border-radius: 4px;
  }
}
.title{
  background-color: #FFF;
  color: #333;
  text-align: center;
  font-family: "Alibaba PuHuiTi";
  font-size: 24px;
  font-style: normal;
  font-weight: 500;
  line-height: normal;
  margin-bottom: 106px;
}
:deep(.el-sender){
  background-color: #F5F6F7;
  border: none;
  border-radius: 20px;
}

:deep(.el-sender:focus-within){
  box-shadow: 0 0 15px 0 rgba(0, 0, 0, 0.1);
}

:deep(.el-popover.el-popper){
  border-radius: 20px;
}
// 时间选择器
.select{
  background: #ffffff;
  border-radius: 10px;
  border: 1px solid rgba(0, 0, 0, 0.10);
}
// 视频效果选择器
.upload-btn{
  display: flex;
  height: 40px;
  padding: 0 15px;
  justify-content: center;
  align-items: center;
  gap: 5px;
  border-radius: 10px;
  border: 1px solid rgba(0, 0, 0, 0.10);
  background: #ffffff;
  cursor: pointer;
  position: relative;
}
.upload-btn:hover{
  background: #E5E7EB;
}
/* 圆形按钮 */
.circle-btn {
  position: absolute;
  right: 0px;
  top: 0px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 90;
  transition: all 0.3s ease;
  color: rgb(0, 0, 0);
  font-size: 20px;

  &:hover {
    transform: scale(1.1);
    // box-shadow: 0 6px 16px rgba(98, 106, 239, 0.6);
  }

  &:active {
    transform: scale(0.95);
  }
}

/* 过渡动画 */
.slide-up-enter-active,
.slide-up-leave-active {
  transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}

.slide-up-enter-from {
  opacity: 0;
  transform: translate(-50%, 100%);
}

.slide-up-leave-to {
  opacity: 0;
  transform: translate(-50%, 100%);
}

.gerenate{
  display: inline-flex;
  height: 40px;
  padding: 0 20px;
  justify-content: center;
  align-items: center;
  gap: 5px;
  border-radius: 10px;
  background: rgba(0, 15, 51, 0.10);
  cursor: pointer;

  color: #000F33;
  text-align: center;
  font-family: "Microsoft YaHei";
  font-size: 14px;
  font-style: normal;
  font-weight: 700;
  line-height: normal;
}
.isprompt{
  color: #ffffff;
  background-color: #000F33;
}
// .gerenate:hover{
//   background: rgba(0, 15, 51, 0.20);
// }
</style>
