<template>
  <div v-if="state.isShowSearch" class="ai-float-window ai-float-fullscreen">
    <div class="ai-float-main">
      <div v-if="props.isLeft" class="ai-float-left">
        <iframe
          ref="iframeRef"
          :src="iframeSrc"
          class="ai-left-iframe"
          @load="onIframeLoad"
        />
      </div>
      <div class="ai-float-right" ref="rightPaneRef">
        <div class="ai-float-header" @mousedown="onDragStart">
          <span>AI智能填报助手</span>
          <el-icon class="ai-float-close" @click="close"><Close /></el-icon>
        </div>
        <div class="ai-float-form-list ai-float-scroll">
          <div class="ai-float-welcome">👋 欢迎使用AI智能填报助手</div>
          <div class="form-list-title">请选择需要填报的表单：</div>
          <!-- 加载状态 -->
          <div v-if="formsLoading" class="loading-container">
            <el-icon class="is-loading"><Loading /></el-icon>
            <span>加载表单中...</span>
          </div>
          <!-- 表单列表 -->
          <div v-else class="form-list">
            <el-tag
              v-for="aiFormSetting in aiFormSettingList"
              :key="aiFormSetting.formSettingId"
              :type="aiFormSetting.formSettingId === selectedFormSettingId ? 'success' : 'info'"
              class="form-tag"
              @click="selectForm(aiFormSetting)"
              effect="dark"
            >
              {{ aiFormSetting.formName }}
            </el-tag>
            <el-button v-if="aiFormSettingList.length > 5" type="text" class="more-btn" @click="showMore = !showMore">更多</el-button>
          </div>
          <el-dialog v-model="showMore" title="选择其他表单" width="400px" @close="moreFilterText = ''">
            <el-input
              v-model="moreFilterText"
              placeholder="输入表单名称过滤"
              clearable
              style="margin-bottom: 12px;"
            />
            <el-scrollbar style="max-height:300px;">
              <el-tag
                v-for="form in filteredForms"
                :key="form.formSettingId"
                :type="form.formSettingId === selectedFormSettingId ? 'success' : 'info'"
                class="form-tag"
                style="margin-bottom: 8px;"
                @click="selectForm(form); showMore = false"
                effect="dark"
              >
                {{ form.formName }}
              </el-tag>
            </el-scrollbar>
          </el-dialog>
        </div>
        <!-- 聊天区始终渲染，内容为空时不显示消息 -->
        <div class="ai-float-chat-list" ref="chatListRef">
          <div v-for="(msg, idx) in chatList" :key="idx" :class="['ai-float-chat-item', msg.from === 'ai' ? 'ai-chat-ai' : 'ai-chat-user']">
            <template v-if="msg.from === 'ai'">
              <div class="ai-avatar">🤖</div>
              <div class="ai-float-chat-bubble ai-float-chat-bubble-ai">
                <div v-if="msg.type === 'select' && msg.selectLists">
                  <div class="ai-select-title" style="font-weight:bold; margin-bottom:8px;">{{ msg.text }}</div>
                  <div class="ai-select-lists">
                    <div v-for="(list, lidx) in msg.selectLists" :key="lidx" class="ai-select-list-block">
                      <div class="ai-select-list-title">{{ list.title }}</div>
                      <div class="ai-select-options">
                        <el-button v-for="opt in list.options.slice(0,4)" :key="opt" size="small" @click="() => handleSelectOption(opt)" :type="selectedOption === opt ? 'primary' : 'default'">{{ opt }}</el-button>
                        <el-button v-if="list.options.length > 4" size="small" type="primary" link @click="() => openSelectDialog(list)">更多</el-button>
                      </div>
                    </div>
                  </div>
                </div>
                <div v-else v-html="formatMsg(msg.text)"></div>
              </div>
            </template>
            <template v-else>
              <div class="ai-float-chat-bubble-user-wrap">
                <div class="ai-float-chat-bubble" v-html="formatMsg(msg.text)"></div>
                <div class="ai-avatar ai-avatar-user">👤</div>
              </div>
            </template>
          </div>
        </div>
        <el-dialog v-model="selectDialog" title="更多选项" width="400px" @close="selectDialogFilterText = ''">
          <div v-if="selectDialogList">
            <div class="ai-select-title">{{ selectDialogList.title }}</div>
            <el-input
              v-model="selectDialogFilterText"
              placeholder="输入关键字过滤"
              clearable
              style="margin-bottom: 12px;"
            />
            <div class="ai-select-options">
              <el-button v-for="opt in filteredSelectDialogOptions" :key="opt" size="small" @click="() => handleSelectOption(opt)" :type="selectedOption === opt ? 'primary' : 'default'">{{ opt }}</el-button>
            </div>
          </div>
        </el-dialog>
        <div class="ai-float-input-area">
          <div v-if="selectedFormSettingId" class="ai-float-form-info">
            <div class="form-info-title">当前表单：{{ aiFormSettingList.find(f => f.formSettingId === selectedFormSettingId)?.formName }}</div>
            <div class="form-info-tip">请根据下方示例填写内容，AI将自动为您智能填报。</div>
            <div class="form-info-example">示例：如"申请10个物料A用于生产线1，计划交付日期为2024-07-01"</div>
          </div>
          <div class="ai-float-input-row">
            <el-input
              v-model="inputValue"
              type="textarea"
              :rows="2"
              :autosize="{ minRows: 2, maxRows: 6 }"
              :maxlength="300"
              :disabled="!selectedFormSettingId || aiThinking"
              placeholder="请输入内容（最多300字符）"
              @keydown="onInputKeydown"
              class="ai-float-input"
              show-word-limit
              clearable
            />
            <el-button
              class="ai-float-send-btn"
              :disabled="!canSend || aiThinking"
              icon="el-icon-s-promotion"
              @click="() => handleSend()"
              circle
              type="primary"
            />
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted, onBeforeUnmount, nextTick, shallowRef, watch, getCurrentInstance } from 'vue'
import { ElMessage } from 'element-plus'
import { Close, Loading } from '@element-plus/icons-vue'
import type { ComponentInternalInstance } from 'vue'
import router from "@/router"

