<script lang="ts" setup>
import { ref, watch, onMounted, onBeforeUnmount } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import * as VueRouter from 'vue-router'
import { loadModule } from 'vue3-sfc-loader'
import * as Vue from 'vue/dist/vue.esm-bundler.js'
import { i18n } from '@/data-visualization/plugins/vue-i18n'
import * as ElementPlus from 'element-plus'
import less from 'less'
import defaultTemplate from '@/views/system/userlogin/login.vue?raw'
// import { moduleList, moduleById } from '@/api/application/module'
import { userLogin } from '@/api/data-visualization/manage/user'
import { useCache } from '@/data-visualization/hooks/web/useCache'
const route = useRoute()
const router = useRouter()
const sfcCode = ref(defaultTemplate)
const previewContainer:any = ref(null)
let prevApp:any = null
// 增强的Base64转换函数
const convertToBase64 = async (imagePath:any) => {
  try {
    // 处理路径别名
    const resolvedPath = imagePath.replace('@/', '/src/')
    const response = await fetch(resolvedPath)
    if (!response.ok) throw new Error(`图片加载失败: ${response.status}`)
    const blob = await response.blob()
    return new Promise((resolve) => {
      const reader = new FileReader()
      reader.onloadend = () => resolve(reader.result)
      reader.readAsDataURL(blob)
    })
  } catch (error:any) {
    console.error('Base64转换失败:', error.message)
    return ''
  }
}
const runCode = async () => {
  try {
    if (prevApp) {
      prevApp.unmount()
      previewContainer.value.innerHTML = ''
    }
    const options:any = {
      moduleCache: {
        vue: Vue,
        'element-plus': ElementPlus,
        'vue/dist/vue.esm-bundler.js': Vue,
        'vue-router': VueRouter,
        '@/api/data-visualization/manage/user': { userLogin },
        '@/data-visualization/hooks/web/useCache': { useCache }
      },
      getFile: async (fileName:any) => {
        if (fileName.startsWith('@/')) {
          const resolvedPath = fileName.replace('@/', '/src/')
          try {
            const response = await fetch(resolvedPath)
            return { content: await response.text() }
          } catch (e) {
            console.error(`文件加载失败: ${resolvedPath}`, e)
            return { content: '<!-- 文件加载失败 -->' }
          }
        }
        if (fileName === 'dynamic.vue') {
          let code = sfcCode.value
          // 增强的Less处理（支持scoped）
          const lessRegex = /<style\s+.*?lang="less".*?>(.*?)<\/style>/gis
          let match
          while ((match = lessRegex.exec(code)) !== null) {
            const [full, content] = match
            try {
              const { css } = await less.render(content, {
                paths: ['.'], // 设置解析路径
                filename: 'dynamic.less'
              })
              code = code.replace(full, `<style>${css}</style>`)
            } catch (e) {
              console.error('Less编译错误:', e.message)
              code = code.replace(full, `<style>/* Less Error: ${e.message} */</style>`)
            }
          }

          // 处理图片资源（增强路径处理）
          const imgRegex = /src=['"](.+?\.(png|jpg|jpeg))['"]/gi
          let imgMatch
          while ((imgMatch = imgRegex.exec(code)) !== null) {
            const [full, path] = imgMatch
            const base64 = await convertToBase64(path)
            code = code.replace(full, `src="${base64}"`)
          }
          return code
            .replace(/<\/script>/g, '<\\/script>')
            .replace(/\\\//g, '/')
        }

        // 处理外部Less文件（支持别名）
        if (fileName.endsWith('.less')) {
          const resolvedPath = fileName.replace('@/', '/src/')
          try {
            const response = await fetch(resolvedPath)
            const content = await response.text()
            const { css } = await less.render(content, { filename: fileName })
            return { content: css, mediaType: 'text/css' }
          } catch (e) {
            return { content: `/* Less Error: ${e.message} */`, mediaType: 'text/css' }
          }
        }

        return ''
      },
      addStyle: (css:any) => {
        const style = document.createElement('style')
        style.textContent = css
        document.head.appendChild(style)

      },
      compiledCache: new Map(),
      compileTemplate: true
    }
    const componentModule:any = await loadModule('dynamic.vue', options)
    const component = componentModule.default || componentModule
    const dynamicProps = ref({
      id: route.query.id,
      name: route.query.name,
      isExecuteEvent: false
    })
    // prevApp = Vue.createApp({
    //   render: () => Vue.h(component, dynamicProps.value)
    // })
    prevApp = Vue.createApp({
      render: () => Vue.h(component, {
        ...dynamicProps.value,
        router: router,
        route: route
      })
    })

    // 显式提供路由实例
    prevApp.use(router)
    prevApp.use(ElementPlus)
    prevApp.use(i18n)
    prevApp.mount(previewContainer.value)

  } catch (error:any) {
    console.error('运行时错误:', error)
    previewContainer.value.innerHTML = `
      <div class="error">
        <h3>错误</h3>
        <pre>${error.message}</pre>
      </div>
    `
  }
}
onMounted(() => {
   init()
   runCode()
})
function init() {
//   const paramss = { appId: route.query.id }
//   moduleList(paramss).then(ress => {
//     var arr = ress.data.data
//     let list: any = {}
//     arr.forEach((item: any) => {
//       if (item.type == '01' && item.node_type == '02') {
//         list = item
//       }
//     })
//     if (list.id) {
//       moduleById(list.id).then(res2 => {
//         if (res2.data.data.canvas_style_data) {
//           sfcCode.value = res2.data.data.canvas_style_data
//           runCode()
//         }
//       })
//     }else{
//       sfcCode.value = defaultTemplate
//       runCode()
//     }
//   })
}
onBeforeUnmount(() => {

});
</script>
<template>
  <div class="loginBox">
    <div ref="previewContainer" class="preview"></div>
  </div>
</template>

<style lang="less" scoped>
.loginBox {
  width: 100%;
  height: 100vh;
}
.no-login{
  width: 100%;
  height: 100vh;
  background-color: #151515;
  color: #787878;
  font-size: 20px;
  line-height: 100vh;
  text-align: center;
  font-weight: 700;
}
</style>
