<template>
  <div class="fc-style">
    <el-container class="fc-container">
      <el-main class="fc-main">
        <el-container>
          <el-aside width="250px">
            <div class="components">
              <ComponentGroup title="基础字段" :list="element.basicComponents" />
              <ComponentGroup title="高级字段" :list="element.advanceComponents" />
              <ComponentGroup title="布局字段" :list="element.layoutComponents" />
            </div>
          </el-aside>
          <el-main class="center-container">
            <ElCustomHeader v-bind="props" @preview="() => (state.previewVisible = true)"
              @uploadJson="() => (state.uploadJsonVisible = true)" @generateJson="handleGenerateJson"
              @generateCode="handleGenerateCode" @clearable="handleClearable">
              <slot name="header"></slot>
            </ElCustomHeader>
            <el-main :class="{ 'widget-empty': state.widgetForm.list }">
              <ElWidgetForm ref="widgetFormRef" v-model:widgetForm="state.widgetForm"
                v-model:widgetFormSelect="state.widgetFormSelect" />
            </el-main>
          </el-main>
          <el-aside class="widget-config-container" width="300px">
            <el-container>
              <el-header>
                <div class="config-tab" :class="{ active: state.configTab === 'widget' }"
                  @click="state.configTab = 'widget'">
                  字段属性
                </div>
                <div class="config-tab" :class="{ active: state.configTab === 'form' }"
                  @click="state.configTab = 'form'">
                  表单属性
                </div>
              </el-header>
              <el-main class="config-content">
                <ElWidgetConfig v-show="state.configTab === 'widget'" v-model:select="state.widgetFormSelect" />
                <ElFormConfig v-show="state.configTab === 'form'" v-model:config="state.widgetForm.config"
                  ref="formConfigRef" />
              </el-main>
            </el-container>
          </el-aside>
        </el-container>
      </el-main>

      <el-dialog v-model="state.uploadJsonVisible" title="导入JSON" :width="800">
        <el-alert type="info" title="JSON格式如下，直接复制生成的json覆盖此处代码点击确定即可" style="margin-bottom: 10px" />
        <CodeEditor v-model:value="state.jsonEg" language="json" />
        <template #footer>
          <el-button @click="() => (state.uploadJsonVisible = false)">取消</el-button>
          <el-button type="primary" @click="handleUploadJson">导入</el-button>
        </template>
      </el-dialog>

      <el-dialog v-model="state.previewVisible" title="预览" :width="800">
        <ElGenerateForm ref="generateFormRef" v-if="state.previewVisible" :data="state.widgetForm" />
        <template #footer>
          <el-button @click="handleReset">重置</el-button>
          <el-button type="primary" @click="handleGetData">获取数据</el-button>
        </template>

        <el-dialog v-model="state.dataJsonVisible" title="获取数据" :width="800">
          <CodeEditor :value="state.dataJsonTemplate" language="json" readonly />

          <template #footer>
            <el-button @click="() => (state.dataJsonVisible = false)">取消</el-button>
            <el-button type="primary" @click="handleCopyClick(state.dataJsonTemplate)">Copy</el-button>
          </template>
        </el-dialog>
      </el-dialog>

      <el-dialog v-model="state.generateJsonVisible" title="生成JSON" :width="800">
        <CodeEditor :value="state.generateJsonTemplate" language="json" readonly />

        <template #footer>
          <el-button @click="() => (state.generateJsonVisible = false)">取消</el-button>
          <el-button type="primary" @click="onConfirm(state.generateJsonTemplate)">确认</el-button>
          <el-button type="primary" @click="handleCopyClick(state.generateJsonTemplate)">Copy</el-button>
        </template>
      </el-dialog>

      <el-dialog v-model="state.dataCodeVisible" title="生成代码" :width="800">
        <el-tabs type="card" v-model="state.codeLanguage" :tabBarStyle="{ margin: 0 }">
          <el-tab-pane label="Vue Component" :name="state.codeType.Vue">
            <CodeEditor :value="state.dataCodeTemplate" language="html" readonly />
          </el-tab-pane>
          <el-tab-pane label="HTML" :name="state.codeType.Html">
            <CodeEditor :value="state.dataCodeTemplate" language="html" readonly />
          </el-tab-pane>
        </el-tabs>

        <template #footer>
          <el-button @click="() => (state.dataCodeVisible = false)">取消</el-button>
          <el-button type="primary" @click="handleCopyClick(state.dataCodeTemplate)">Copy</el-button>
        </template>
      </el-dialog>
    </el-container>
  </div>
</template>

