<template>
	<a-drawer v-model:open="visible" title="生成结果" width="50%" :closable="false">
		<a-tabs v-model:active-key="activeKey">
			<template #rightExtra>
				<a-button type="primary" size="small" @click="copy(code)">
					<template #icon>
						<icon-font type="icon-copy"></icon-font>
					</template>
					复制
				</a-button>
			</template>
			<a-tab-pane key="form" tab="form.ts"></a-tab-pane>
			<a-tab-pane key="render" tab="form.vue"></a-tab-pane>
			<a-tab-pane key="modal" tab="modal.vue"></a-tab-pane>
		</a-tabs>
		<codemirror
			v-model="code"
			disabled
			:style="{ height: 'calc(100vh - 175px)' }"
			:autofocus="true"
			:indent-with-tab="true"
			:tab-size="2"
			:extensions="extensions"
		/>
	</a-drawer>
</template>
<script lang="ts" setup>
	import { PropType, computed, ref, toRefs, watch } from 'vue'
	import { Codemirror } from 'vue-codemirror'
	import { java } from '@codemirror/lang-java'
	import { javascript } from '@codemirror/lang-javascript'
	import { oneDark } from '@codemirror/theme-one-dark'
	import XEUtils from 'xe-utils'
	import { notification } from 'ant-design-vue'
	import { useClipboard } from '@vueuse/core'
	import { FormDesignerItem } from '../form-designer-types'
	import { FormConfig, FormItem } from '@/components/form-render/form-render-types'

	const extensions = [java(), javascript({ jsx: true, typescript: true }), oneDark]
	const visible = ref(false)

	const show = () => {
		visible.value = true
	}
	defineExpose({
		show,
	})

	const props = defineProps({
		components: {
			type: Array as PropType<FormDesignerItem[]>,
			required: true,
		},
		config: {
			type: Object as PropType<FormConfig>,
			required: true,
		},
	})
	const { components, config } = toRefs(props)

	const hanldConfig = (item: FormDesignerItem) => {
		if (item.formItem.config) {
			delete item.formItem.config.labelColFixedWidthInPx
			delete item.formItem.config.labelColSpanWidth
			delete item.formItem.config.labelType
			delete item.formItem.config.useFormConfig
			if (item.formItem.config.labelType === 'fixed') {
				delete item.formItem.config.labelCol?.span
				delete item.formItem.config.labelCol?.offset
			} else {
				delete item.formItem.config.labelCol?.style
			}
		}
		if (item.formItem.properties.options) {
			item.formItem.properties.options.forEach((item) => {
				delete item.uuid
			})
		}
		if (item.formItem.rules?.length) {
			item.formItem.rules.forEach((item) => {
				;(item as { uuid?: string }).uuid = undefined
				if (item.enum) {
					item.enum = String(item.enum).split(',')
				}
			})
		}
	}
	const activeKey = ref('form')
	const configTransfer = (item: FormDesignerItem): FormItem => {
		if (item.formItem) {
			delete item.formItem.propertyConfigFormComponents
		}
		if (item.formItem?.config) {
			hanldConfig(item)
		}
		if (item.formItem.propertiesTransfer) {
			item.formItem.properties = item.formItem.propertiesTransfer(item.formItem.properties)
		}
		//递归一下
		if (item.children) {
			return XEUtils.assign(item.formItem, { children: item.children.map((item) => configTransfer(item)) })
		}
		return item.formItem
	}
	const code = computed(() => {
		const formConfig = XEUtils.clone(config.value, true)
		if (formConfig.labelType === 'fixed') {
			delete formConfig.labelCol?.span
			delete formConfig.labelCol?.offset
		} else {
			delete formConfig.labelCol?.style
		}
		delete formConfig.labelColFixedWidthInPx
		delete formConfig.labelColSpanWidth
		delete formConfig.labelType
		switch (activeKey.value) {
			case 'form':
				return `import { FormItem, FormConfig } from '@/components/form-render/form-render-types';

export const config: FormConfig = ${JSON.stringify(formConfig, undefined, 2)}

export const formItems: FormItem[] = ${JSON.stringify(
					XEUtils.clone(components.value, true).map((item) => configTransfer(item)),
					undefined,
					2,
				)}
          `
			case 'modal':
				return `<template>
  <div>
    <a-button type="primary" @click="add">添加</a-button>
    <form-modal
      ref="formModal"
      v-model="data"
      :form-items="items"
      :config="formConfig"
      :title="title"
      :hidden-fields="hiddenFields"
      :disabled-fields="disabledFields"
      @ok="hanldOk"
    ></form-modal>
  </div>
</template>
<script lang="ts" setup>
import FormModal from '@/components/form-render/form-modal.vue';
import { config, formItems } from './form';
import { FormDataType } from '@/components/form-render/form-render-types';
const items = computed(() => {
  return formItems;
});

const formConfig = computed(() => {
  return config;
});

const data = ref<FormDataType>({});
const title = computed(() => {
  //TODO 根据数据情况设置标题
  return '添加';
});
const hiddenFields = computed(() => {
  //TODO 根据数据情况设置隐藏字段
  return [];
});
const hanldOk = (_data: FormDataType) => {
  //TODO 根据业务情况处理
  console.log(_data);
  formModal.value?.close(); //关闭弹窗
};
const disabledFields = computed(() => {
  //TODO 根据数据情况设置隐藏字段
  return [];
});
const formModal = ref<typeof FormModal>();

const add = () => {
  formModal.value?.open(); //通过ref可调用的其他方法有 open, close,reset, validateFields,resetFields,getModalContentWrapper, getPopupContainerId, closeLoading,
};
// 其他属性包含 maxHeight,width,wrapClassName,modalContentWrapperClassName
<\\/script>
`.replace('\\', '')
			case 'render':
				return `<template>
  <form-render
    v-model="data"
    :items="items"
    :config="formConfig"
    :hidden-fields="hiddenFields"
    :disabled-fields="disabledFields"
  ></form-render>
</template>
<script lang="ts" setup>
import { config, formItems } from './form';
import { FormDataType } from '@/components/form-render/form-render-types';
const items = computed(() => {
  return formItems;
});

const formConfig = computed(() => {
  return config;
});

const data = ref<FormDataType>({});
const hiddenFields = computed(() => {
  //TODO 根据数据情况设置隐藏字段
  return [];
});
const disabledFields = computed(() => {
  //TODO 根据数据情况设置隐藏字段
  return [];
});
// 可通过ref调用render的方法有 validateFields, resetFields, clearValidate
<\\/script>
`.replace('\\', '')
			default:
				return `
<template>
  <form-render v-model="formData" :form-config="formConfig" :form-items="formItems" />
</template>

<script lang="ts" setup>
import FormRender from '@/components/form-render/form-render.vue';
import { useFormItems } from './form-items';
import type { FormConfig } from '@/components/form-render/types/form-designer';
import type { FormData } from '@/components/form-render/types/form-render';

const formData = ref<FormData>({
  layout: 'horizontal',
  colon: true,
  hideRequiredMark: false,
  labelAlign: 'right',
  labelType: 'fixed',
  scrollToFirstError: false,
  validateOnRuleChange: true,
  labelCol: {}
});
const formConfig = ref<FormConfig>();
const { formItems } = useFormItems();
<\\/script>
`.replace('\\', '')
		}
	})
	const { copy, text } = useClipboard()

	watch(text, (newVal) => {
		if (newVal) {
			notification.success({
				message: '操作成功',
				description: '代码已经成功复制',
			})
		}
	})
</script>
