<template>
	<view class="uni-easyinput" :class="{'uni-easyinput-error':msg}" :style="{color:inputBorder && msg?'#dd524d':styles.color}">
		<view class="uni-easyinput__content" :class="{'is-input-border':inputBorder ,'is-input-error-border':inputBorder && msg,'is-textarea':type==='textarea','is-disabled':disabled}"
		 :style="{'border-color':inputBorder && msg?'#dd524d':styles.borderColor,'background-color':disabled?styles.disableColor:''}">
			<uni-icons v-if="prefixIcon" class="content-clear-icon" :type="prefixIcon" color="#c0c4cc" @click="onClickIcon('prefix')"></uni-icons>
			<textarea v-if="type === 'textarea'" class="uni-easyinput__content-textarea" :class="{'input-padding':inputBorder}"
			 :name="name" :value="val" :placeholder="placeholder" :placeholderStyle="placeholderStyle" :disabled="disabled"
			 :maxlength="inputMaxlength" :focus="focused" :autoHeight="autoHeight" @input="onInput" @blur="onBlur"  @focus="onFocus"
			 @confirm="onConfirm"></textarea>
			<input v-else :type="type === 'password'?'text':type" class="uni-easyinput__content-input" :style="{
				 'padding-right':type === 'password' ||clearable || prefixIcon?'':'10px',
				 'padding-left':prefixIcon?'':'10px'
			 }"
			 :name="name" :value="val" :password="!showPassword && type === 'password'" :placeholder="placeholder"
			 :placeholderStyle="placeholderStyle" :disabled="disabled" :maxlength="inputMaxlength" :focus="focused" :confirmType="confirmType" @focus="onFocus"
			 @blur="onBlur" @input="onInput" @confirm="onConfirm" />
			<template v-if="type === 'password' && passwordIcon" >
				<uni-icons v-if="val != '' " class="content-clear-icon" :class="{'is-textarea-icon':type==='textarea'}" :type="showPassword?'eye-slash-filled':'eye-filled'"
				 :size="18" color="#c0c4cc" @click="onEyes"></uni-icons>
			</template>
			<template v-else-if="suffixIcon">
				<uni-icons v-if="suffixIcon" class="content-clear-icon" :type="suffixIcon" color="#c0c4cc" @click="onClickIcon('suffix')"></uni-icons>
			</template>
			<template v-else>
				<uni-icons class="content-clear-icon" :class="{'is-textarea-icon':type==='textarea'}" type="clear" :size="clearSize"
				 v-if="clearable && val && !disabled" color="#c0c4cc" @click="onClear"></uni-icons>
			</template>
			<slot name="right"></slot>
		</view>
	</view>
</template>