<script lang="ts" setup>
import { reactive, watchEffect, ref, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import { defaultsDeep } from 'lodash'
import CodeEditor from '../../components/CodeEditor.vue'
import ComponentGroup from '../../components/ComponentGroup.vue'
import ElCustomHeader from './ElCustomHeader.vue'
import ElWidgetForm from './ElWidgetForm.vue'
import ElGenerateForm from './ElGenerateForm.vue'
import ElWidgetConfig from './ElWidgetConfig.vue'
import ElFormConfig from './ElFormConfig.vue'
import { element } from '../../config'
import { copy } from '../../utils'
import { CodeType, PlatformType } from '../../enums'
import generateCode from '../../utils/generateCode'
import { WidgetForm } from '../../config/element'

const props = defineProps({
  preview: {
    type: Boolean,
    default: true
  },
  generateCode: {
    type: Boolean,
    default: true
  },
  generateJson: {
    type: Boolean,
    default: true
  },
  uploadJson: {
    type: Boolean,
    default: true
  },
  clearable: {
    type: Boolean,
    default: true
  },
  // 设置盒子的最小高度
  height: {
    type: Number,
    default: 400
  }
})

const state = reactive({
  element,
  codeType: CodeType,
  widgetForm: JSON.parse(JSON.stringify(element.widgetForm)),
  widgetFormSelect: undefined,
  configTab: 'widget',
  previewVisible: false,
  uploadJsonVisible: false,
  dataJsonVisible: false,
  dataCodeVisible: false,
  generateJsonVisible: false,
  generateCodeVisible: false,
  generateJsonTemplate: JSON.stringify(element.widgetForm, null, 2),
  generateJsonTemplate1: element.widgetForm,
  dataJsonTemplate: '',
  dataCodeTemplate: '',
  codeLanguage: CodeType.Vue,
  jsonEg: JSON.stringify(element.widgetForm, null, 2),
  loading: false
})

const formConfigRef = ref()
const generateFormRef = ref()

const showPreviewVisible = () => {
  state.previewVisible = true
}

const showGenerateJsonVisible = () => {
  state.generateJsonVisible = true
}
const detailJson = (Json: string) => {
  if (Json) {
    state.widgetForm = {}
    nextTick(() => defaultsDeep(state.widgetForm, JSON.parse(Json))) // 加载速度要比下面快
    formConfigRef.value.updataNewData(JSON.parse(Json))
  }
}
// 导入json
const handleUploadJson = () => {
  try {
    state.widgetForm.list = []
    defaultsDeep(state.widgetForm, JSON.parse(state.jsonEg))

    if (state.widgetForm.list) state.widgetFormSelect = state.widgetForm.list[0]

    state.uploadJsonVisible = false
    ElMessage.success('上传成功')
  } catch (error) {
    ElMessage.error('上传失败')
  }
}
// 确认
const onConfirm = (text: string) => {
  state.generateJsonVisible = false
}
const handleCopyClick = (text: string) => {
  copy(text)
  ElMessage.success('Copy成功')
}
// 获取数据
const handleGetData = () => {
  generateFormRef.value.getData().then((res: any) => {
    const dataForm = {
      id: '',
      list: res,
      formid: state.widgetForm.config.formField
    }
    state.dataJsonTemplate = JSON.stringify(dataForm, null, 2)
    state.dataJsonVisible = true
  })
}

// 生成json代码
const handleGenerateJson = () => {
  (state.generateJsonTemplate = JSON.stringify(
    state.widgetForm,
    null,
    2
  )) && (state.generateJsonVisible = true)
}

// 生成json代码
const handleGenerateJson1 = () => {
  (state.generateJsonTemplate = JSON.stringify(
    state.widgetForm,
    null,
    2
  ))
}

// 生成代码
const handleGenerateCode = () => {
  state.codeLanguage = CodeType.Vue // vue
  state.dataCodeVisible = true
}

watchEffect(() => {
  if (state.dataCodeVisible) {
    state.dataCodeTemplate = generateCode(
      state.widgetForm,
      state.codeLanguage,
      PlatformType.Element
    )!
  }
})

// 清空数据
const handleClearable = () => {
  state.widgetForm.list = []
  nextTick(() => defaultsDeep(
    state.widgetForm,
    JSON.parse(JSON.stringify(element.widgetForm))
  ))
  state.widgetFormSelect = undefined
}

const handleReset = () => generateFormRef.value.reset()

const getJson = () => state.widgetForm

const setJson = (json: WidgetForm) => {
  state.widgetForm.list = []
  defaultsDeep(state.widgetForm, json)
  if (json.list.length) {
    state.widgetFormSelect = json.list[0]
  }
}

const getTemplate = (codeType: CodeType) =>
  generateCode(state.widgetForm, codeType, PlatformType.Element)

// 使用最新数据
const clear = () => {
  handleClearable()
  formConfigRef.value.updataNewData(element.widgetForm)
}

defineExpose({
  state,
  handleClearable,
  detailJson,
  clear
})
</script>

<style lang="scss" scoped>
</style>