import {getAiFormSettingList} from '@/api/ai/base/aiFormSetting';
import {AiFormSettingVO} from '@/api/ai/base/aiFormSetting/types';

const props = defineProps({
  isLeft: Boolean
});
const { proxy } = getCurrentInstance() as ComponentInternalInstance;

// 用reactive对象直接定义state
const state = reactive({
  isShowSearch: false,
  menuQuery: '',
  menuList: []
});


const aiFormSettingList = ref<AiFormSettingVO[]>([])
const selectedFormSettingId = ref<number | null>(null)
const formsLoading = ref(false)

// 搜索弹窗打开
const openSearch = () => {
  state.menuQuery = '';
  state.isShowSearch = true;
  nextTick(() => {
    setTimeout(() => {
      // layoutMenuAutocompleteRef.value.focus();
    });
  });
};
// 搜索弹窗关闭
const closeSearch = () => {
  state.isShowSearch = false;
};

// 暴露变量
defineExpose({
  openSearch
});

// 动态生成的表单页面映射
const formPageMap = ref<Record<number, { loader: () => Promise<any>, props: any }>>({})

// 加载表单数据并初始化formPageMap
const loadForms = async () => {
  try {
    formsLoading.value = true
    const res = await getAiFormSettingList({})
    if (res.code === 200) {
      aiFormSettingList.value = res.data || []
      // 动态生成formPageMap
      // initFormPageMap()
    }
  } catch (error) {
    console.error('加载表单数据失败:', error)
    ElMessage.error('加载表单数据失败')
  } finally {
    formsLoading.value = false
  }
}

// 动态生成formPageMap
const initFormPageMap = () => {
  const newFormPageMap: Record<number, { loader: () => Promise<any>, props: any }> = {}

  aiFormSettingList.value.forEach(form => {
    // 根据表单的formPath字段动态生成组件路径
    const componentPath = `../../../views/${form.formPath}.vue`
    // 创建动态加载器
    const loader = () => {
      try {

        // const dd = new URL(`@/views/system/user/index.vue`, import.meta.url).href;
        // alert("--"+componentPath.replace('@/', '../../../'))
        // return import(`${componentPathUrl}`);
        // localStorage.setItem("previousRoute", "ai");
        return import(/* @vite-ignore */ componentPath)
      } catch (error) {
        console.error(`加载组件失败: ${componentPath}`, error)
        // 如果加载失败，返回默认组件
        // return import('@/views/ai/skill/aiForm/index.vue')
      }
    }

    // 根据表单类型设置不同的props
    const props = getFormProps(form)

    newFormPageMap[form.formSettingId] = { loader, props }
  })

  formPageMap.value = newFormPageMap
}

function selectForm(aiFormSetting: AiFormSettingVO) {
  selectedFormSettingId.value = aiFormSetting.formSettingId
  console.log('选择表单:', aiFormSetting.formPath)
}


