import { inject } from "vue"
import { MP__UPLOADER } from "../provider/MpProvider.jsx"
import { isBoolean, isFunction, isString, pick } from "lodash-es"
import MpField from "./MpField.jsx"
import MpSelect from "./MpSelect.jsx"
import MpDate from "./MpDate.jsx"
import MpSwitch from "./MpSwitch.jsx"
import MpCheckbox from "./MpCheckbox.jsx"
import MpRadio from "./MpRadio.jsx"
import MpDatetime from "./MpDatetime.jsx"
import MpNumber from "./MpNumber.jsx"
import MpRate from "./MpRate.jsx"
import MpSlider from "./MpSlider.jsx"
import MpAddress from "./MpAddress.jsx"
import MpCascader from "./MpCascader.jsx"
import MpTime from "./MpTime.jsx"
import MpFieldUploader from "./MpFieldUploader.jsx"

/**
 *
 * @param item
 * @param submitForm
 * @param props
 * @param slots
 * @return {*|JSX.Element}
 */
const render = (item, submitForm, { props, slots }) => {
	const uploaderProvider = inject(MP__UPLOADER, () => ({}))

	if (item.type === "slot" && slots[item.key]) {
		return slots[item.key]({ submitForm })
	}
	let renderItem = null

	const pickerTypes = ["select", "date", "datetime", "time", "address", "cascade"]
	const isPicker = pickerTypes.includes(item.type)

	// 处理 hidden
	if ((isFunction(item.hidden) && item.hidden(submitForm)) || (isBoolean(item.hidden) && item.hidden)) {
		return null
	}

	// MpField 的 props
	let fieldProps = pick(item, ["placeholder", "help", "required", "disabled", "rules", "readonly", "isLink", "fieldProps"])

	fieldProps.required = isFunction(fieldProps.required) ? fieldProps.required(submitForm) : fieldProps.required
	fieldProps.disabled = isFunction(fieldProps.disabled) ? fieldProps.disabled(submitForm) : fieldProps.disabled

	fieldProps = { readonly: props.readonly, disabled: props.disabled, ...fieldProps }

	if (fieldProps.readonly || fieldProps.disabled) {
		fieldProps.required = false
	}

	fieldProps.label = item.title
	fieldProps.name = item.key
	fieldProps.placeholder = fieldProps.placeholder || (isPicker ? `请选择${item.title}` : `请填写${item.title}`)
	fieldProps.rules = fieldProps.rules?.length
		? fieldProps.rules.map((rule) => {
				if (rule.pattern) {
					return {
						...rule,
						pattern: new RegExp(rule.pattern),
					}
				}
				return { ...rule }
		  })
		: []

	// 具体组件的 props
	const componentProps = pick(item, ["options", "defaultProps"])

	//混合了Field和input slot组件的slots组合
	const componentSlots = item.defaultSlots || {}

	item.type = item.type ? item.type.toLowerCase() : item.type

	//特殊：readonly 的情况下不显示 required
	if (fieldProps.required) {
		fieldProps.rules.push({
			required: true,
			message: isPicker ? `请选择${item.title}` : `请填写${item.title}`,
			trigger: isPicker ? "onChange" : "onBlur", //特意
		})
	}

	//特殊：readonly 情况下不显示 placeholder
	if (fieldProps.readonly || fieldProps.disabled) {
		fieldProps.placeholder = "--"
	}

	if (item.customRender) {
		renderItem = item.customRender({ submitForm, item })
		if (!renderItem) {
			return null
		}
	} else if (item.match) {
		// 匹配模式, 合并选项后需要移除 match
		const matchItem = { ...item, ...item.match(submitForm), match: null }
		return render(matchItem, submitForm, { props, slots })
	} else {
		switch (item.type) {
			case "select":
				renderItem = (
					<MpSelect v-model={submitForm[item.key]} {...componentProps} {...fieldProps}>
						{componentSlots}
					</MpSelect>
				)
				break
			case "date":
				renderItem = (
					<MpDate v-model={submitForm[item.key]} {...componentProps} {...fieldProps}>
						{componentSlots}
					</MpDate>
				)
				break
			case "datetime":
				renderItem = (
					<MpDatetime v-model={submitForm[item.key]} {...componentProps} {...fieldProps}>
						{componentSlots}
					</MpDatetime>
				)
				break
			case "time":
				renderItem = (
					<MpTime v-model={submitForm[item.key]} {...componentProps} {...fieldProps}>
						{componentSlots}
					</MpTime>
				)
				break
			case "switch":
				renderItem = (
					<MpSwitch v-model={submitForm[item.key]} {...componentProps} {...fieldProps}>
						{componentSlots}
					</MpSwitch>
				)
				break
			case "radio":
				renderItem = (
					<MpRadio v-model={submitForm[item.key]} {...componentProps} {...fieldProps}>
						{componentSlots}
					</MpRadio>
				)
				break
			case "checkbox":
				renderItem = (
					<MpCheckbox v-model={submitForm[item.key]} {...componentProps} {...fieldProps}>
						{componentSlots}
					</MpCheckbox>
				)
				break
			case "address":
				renderItem = (
					<MpAddress v-model={submitForm[item.key]} {...fieldProps}>
						{componentSlots}
					</MpAddress>
				)
				break
			case "cascade":
				renderItem = (
					<MpCascader v-model={submitForm[item.key]} {...componentProps} {...fieldProps}>
						{componentSlots}
					</MpCascader>
				)
				break
			case "number":
				renderItem = (
					<MpNumber v-model={submitForm[item.key]} {...componentProps} {...fieldProps}>
						{componentSlots}
					</MpNumber>
				)
				break
			case "rate":
				renderItem = (
					<MpRate v-model={submitForm[item.key]} {...componentProps} {...fieldProps}>
						{componentSlots}
					</MpRate>
				)
				break
			case "slider":
				renderItem = (
					<MpSlider v-model={submitForm[item.key]} {...componentProps} {...fieldProps}>
						{componentSlots}
					</MpSlider>
				)
				break
			case "uploader":
				renderItem = (
					<MpFieldUploader v-model={submitForm[item.key]} {...componentProps} {...fieldProps}>
						{componentSlots}
					</MpFieldUploader>
				)
				if (item.required) {
					if (!Object.keys(uploaderProvider).length) {
						console.error("请在根组件中注入 NEWBIE_UPLOADER 配置项")
						renderItem = null
						break
					}

					/*if (item.defaultProps?.maxNum && item.defaultProps?.maxNum > 1) {
                        rules.type = "array"
                        rules.message = `请上传${item.title}`
                    } else {
                        rules = {
                            type: "object",
                            required: true,
                            message: `请上传${item.title}`,
                            fields: {
                                [uploaderProvider.path]: {
                                    type: "string",
                                    required: true,
                                    message: `请上传${item.title}`,
                                },
                            },
                        }
                    }*/
				}
				break
			/* case "html":
                  renderItem = Fields.createHtml(item, submitForm)
                  break

              case "text":
                  renderItem = Fields.createText(item, submitForm)
                  break
              case "group":
                  renderItem = Fields.createGroup(item, submitForm, { provider: { uploaderProvider } })
                  break*/
			case "textarea":
				fieldProps.type = "textarea"
				renderItem = (
					<MpField v-model={submitForm[item.key]} {...fieldProps}>
						{componentSlots}
					</MpField>
				)
				break
			case "password":
				fieldProps.type = "password"
				renderItem = (
					<MpField v-model={submitForm[item.key]} {...fieldProps}>
						{componentSlots}
					</MpField>
				)
				break
			default:
				renderItem = (
					<MpField v-model={submitForm[item.key]} {...fieldProps}>
						{componentSlots}
					</MpField>
				)
				break
		}
	}

	const formItem = [renderItem]

	if (item.break) {
		formItem.unshift(<nut-divider {...props.dividerProps}>{() => (isString(item.break) ? item.break : null)}</nut-divider>)
	}

	return formItem
}

export default render