<script>
	// import {
	// 	debounce,
	// 	throttle
	// } from './common.js'
	/**
	 * Easyinput 输入框
	 * @description 此组件可以实现表单的输入与校验，包括 "text" 和 "textarea" 类型。
	 * @tutorial https://ext.dcloud.net.cn/plugin?id=3455
	 * @property {String}	value	输入内容
	 * @property {String }	type	输入框的类型（默认text） password/text/textarea/..
	 * 	@value text			文本输入键盘
	 * 	@value textarea	多行文本输入键盘
	 * 	@value password	密码输入键盘
	 * 	@value number		数字输入键盘，注意iOS上app-vue弹出的数字键盘并非9宫格方式
	 * 	@value idcard		身份证输入键盘，信、支付宝、百度、QQ小程序
	 * 	@value digit		带小数点的数字键盘	，App的nvue页面、微信、支付宝、百度、头条、QQ小程序支持
	 * @property {Boolean}	clearable	是否显示右侧清空内容的图标控件，点击可清空输入框内容（默认true）
	 * @property {Boolean}	autoHeight	是否自动增高输入区域，type为textarea时有效（默认true）
	 * @property {String }	placeholder	输入框的提示文字
	 * @property {String }	placeholderStyle	placeholder的样式(内联样式，字符串)，如"color: #ddd"
	 * @property {Boolean}	focus	是否自动获得焦点（默认false）
	 * @property {Boolean}	disabled	是否禁用（默认false）
	 * @property {Number }	maxlength	最大输入长度，设置为 -1 的时候不限制最大长度（默认140）
	 * @property {String }	confirmType	设置键盘右下角按钮的文字，仅在type="text"时生效（默认done）
	 * @property {Number }	clearSize	清除图标的大小，单位px（默认15）
	 * @property {String}	prefixIcon	输入框头部图标
	 * @property {String}	suffixIcon	输入框尾部图标
	 * @property {Boolean}	trim	是否自动去除两端的空格
	 * @value both	去除两端空格
	 * @value left	去除左侧空格
	 * @value right	去除右侧空格
	 * @value start	去除左侧空格
	 * @value end		去除右侧空格
	 * @value all		去除全部空格
	 * @value none	不去除空格
	 * @property {Boolean}	inputBorder	是否显示input输入框的边框（默认true）
	 * @property {Boolean}	passwordIcon	type=password时是否显示小眼睛图标
	 * @property {Object}	styles	自定义颜色
	 * @event {Function}	input	输入框内容发生变化时触发
	 * @event {Function}	focus	输入框获得焦点时触发
	 * @event {Function}	blur	输入框失去焦点时触发
	 * @event {Function}	confirm	点击完成按钮时触发
	 * @event {Function}	iconClick	点击图标时触发
	 * @example <uni-easyinput v-model="mobile"></uni-easyinput>
	 */

	export default {
		name: 'uni-easyinput',
		emits:['click','iconClick','update:modelValue','input','focus','blur','confirm'],
		model:{
			prop:'modelValue',
			event:'update:modelValue'
		},
		props: {
			name: String,
			value: [Number, String],
			modelValue: [Number, String],
			type: {
				type: String,
				default: 'text'
			},
			clearable: {
				type: Boolean,
				default: true
			},
			autoHeight: {
				type: Boolean,
				default: false
			},
			placeholder: String,
			placeholderStyle: String,
			focus: {
				type: Boolean,
				default: false
			},
			disabled: {
				type: Boolean,
				default: false
			},
			maxlength: {
				type: [Number, String],
				default: 140
			},
			confirmType: {
				type: String,
				default: 'done'
			},
			clearSize: {
				type: [Number, String],
				default: 15
			},
			inputBorder: {
				type: Boolean,
				default: true
			},
			prefixIcon: {
				type: String,
				default: ''
			},
			suffixIcon: {
				type: String,
				default: ''
			},
			trim: {
				type: [Boolean, String],
				default: true
			},
			passwordIcon:{
				type: Boolean,
				default: true
			},
			styles: {
				type: Object,
				default () {
					return {
						color: '#333',
						disableColor: '#eee',
						borderColor: '#e5e5e5'
					}
				}
			},
			errorMessage:{
				type:[String,Boolean],
				default:''
			}
		},
		data() {
			return {
				focused: false,
				errMsg: '',
				val: '',
				showMsg: '',
				border: false,
				isFirstBorder: false,
				showClearIcon: false,
				showPassword: false
			};
		},
		computed: {
			msg() {
				return this.errorMessage || this.errMsg;
			},
			// 因为uniapp的input组件的maxlength组件必须要数值，这里转为数值，给用户可以传入字符串数值
			inputMaxlength() {
				return Number(this.maxlength);
			},
		},
		watch: {
			value(newVal) {
				if (this.errMsg) this.errMsg = ''
				this.val = newVal
				if (this.form && this.formItem) {
					this.formItem.setValue(newVal)
				}
			},
			modelValue(newVal) {
				if (this.errMsg) this.errMsg = ''
				this.val = newVal
				if (this.form && this.formItem) {
					this.formItem.setValue(newVal)
				}
			},
			focus(newVal) {
				this.$nextTick(() => {
					this.focused = this.focus
				})
			}
		},
		created() {
			if(!this.value){
				this.val = this.modelValue
			}
			if(!this.modelValue){
				this.val = this.value
			}
			this.form = this.getForm('uniForms')
			this.formItem = this.getForm('uniFormsItem')
			if (this.form && this.formItem) {
				if (this.formItem.name) {
					this.rename = this.formItem.name
					this.form.inputChildrens.push(this)
				}
			}
		},
		mounted() {
			// this.onInput = throttle(this.input, 500)
			this.$nextTick(() => {
				// setTimeout(()=>{
				// },1000)
				this.focused = this.focus
			})
		},
		methods: {
			/**
			 * 初始化变量值
			 */
			init() {

			},
			onClickIcon(type) {
				this.$emit('iconClick', type)
			},
			/**
			 * 获取父元素实例
			 */
			getForm(name = 'uniForms') {
				let parent = this.$parent;
				let parentName = parent.$options.name;
				while (parentName !== name) {
					parent = parent.$parent;
					if (!parent) return false;
					parentName = parent.$options.name;
				}
				return parent;
			},

			onEyes() {
				this.showPassword = !this.showPassword
			},
			onInput(event) {
				let value = event.detail.value;
				// 判断是否去除空格
				if (this.trim) {
					if (typeof(this.trim) === 'boolean' && this.trim) {
						value = this.trimStr(value)
					}
					if (typeof(this.trim) === 'string') {
						value = this.trimStr(value, this.trim)
					}
				};
				if (this.errMsg) this.errMsg = ''
				this.val = value
				// TODO 兼容 vue2
				this.$emit('input', value);
				// TODO　兼容　vue3
				this.$emit('update:modelValue',value)
			},

			onFocus(event) {
				// this.focused = true;
				this.$emit('focus', event);
			},
			onBlur(event) {
				let value = event.detail.value;
				// setTimeout(() => {
				// this.focused = false;
				// }, 100);
				this.$emit('blur', event);
			},
			onConfirm(e) {
				this.$emit('confirm', e.detail.value);
			},
			onClear(event) {
				this.val = '';
				// TODO 兼容 vue2
				this.$emit('input', '');
				// TODO 兼容 vue2
				// TODO　兼容　vue3
				this.$emit('update:modelValue','')
			},
			fieldClick() {
				this.$emit('click');
			},
			trimStr(str, pos = 'both') {
				if (pos === 'both') {
					return str.trim();
				} else if (pos === 'left') {
					return str.trimLeft();
				} else if (pos === 'right') {
					return str.trimRight();
				} else if (pos === 'start') {
					return str.trimStart()
				} else if (pos === 'end') {
					return str.trimEnd()
				} else if (pos === 'all') {
					return str.replace(/\s+/g, '');
				} else if (pos === 'none') {
					return str;
				}
				return str;
			}
		}
	};