// 根据表单信息生成props
const getFormProps = (form: AiFormSettingVO) => {
  const baseProps = {
    formSettingId: form.formSettingId,
    formName: form.formName,
    formType: form.formType,
    userInput: ''
  }

  // 根据表单类型添加特定props
  switch (form.formType) {
    case 'system':
      return { ...baseProps, pageNum: 1, pageSize: 10 }
    case 'ai':
      return { ...baseProps, aiType: 'form', mode: 'edit' }
    default:
      return baseProps
  }
}

const showMore = ref(false)
const inputValue = ref('')
const canSend = computed(() => selectedFormSettingId.value && inputValue.value.trim().length > 0)

// 新增：更多弹窗过滤输入
const moreFilterText = ref('')
const filteredForms = computed(() =>
  aiFormSettingList.value.filter(form => form.formName.includes(moreFilterText.value))
)

type ChatSelectList = { title: string, options: string[] }
type ChatMsg = { text: string, from: 'user' | 'ai', type?: 'text' | 'select', selectLists?: ChatSelectList[] }
const chatList = ref<ChatMsg[]>([])
const selectDialog = ref(false)
const selectDialogList = ref<ChatSelectList|null>(null)
const aiThinking = ref(false)
const chatListRef = ref<HTMLElement | null>(null)
const rightPaneRef = ref<HTMLElement | null>(null)
const selectedOption = ref('')
const iframeRef = ref<HTMLIFrameElement | null>(null)
const iframeSrc = ref<string>('')

// 新增：AI更多弹窗过滤输入
const selectDialogFilterText = ref('')
const filteredSelectDialogOptions = computed(() =>
  selectDialogList.value
    ? selectDialogList.value.options.filter(opt => opt.includes(selectDialogFilterText.value))
    : []
)

// 悬浮窗拖拽
const floatStyle = reactive({
  left: '',
  top: '0px',
  width: '440px',
  height: '100vh',
  zIndex: 9999,
  position: 'fixed' as const,
})

// 默认显示在最右侧
onMounted(() => {
  // 放宽对话框焦点陷阱以允许右侧输入
  document.addEventListener('focusin', focusTrapBypass, true);
  floatStyle.left = (window.innerWidth - 440) + 'px';
  floatStyle.top = '0px';
  // 加载表单数据
})





let drag = false
let offsetX = 0
let offsetY = 0
function onDragStart(e: MouseEvent) {
  drag = true
  offsetX = e.clientX - parseInt(floatStyle.left)
  offsetY = e.clientY - parseInt(floatStyle.top)
  document.addEventListener('mousemove', onDragging)
  document.addEventListener('mouseup', onDragEnd)
}
function onDragging(e: MouseEvent) {
  if (!drag) return
  let newLeft = e.clientX - offsetX
  let newTop = e.clientY - offsetY
  // 限制在屏幕内
  newLeft = Math.max(0, Math.min(newLeft, window.innerWidth - 440))
  newTop = Math.max(0, Math.min(newTop, window.innerHeight - 100))
  floatStyle.left = newLeft + 'px'
  floatStyle.top = newTop + 'px'
}
function onDragEnd() {
  drag = false
  document.removeEventListener('mousemove', onDragging)
  document.removeEventListener('mouseup', onDragEnd)
}

function focusTrapBypass(e: FocusEvent) {
  const overlay = document.querySelector('.el-overlay') as HTMLElement | null
  const dialog = overlay?.querySelector('.el-dialog') as HTMLElement | null
  if (!overlay || !dialog) return
  const rightPane = rightPaneRef.value
  if (!rightPane) return
  // 如果焦点转移到右侧面板内，允许通过
  if (rightPane.contains(e.target as Node)) {
    // 取消Element Plus 可能的焦点回滚
    e.stopPropagation()
  }
}

onBeforeUnmount(() => {
  document.removeEventListener('mousemove', onDragging)
  document.removeEventListener('mouseup', onDragEnd)
  document.removeEventListener('focusin', focusTrapBypass, true)
})



function scrollToBottom() {
  nextTick(() => {
    if (chatListRef.value) {
      chatListRef.value.scrollTop = chatListRef.value.scrollHeight
    }
  })
}

function onIframeLoad() {
  // 载入完成后同步一次参数
  const form = aiFormSettingList.value.find(f => f.formSettingId === selectedFormSettingId.value)
  if (form) {
    alert(233333)
    console.log('iframe 加载完成，开始传参');
    sendToIframe({ type: 'init', payload:` getFormProps(form)` })
  }
}

