<script>
import { loadModule } from 'vue3-sfc-loader/vue2'
import { VueSfcModuleCache } from '@vue2-client/utils/module-loader'

export default {
  name: 'VueSfcComponent',
  props: {
    value: {
      type: String,
      default: ''
    },
    // 配置元信息
    globalProp: {
      type: Object,
      default: () => ({
        name: 'default',
        namespaceName: 'default',
        version: Date.now()
      })
    }
  },
  data () {
    return {
      componentDefinition: null,
      loading: false,
      error: null,
      debounceTimer: null,
      injectedStyles: []
    }
  },
  computed: {
    previewStyles () {
      return {
        width: '100%',
        height: '100%',
        overflow: 'auto'
      }
    },
    virtualUrl () {
      return `${this.globalProp.name}.vue?s=${this.globalProp.namespaceName}&v=${this.globalProp.version}`
    }
  },
  watch: {
    globalProp: {
      deep: true,
      immediate: true,
      handler () {
        this.debounceLoad()
      }
    }
  },
  beforeDestroy () {
    if (this.debounceTimer) {
      clearTimeout(this.debounceTimer)
    }
    this.cleanupInjectedStyles()
  },
  methods: {
    cleanupInjectedStyles () {
      if (this.injectedStyles && this.injectedStyles.length > 0) {
        this.injectedStyles.forEach(style => {
          if (style.parentNode) {
            style.parentNode.removeChild(style)
          }
        })
        this.injectedStyles = []
      }
    },
    debounceLoad () {
      if (this.debounceTimer) {
        clearTimeout(this.debounceTimer)
      }
      this.debounceTimer = setTimeout(() => {
        this.loadSFC()
      }, 300)
    },
    async loadSFC () {
      if (!this.value || !this.value.trim()) {
        this.componentDefinition = null
        this.error = null
        this.cleanupInjectedStyles()
        return
      }

      this.loading = true
      this.error = null
      this.cleanupInjectedStyles()

      try {
        // 获取 moduleCache（从单例获取）
        const moduleCache = VueSfcModuleCache.toObject()

        // 准备编译选项
        const options = {
          moduleCache,
          getFile: this.getFile.bind(this),
          addStyle: (textContent) => {
            const style = document.createElement('style')
            style.textContent = textContent
            document.head.appendChild(style)
            this.injectedStyles.push(style)
          }
        }

        // 编译 SFC
        console.log('编译对象:', this.virtualUrl)
        const component = await loadModule(this.virtualUrl, options)

        if (component && typeof component === 'object') {
          this.componentDefinition = component
        } else {
          this.error = '组件加载失败，返回结果为空'
          this.componentDefinition = null
        }
      } catch (e) {
        console.error('[VueSfcComponent] 加载错误:', e)
        this.error = this.formatError(e)
        this.componentDefinition = null
      } finally {
        this.loading = false
      }
    },

    /**
     * getFile：返回文件内容（仅支持 virtualUrl）
     * @param {string} url - 虚拟文件 URL
     */
    getFile (url) {
      if (url.startsWith(this.virtualUrl)) {
        return {
          getContentData: () => this.value,
          type: '.vue'
        }
      }
      console.warn('[VueSfcComponent] getFile 被非 virtualUrl 路径调用:', url)
      return {
        getContentData: () => null,
        type: ''
      }
    },
    formatError (e) {
      if (e.message) {
        return e.message.replace(/https?:\/\/[^\s]+/g, '').trim() || '组件渲染失败'
      }
      if (typeof e === 'string') {
        return e
      }
      return '组件渲染失败'
    },

    refresh () {
      this.loadSFC(this.value)
    }
  },
  render (h) {
    if (this.loading) {
      return h('div', {
        class: 'vue-sfc-component',
        style: this.previewStyles
      }, [
        h('div', {
          class: 'component-loading',
          style: { display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%' }
        }, [
          h('a-spin', { props: { size: 'large' } }),
          h('span', { style: { marginLeft: '12px', color: '#666' } }, '正在编译渲染...')
        ])
      ])
    }

    if (this.error) {
      return h('div', {
        class: 'vue-sfc-component',
        style: this.previewStyles
      }, [
        h('div', {
          class: 'component-error',
          style: { padding: '16px', color: '#f5222d' }
        }, [
          h('a-icon', { props: { type: 'close-circle', theme: 'filled', style: { fontSize: '20px', marginRight: '8px' } } }),
          h('span', { style: { fontWeight: '500' } }, '渲染错误'),
          h('pre', {
            style: {
              marginTop: '8px',
              padding: '12px',
              background: '#fff2f0',
              borderRadius: '4px',
              fontSize: '12px',
              whiteSpace: 'pre-wrap',
              wordBreak: 'break-all'
            }
          }, this.error)
        ])
      ])
    }

    if (this.componentDefinition) {
      try {
        return h(this.componentDefinition, { props: this.$attrs })
      } catch (err) {
        console.error('[VueSfcComponent] 渲染错误:', err)
        return h('div', {
          class: 'vue-sfc-component',
          style: this.previewStyles
        }, [
          h('div', {
            class: 'component-error',
            style: { padding: '16px', color: '#f5222d' }
          }, '渲染组件时出错: ' + err.message)
        ])
      }
    }

    return h('div', {
      class: 'vue-sfc-component',
      style: this.previewStyles
    }, [
      h('div', {
        class: 'component-empty',
        style: { display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%', color: '#999' }
      }, [
        h('a-empty', {
          props: { description: '暂无内容，请先编写 Vue 组件代码' }
        })
      ])
    ])
  }
}
</script>

<style scoped lang="less">
.vue-sfc-component {
  background: #fff;
  border: 1px solid #e8e8e8;
  border-radius: 4px;
  overflow: hidden;
}

.component-loading,
.component-error,
.component-content,
.component-empty {
  width: 100%;
  height: 100%;
}
</style>
