<template>
  <div id="app">
    <div class="sfc-header">
      <div class="sfc-header-left">
        <!-- <div class="return-box"><img src="@/assets/newimg/u594.png" alt=""></div> -->
        <div class="sfc-header-icon"><img src="@/assets/newimg/logosmall.png" alt=""></div>
        <div class="sfc-header-title">{{ hearderName }}</div>
      </div>
    </div>
    <div class="sfc-content">
      <el-tabs v-model="activeName" type="border-card" class="demo-tabs" @tab-change="handleClick"
        style="height: calc(100vh - 100px);">
        <el-tab-pane label="代码" name="代码">
          <div style="height: calc(100vh - 215px);">
            <textarea v-model="sfcCode"></textarea>
          </div>
          <div class="sfc-content-bottom">
            <el-button type="primary" @click="importNav">导入模板</el-button>
            <el-button type="primary" @click="saveClick">保存</el-button>
          </div>
        </el-tab-pane>
        <el-tab-pane label="预览" name="预览" style="height: calc(100vh - 175px);">
          <div ref="previewContainer" class="preview"></div>
        </el-tab-pane>
      </el-tabs>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref, onMounted, reactive, nextTick } from 'vue'
import { ElIcon, ElMessage } from 'element-plus-secondary'
import { useRoute, useRouter } from 'vue-router'
import { loadModule } from 'vue3-sfc-loader'
import * as Vue from 'vue/dist/vue.esm-bundler.js'
import * as ElementPlus from 'element-plus'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import * as VueRouter from 'vue-router'
import less from 'less'
import defaultTemplate from '@/viewsnew/application/SfcEditor/NavbarEditor/Navbar.vue?raw'
import { getMenuTree } from '@/api/permission/menu'
import { moduleUpdate, moduleById } from '@/api/application/module'
import { i18n } from '@/plugins/vue-i18n'
import { useCache } from '@/hooks/web/useCache'
import 'element-plus/dist/index.css'
const route = useRoute()
const router = useRouter()
const activeName: any = ref('代码')
const hearderName: any = ref('')
const sfcCode = ref('')
const previewContainer = ref(null)
let prevApp = null
const applicationId: any = ref('')
const menuList: any = ref([])
const appname: any = ref('')
const dvId: any = ref('')
// 增强的Base64转换函数
const convertToBase64 = async (imagePath) => {
  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) {
    console.error('Base64转换失败:', error.message)
    return ''
  }
}
const runCode = async () => {
  try {
    if (prevApp) {
      prevApp.unmount()
      previewContainer.value.innerHTML = ''
    }
    const options = {
      moduleCache: {
        vue: Vue,
        'element-plus': ElementPlus,
        'vue/dist/vue.esm-bundler.js': Vue,
        'vue-router': VueRouter,
        '@/viewsnew/application/SfcEditor/NavbarEditor/assocPage.vue': Vue.defineAsyncComponent(() =>
          import('@/viewsnew/application/SfcEditor/NavbarEditor/assocPage.vue')
        ),
        '@/viewsnew/application/permissionset/index.vue': Vue.defineAsyncComponent(() =>
          import('@/viewsnew/application/permissionset/index.vue')
        ),
        '@/viewsnew/application/permissionset/user/userinfo.vue': Vue.defineAsyncComponent(() =>
          import('@/viewsnew/application/permissionset/user/userinfo.vue')
        ),
        '@/hooks/web/useCache':{useCache}
      },
      getFile: async (fileName) => {
        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) => {
        const style = document.createElement('style')
        style.textContent = css
        document.head.appendChild(style)

      },
      compiledCache: new Map(),
      compileTemplate: true
    }
    const componentModule = await loadModule('dynamic.vue', options)
    const component = componentModule.default || componentModule
    const dynamicProps = Vue.reactive({
      menuList: menuList.value,
      isFixed: false,
      projectName: appname.value,
      applicationId: applicationId.value,
      isExecuteEvent: true
    })
    prevApp = Vue.createApp({
      render: () => Vue.h(component, {
        ...dynamicProps,
        router: router,
        route: route
      })
    })
    prevApp.use(router)
    prevApp.use(route)
    prevApp.use(i18n)
    prevApp.use(ElementPlus)
    prevApp.use(ElementPlus, {
      locale: zhCn,
    })
    prevApp.mount(previewContainer.value)

  } catch (error) {
    console.error('运行时错误:', error)
    previewContainer.value.innerHTML = `
      <div class="error">
        <h3>错误</h3>
        <pre>${error.message}</pre>
      </div>
    `
  }
}
onMounted(() => {
  hearderName.value = route.query.name
  if (route.query.appId) {
    applicationId.value = route.query.appId
    appname.value = route.query.appname
    dvId.value = route.query.dvId
    getmenuinfo()
  }
})
function getmenuinfo() {
  const params = {
    appId: applicationId.value,
    name: '',
    isdisplay: ''
  }
  getMenuTree(params).then(res => {
    menuList.value = res.data
  })
  moduleById(dvId.value).then(res => {
    if (res.data.data.canvas_style_data) {
      sfcCode.value = res.data.data.canvas_style_data
    }
  })
}
function goBack() {
  router.push({
    path: '/module',
    query: {
      id: route.query.appId
    }
  })
}
function handleClick() {
  if (activeName.value == '预览') {
    runCode()
  }
}
function saveClick() {
  const params = {
    canvasStyleData: sfcCode.value,
    componentData: '',
    id: dvId.value
  }
  moduleUpdate(params).then(res => {
    if (res.data.code == '0') {
      ElMessage.success('保存成功')
    } else {
      ElMessage.error('保存失败')
    }
  })
}
function importNav() {
  sfcCode.value = defaultTemplate
}
</script>