function sendToIframe(message: any) {
  const iframeEl = iframeRef.value
  try {
    iframeEl?.contentWindow?.postMessage(message, '*')
  } catch (e) {
    // 忽略跨域异常
    console.error('传参失败:', e);
  }
}

function handleSend(selectedText?: string) {
  if ((!canSend.value || aiThinking.value) && !selectedText) return
  const userMsg = selectedText || inputValue.value
  chatList.value.push({ text: userMsg, from: 'user', type: 'text' })
  // 同步用户输入到 iframe 页面
  sendToIframe({ type: 'userInput', payload: userMsg })
  scrollToBottom()
  aiThinking.value = true
  inputValue.value = 'AI思考中....'
  setTimeout(() => {
    inputValue.value = ''
    aiThinking.value = false
    // 固定AI回复+多个选择列表
    chatList.value.push({
      text: '操作成功，请选择相关信息：',
      from: 'ai',
      type: 'select',
      selectLists: [
        { title: '物料信息', options: ['物料A', '物料B', '物料C', '物料D', '物料E', '物料F'] },
        { title: 'BOM信息', options: ['BOM-001', 'BOM-002', 'BOM-003', 'BOM-004', 'BOM-005'] }
      ]
    })
    scrollToBottom()
  }, 2000)
}

// 保证所有方法直接在<script setup>中定义
function handleSelectOption(opt: string) {
  selectedOption.value = opt
}
function openSelectDialog(list: ChatSelectList) {
  selectDialogList.value = list
  selectDialog.value = true
}
function formatMsg(text: string) {
  // 转换换行符为<br>，并做简单转义防XSS
  return text
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/\n/g, '<br>')
}
function onInputKeydown(e: KeyboardEvent) {
  if (e.key === 'Enter' && !e.shiftKey) {
    e.preventDefault();
    handleSend();
  }
  // shift+enter 默认换行，无需处理
}

function close() {
  state.isShowSearch = false
}








const currentComponent = shallowRef(null)
const currentProps = ref({})

function buildIframeSrc(form: AiFormSettingVO) {
  try {
    const resolved = router.resolve({ path: `/${form.formPath}` })
    resolved.href += "?ai=true"
    return resolved.href
  } catch (e) {
    return `/${form.formPath}`
  }
}

watch(selectedFormSettingId, async (formSettingId) => {
  const form = aiFormSettingList.value.find(f => f.formSettingId === formSettingId)
  if (form) {
    iframeSrc.value = buildIframeSrc(form)
    // alert(iframeSrc.value)
    // 同时准备将初始参数 postMessage 给 iframe
    // 使用 nextTick 确保 iframe 已更新
    // nextTick(() => {
    //   sendToIframe({ type: 'init', payload: 'getFormProps(form)' })
    //   alert(12)
    // })
  }
})

watch(state, (newVal) => {
  if (newVal.isShowSearch) {
    loadForms()
  }

});
</script>

<style scoped>
.ai-float-fullscreen {
  position: fixed;
  left: 0;
  top: 0;
  width: 100vw;
  height: 100vh;
  z-index: 2005;
  background: #fff;
  border-radius: 0;
  box-shadow: none;
}
/* 让全局弹窗显示在浮窗之上 */
:deep(.el-overlay) {
  z-index: 3000 !important;
}
:deep(.el-overlay .el-dialog) {
  z-index: 3001 !important;
}
/* 允许遮罩不拦截右侧输入：只有遮罩变为不拦截，弹窗可交互 */
:deep(.el-overlay) {
  pointer-events: none;
}
:deep(.el-overlay .el-dialog),
:deep(.el-overlay .el-message-box),
:deep(.el-overlay .el-drawer),
:deep(.el-overlay .el-popup) {
  pointer-events: auto;
}
.ai-float-window {
  box-shadow: 0 4px 24px rgba(0,0,0,0.18);
  background: #fff;
  border-radius: 12px;
  padding: 0 0 16px 0;
  min-height: 220px;
  user-select: none;
  display: flex;
  flex-direction: column;
  height: 100vh;
  width: 90vw;
  right: 0;
  left: auto;
  top: 0;
  position: fixed;
  z-index: 2005;
}
.ai-float-main {
  display: flex;
  height: 100vh;
}
.ai-float-left {
  flex: 7 7 0;
  min-width: 400px;
  background: #f7f8fa;
  border-right: 1px solid #e0e7ef;
  overflow: hidden;
  height: 100%;
}
.ai-left-iframe {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}
.ai-float-right {
  flex: 3 3 0;
  min-width: 260px;
  height: 100%;
  display: flex;
  flex-direction: column;
}
.ai-float-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 18px;
  font-weight: bold;
  padding: 16px 24px 8px 24px;
  cursor: move;
  border-bottom: 1px solid #f0f0f0;
}
.ai-float-welcome {
  font-size: 16px;
  color: #409eff;
  margin-bottom: 10px;
  font-weight: 500;
}
.ai-float-close {
  font-size: 20px;
  cursor: pointer;
  color: #888;
  transition: color 0.2s;
}
.ai-float-close:hover {
  color: #f56c6c;
}
.ai-float-form-list {
  padding: 16px 24px 0 24px;
  flex-shrink: 0;
  max-height: 220px;
  overflow-y: auto;
}
.form-list-title {
  font-size: 15px;
  margin-bottom: 8px;
  color: #333;
}
.form-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}
.form-tag {
  cursor: pointer;
  margin-bottom: 4px;
}
.more-btn {
  margin-left: 8px;
  font-size: 13px;
  padding: 0 4px;
}
.loading-container {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  color: #666;
  gap: 8px;
}
.ai-float-input-area {
  padding: 6px 24px 0 24px;
  flex-shrink: 0;
  height: 140px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}
