import { computed, defineComponent, getCurrentInstance, reactive, watch } from "vue"
import { defaultFieldProps, defaultFieldSlots } from "../utils"
import { omit, pick } from "lodash-es"
import { Issue } from "@nutui/icons-vue-taro"

/**
 * MpField 输入框
 * @version 1.0.0
 */
export default defineComponent({
	name: "MpField",
	props: {
		...defaultFieldProps,

		/**
		 * 输入框内容
		 */
		modelValue: { type: [String, Number, Array, Object, Boolean], default: () => "" },

		/**
		 * 输入框类型, 支持原生 input 标签的所有
		 */
		type: { type: String, default: "" },

		/**
		 * 是否作为 Picker 的 Trigger
		 */
		mask: { type: Boolean, default: false },
	},
	emits: ["update:modelValue", "click"],
	setup(props, { slots, emit }) {
		const instance = getCurrentInstance()
		const displayText = instance.parent?.parent?.exposed?.displayText

		const state = reactive({
			value: props.mask ? displayText : props.modelValue,
			showHelp: false,
		})

		watch(
			() => props.modelValue,
			() => {
				state.value = props.modelValue
			},
		)

		const isLink = computed(() => (props.mask && !props.disabled && !props.readonly ? true : props.isLink))
		const isReadonly = computed(() => (props.mask ? true : props.readonly))

		const onUpdateValue = (value) => {
			emit("update:modelValue", value)
		}

		/****************** render **********************/

		const labelElem = () => (
			<div class={"mp-field__label"}>
				<text>{props.label || slots.label?.()}</text>

				<nut-popover v-model:visible={state.showHelp} theme={"dark"} placement={"bottom-start"}>
					{{
						content: () => <div class={"mp-field__help"}>{props.help}</div>,
						reference: () =>
							props.help ? (
								<text class={"mp-field__help-handler"}>
									<Issue />
								</text>
							) : null,
					}}
				</nut-popover>
			</div>
		)

		const inputElem = () => {
			let inputSlots = omit(slots, Object.keys(defaultFieldSlots))
			let InputElem = slots.input ? slots.input() : null

			if (Object.keys(inputSlots).length) {
				if (InputElem.length > 1) {
					console.warn("More than one root element wrapped in MpField with input slots!")
				}
				InputElem = InputElem[0]
				return <InputElem>{inputSlots}</InputElem>
			}
			return InputElem
		}

		return () => {
			let fieldSlots = pick(slots, Object.keys(defaultFieldSlots))

			if (!fieldSlots.label) {
				fieldSlots.label = labelElem
			}

			if (fieldSlots.input) {
				fieldSlots.input = inputElem
			}

			return (
				<div class={`mp-field`}>
					<nut-input
						v-model={state.value}
						type={props.type}
						name={props.name}
						placeholder={props.placeholder}
						readonly={isReadonly.value}
						disabled={props.disabled}
						required={props.required}
						isLink={isLink.value}
						rules={props.rules}
						onClickInput={() => emit("click")}
						onUpdate:modelValue={onUpdateValue}
						{...props.fieldProps}
					>
						{{
							...fieldSlots,
						}}
					</nut-input>
				</div>
			)
		}
	},
})
