<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" />
            <paintingProportion
              v-if="showProportion"
              v-model="proportion"
              v-model:resolution="resolution"
              v-model:width="customWidth"
              v-model:height="customHight"
              :proportion-options="paintingProportionOpts"
              :resolution-options="paintingResolutionOpts"
              :allow-custom="hasCustomSize"
            />
            <Quantity v-if="showQuantity" v-model="quantity" :max="quantityMax" />
          </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 paintingProportion from './proportion/painting.vue'
import Quantity from './quantity/index.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({})

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

// 模型是否有数量参数（imageNum），或生成类模型显示张数选择
const showQuantity = computed(() => {
  if (props.type !== 'Painting') return false
  const qtyParam = modelConfig.value?.params?.find(p => p.ui === 'quantity')
  if (qtyParam) return true
  return modelType.value === 'text' && !modelConfig.value?.params?.find(p => p.name === 'forceSingle')
})

// 模型是否使用 proportion 组件（aspectRatio 参数）
const showProportion = computed(() => {
  return !!modelConfig.value?.params?.find(p => p.ui === 'proportion')
})

// 模型是否支持自定义尺寸（aspectRatio 选项含 'custom'）
const hasCustomSize = computed(() => {
  const ratioParam = modelConfig.value?.params?.find(p => p.ui === 'proportion')
  return ratioParam?.options?.includes('custom') || false
})

// 从模型配置派生比例选项，回退到默认值
const paintingProportionOpts = computed(() => {
  const ratioParam = modelConfig.value?.params?.find(p => p.ui === 'proportion')
  if (ratioParam?.options) {
    return ratioParam.options
      .filter(o => o !== 'custom')
      .map(o => ({ value: o, label: o }))
  }
  return proportionOptions.value
})

// 从模型配置派生分辨率选项（仅模型有 resolution 参数时显示）
const paintingResolutionOpts = computed(() => {
  const resParam = modelConfig.value?.params?.find(p => p.ui === 'resolution')
  if (resParam?.options) {
    return resParam.options.map(o => ({ value: o, label: o.toUpperCase() }))
  }
  return []
})

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 customWidth = ref(1024) // 自定义宽度
const customHight = ref(1024) // 自定义高度

const quantityMax = computed(() => {
  const qtyParam = modelConfig.value?.params?.find(p => p.ui === 'quantity')
  if (qtyParam?.options?.length) return Math.max(...qtyParam.options)
  return 4
})

// 同步模型默认值到 paramValues 和 UI refs
watch(modelConfig, (config) => {
  if (!config) return
  config.params.forEach(p => {
    if (!(p.name in paramValues)) {
      if (p.name === 'outputFormat') {
        paramValues[p.name] = 'png'
      } else {
        paramValues[p.name] = p.default ?? ''
      }
    }
  })
  // 同步默认值到 UI 控件
  const ratioParam = config.params.find(p => p.ui === 'proportion')
  if (ratioParam) proportion.value = ratioParam.default || '1:1'
  const resParam = config.params.find(p => p.ui === 'resolution')
  if (resParam) resolution.value = resParam.default || '2k'
  const qtyParam = config.params.find(p => p.ui === 'quantity')
  if (qtyParam) quantity.value = qtyParam.default || 1
  const cwParam = config.params.find(p => p.name === 'customWidth')
  if (cwParam) customWidth.value = cwParam.default || 1024
  const chParam = config.params.find(p => p.name === 'customHight')
  if (chParam) customHight.value = chParam.default || 1024
}, { immediate: true })

// 反向同步：UI refs → paramValues
watch(proportion, (val) => {
  const p = modelConfig.value?.params?.find(param => param.ui === 'proportion')
  if (p) paramValues[p.name] = val
})
watch(resolution, (val) => {
  const p = modelConfig.value?.params?.find(param => param.ui === 'resolution')
  if (p) paramValues[p.name] = val
})
watch(quantity, (val) => {
  const p = modelConfig.value?.params?.find(param => param.ui === 'quantity')
  if (p) paramValues[p.name] = val
})
watch(customWidth, (val) => {
  if (modelConfig.value?.params?.find(p => p.name === 'customWidth')) {
    paramValues.customWidth = val
  }
})
watch(customHight, (val) => {
  if (modelConfig.value?.params?.find(p => p.name === 'customHight')) {
    paramValues.customHight = val
  }
})

// 同步参考图片到 paramValues
watch(referenceImages, (imgs) => {
  const imageParam = modelConfig.value?.params?.find(p => p.ui === 'imageUpload')
  if (imageParam) {
    paramValues[imageParam.name] = imgs.map(img => img.url)
  }
}, { deep: true })

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

const resolutionOptions = ref([
  { value: '1k', label: '标清 1K' },
  { value: '2k', label: '高清 2K' },
  { value: '4k', label: '超清 4K' },
])
const proportionOptions = ref([
  { value: '智能', label: '智能' },
  { value: '21:9', label: '21:9' },
  { value: '16:9', label: '16:9' },
  { value: '4:3', label: '4:3' },
  { value: '1:1', label: '1:1' },
  { value: '3:4', label: '3:4' },
  { value: '9:16', label: '9:16' },
])
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)

// 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,
    customWidth: customWidth.value,
    customHight: customHight.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.customWidth !== undefined) customWidth.value = resultData.customWidth
  if (resultData.customHight !== undefined) customHight.value = resultData.customHight
  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') {
    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 })

</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>
