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

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

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

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

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

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

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

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

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

<script lang="ts">
import { defineComponent, reactive, PropType, toRefs, watchEffect } 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, widgetForm } from '../../config/element'
// import { getGenerate, saveGenerate } from '@/services/api/table/tableCreator/tableCreatorAPI'

export default defineComponent({
  name: 'ElDesignForm',
  components: {
    ElCustomHeader,
    ComponentGroup,
    CodeEditor,
    ElWidgetForm,
    ElGenerateForm,
    ElWidgetConfig,
    ElFormConfig
  },
  props: {
    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
    },
    basicFields: {
      type: Array as PropType<Array<string>>,
      default: () => [
        'input',
        'password',
        'textarea',
        'number',
        'radio',
        'checkbox',
        'time',
        'date',
        'rate',
        'select',
        'switch',
        'slider',
        'text'
      ]
    },
    advanceFields: {
      type: Array as PropType<Array<string>>,
      default: () => ['img-upload', 'richtext-editor', 'cascader']
    },
    layoutFields: {
      type: Array as PropType<Array<string>>,
      default: () => ['grid']
    }
  },
  setup(props: any, context: any) {
    const state = reactive({
      element,
      codeType: CodeType,
      widgetForm: JSON.parse(JSON.stringify(element.widgetForm)),
      widgetFormSelect: undefined,
      generateFormRef: null as any,
      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 showPreviewVisible = () => {
      state.previewVisible = true
    }

    const showGenerateJsonVisible = () => {
      state.generateJsonVisible = true
    }
    const detailJson = (Json: string) => {
      if (Json) {
        console.log('json', JSON.parse(Json));
        state.widgetForm = {}
        defaultsDeep(state.widgetForm, JSON.parse(Json))
        element.widgetForm.config = JSON.parse(Json).config
        // element.widgetForm.config
        console.log('state.widgetForm', state.widgetForm);
        console.log('element.widgetForm', element.widgetForm);
      }
    }
    // 导入json
    const handleUploadJson = () => {
      try {
        state.widgetForm.list = []
        defaultsDeep(state.widgetForm, JSON.parse(state.jsonEg))
        console.log("json1", state.widgetForm.list);

        if (state.widgetForm.list) {
          state.widgetFormSelect = state.widgetForm.list[0]
          console.log("json", state.widgetFormSelect);
        }

        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 = () => {
      state.generateFormRef.getData().then((res: any) => {
        const dataForm = {
          id: '',
          list: res,
          formid: state.widgetForm.config.formField
        }
        console.log('Object数据', dataForm);
        state.dataJsonTemplate = JSON.stringify(dataForm, null, 2)
        console.log('json数据', state.dataJsonTemplate);
        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
      state.dataCodeVisible = true
    }

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

    const handleClearable = () => {
      state.widgetForm.list = []
      defaultsDeep(
        state.widgetForm,
        JSON.parse(JSON.stringify(element.widgetForm))
      )
      state.widgetFormSelect = undefined
    }

    const handleReset = () => state.generateFormRef.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()
    return {
      state,
      ...toRefs(state),
      handleUploadJson,
      handleCopyClick,
      handleGetData,
      handleGenerateJson,
      handleGenerateJson1,
      handleGenerateCode,
      handleClearable,
      handleReset,
      getJson,
      setJson,
      getTemplate,
      clear,
      showPreviewVisible,
      showGenerateJsonVisible,
      onConfirm,
      detailJson
    }
  }
})
</script>