<style scoped>
#app {
  font-family: Arial, sans-serif;
  margin: 0 auto;
  width: 100%;
  height: 100vh;
  background: rgb(21, 21, 21);
}

.sfc-header {
  width: 100%;
  height: 60px;
  background-color: #252626;
  border-bottom: 1px solid #4f5052;
  display: flex;
  align-items: center;
  color: #fff;
  padding: 0px 20px;
}

.sfc-header-left {
  display: flex;
  align-items: center;
}

.sfc-header-icon {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 36px;
  height: 36px;
  cursor: pointer;
}

.return-box {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 36px;
  height: 36px;
  cursor: pointer;
}

.return-box:hover {
  background-color: rgba(255, 255, 255, 0.1);
}

.sfc-header-title {
  font-family: 'Arial Negreta', 'Arial Normal', 'Arial';
  font-weight: 700;
  font-style: normal;
  font-size: 16px;
  color: #F2F4F5;
  padding-left: 14px;
}

.sfc-content {
  height: calc(100vh - 60px);
  padding: 10px 20px;
  color: #fff;
}

textarea {
  flex: 1;
  margin-bottom: 10px;
  font-family: Monaco, monospace;
  padding: 10px;
  background: #252626;
  width: 100%;
  height: 100%;
  color: #ffffff;
}

.sfc-content-bottom {
  margin-top: 10px;
  display: flex;
  justify-content: flex-end;
}

.preview {
  width: 100%;
  height: 100%;
}

:deep(.ed-tabs__item) {
  color: #fff !important;
  padding-right: 0px;
}

:deep(.ed-tabs__header) {
  border-bottom: 1px solid #4f5052;
}

:deep(.ed-tabs__item.is-active) {
  color: #0089ff !important;
}

:deep(.ed-tabs__active-bar) {
  background-color: #0089ff !important;
}

:deep(.ed-tabs--border-card) {
  background: rgb(21, 21, 21);
  border-color: #4f5052;
}

:deep(.ed-tabs--border-card>.ed-tabs__header) {
  background: rgb(21, 21, 21);
}

:deep(.ed-tabs--border-card>.ed-tabs__header .ed-tabs__item.is-active) {
  background: rgb(21, 21, 21);
  border-color: #4f5052;
  border-bottom: none;
}

:deep(.ed-button) {
  background-color: #0089ff;
}
</style>