.ai-float-form-info {
  margin-bottom: 8px;
  background: #f6f8fa;
  border-radius: 1px;
  padding: 10px 14px;
}
.form-info-title {
  font-weight: bold;
  color: #333;
  margin-bottom: 2px;
}
.form-info-tip {
  color: #666;
  font-size: 13px;
  margin-bottom: 2px;
}
.form-info-example {
  color: #999;
  font-size: 13px;
}
.ai-float-input-row {
  display: flex;
  align-items: flex-end;
  gap: 8px;
}
.ai-float-input {
  flex: 1 1 auto;
}
.ai-float-send-btn {
  margin-bottom: 4px;
}
.ai-float-chat-list {
  flex: 1 1 auto;
  margin: 0 24px;
  margin-top: 12px;
  margin-bottom:20px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  overflow-y: auto;
  min-height: 0;
  max-height: calc(100vh - 170px - 140px - 32px);
}
.ai-float-chat-item {
  display: flex;
  justify-content: flex-end;
  align-items: flex-end;
}
.ai-chat-ai {
  justify-content: flex-start;
}
.ai-avatar {
  width: 32px;
  height: 32px;
  background: linear-gradient(135deg, #e0e7ef 0%, #f6f8fa 100%);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  margin-right: 8px;
  box-shadow: 0 2px 8px rgba(64,158,255,0.08);
}
.ai-float-chat-bubble {
  background: linear-gradient(135deg, #409eff 0%, #6ec1ff 100%);
  color: #fff;
  border-radius: 20px 20px 4px 24px;
  padding: 12px 22px;
  max-width: 80%;
  font-size: 16px;
  word-break: break-all;
  box-shadow: 0 4px 16px rgba(64,158,255,0.13);
  line-height: 1.85;
  min-height: 36px;
  display: inline-block;
  text-shadow: 0 1px 2px rgba(0,0,0,0.08);
}
.ai-float-chat-bubble-ai {
  background: linear-gradient(135deg, #f4f4f4 0%, #e9f0fb 100%);
  color: #333;
  border-radius: 16px 16px 16px 6px;
  box-shadow: 0 2px 12px rgba(64,158,255,0.10);
  border: 1px solid #e0e7ef;
}
.ai-select-lists {
  display: flex;
  flex-direction: column;
  gap: 12px;
  align-items: stretch;
}
.ai-select-list-block {
  width: 100%;
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 0;
  margin: 0;
}
.ai-select-list-title {
  font-weight: 500;
  color: #333;
  text-align: left;
  width: 100%;
  margin: 0;
  padding: 0;
}
.ai-select-options {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
  text-align: left;
  margin: 0;
  padding: 0;
}
.ai-select-options .el-button {
  width: 100%;
  text-align: left;
  margin: 0;
  padding-left: 0 !important;
  justify-content: flex-start;
}
.el-dialog__body .ai-select-title {
  margin-bottom: 8px;
}
.el-dialog__body .ai-select-options {
  width: 100%;
  justify-content: flex-start;
  gap: 8px;
}
.ai-float-chat-bubble-user-wrap {
  display: flex;
  align-items: flex-end;
  justify-content: flex-end;
  gap: 8px;
}
.ai-avatar-user {
  background: linear-gradient(135deg, #e0e7ef 0%, #d0eaff 100%);
  color: #409eff;
}
</style>