</script>

<style lang="scss" scoped>
	.uni-easyinput {
		/* #ifndef APP-NVUE */
		width: 100%;
		/* #endif */
		flex: 1;
		position: relative;
		text-align: left;
		color: #333;
		font-size: 14px;
	}

	.uni-easyinput__content {
		flex: 1;
		/* #ifndef APP-NVUE */
		width: 100%;
		display: flex;
		box-sizing: border-box;
		min-height: 36px;
		/* #endif */
		flex-direction: row;
		align-items: center;
	}

	.uni-easyinput__content-input {
		/* #ifndef APP-NVUE */
		width: auto;
		/* #endif */
		position: relative;
		overflow: hidden;
		flex: 1;
		line-height: 1;
		font-size: 14px;
	}

	.is-textarea {
		align-items: flex-start;
	}

	.is-textarea-icon {
		margin-top: 5px;
	}

	.uni-easyinput__content-textarea {
		position: relative;
		overflow: hidden;
		flex: 1;
		line-height: 1.5;
		font-size: 14px;
		padding-top: 6px;
		padding-bottom: 10px;
		height: 80px;
		/* #ifndef APP-NVUE */
		min-height: 80px;
		width: auto;
		/* #endif */
	}

	.input-padding {
		padding-left: 10px;
	}

	.content-clear-icon {
		padding: 0 5px;
	}

	.label-icon {
		margin-right: 5px;
		margin-top: -1px;
	}

	// 显示边框
	.is-input-border {
		/* #ifndef APP-NVUE */
		display: flex;
		box-sizing: border-box;
		/* #endif */
		flex-direction: row;
		align-items: center;
		border: 1px solid $uni-border-color;
		border-radius: 4px;
	}

	.uni-easyinput__right {
		// margin-left: 5px;
	}

	// 必填
	.is-required {
		color: $uni-color-error;
	}

	.uni-error-message {
		position: absolute;
		bottom: -17px;
		left: 0;
		line-height: 12px;
		color: $uni-color-error;
		font-size: 12px;
		text-align: left;
	}

	.uni-error-msg--boeder {
		position: relative;
		bottom: 0;
		line-height: 22px;
	}

	.is-input-error-border {
		border-color: $uni-color-error;
	}

	.uni-easyinput--border {
		margin-bottom: 0;
		padding: 10px 15px;
		// padding-bottom: 0;
		border-top: 1px #eee solid;
	}

	.uni-easyinput-error {
		padding-bottom: 0;
	}

	.is-first-border {
		/* #ifndef APP-NVUE */
		border: none;
		/* #endif */
		/* #ifdef APP-NVUE */
		border-width: 0;
		/* #endif */
	}

	.is-disabled {
		background-color: #eee;
	}
</style>
