<template>
	<ion-item lines="full" ref="item">
		<ion-label v-if="label" position="fixed">{{ $t(label) }} <span v-if="required">*</span></ion-label>
		<ion-textarea
			v-if="type === 'textarea'"
			v-model="value"
			:placeholder="placeholder ? $t(placeholder) : ''"
			:rows="5"
			:minlength="minLength ?? 0"
			:maxlength="maxLength ?? 1000"
			:readonly="readOnly || false"
			@ion-change="changeValue"
			@ion-blur="markTouched"
			ref="textarea"
		></ion-textarea>
		<ion-searchbar
			v-else-if="type === 'search'"
			v-model="value"
			:placeholder="placeholder ? $t(placeholder) : ''"
			@ion-change="changeValue"
			@ion-blur="markTouched"
			ref="search"
		></ion-searchbar>
		<sgc-radio v-else-if="type === 'radio'" v-model="value" :codeKey="codeKey" :add-all="addAll" @sgc-change="changeValue" @sgc-blur="markTouched" ref="radio"></sgc-radio>
		<sgc-checkbox v-else-if="type === 'checkbox'" v-model="value" :codeKey="codeKey" @sgc-change="changeValue" @sgc-blur="markTouched" ref="checkbox"></sgc-checkbox>
		<sgc-select
			v-else-if="type === 'select'"
			v-model="value"
			:codeKey="codeKey"
			:add-all="addAll"
			:placeholder="placeholder"
			@sgc-change="changeValue"
			@sgc-blur="markTouched"
			ref="select"
		></sgc-select>
		<sgc-datetime
			v-else-if="type === 'datetime'"
			v-model="value"
			:hide-clear-button="hideClearButton"
			:readonly="readOnly || false"
			@sgc-change="changeValue"
			@sgc-blur="markTouched"
			ref="datetime"
		></sgc-datetime>
		<sgc-datetime-range
			v-else-if="type === 'datetime-range'"
			v-model:from="value"
			v-model:to="extraValue"
			@sgc-change="changeValue"
			@sgc-blur="markTouched"
			ref="datetimerange"
		></sgc-datetime-range>
		<sgc-hour-range
			v-else-if="type === 'hour-range'"
			v-model:from="value"
			v-model:to="extraValue"
			:codeKey="codeKey"
			@sgc-change="changeValue"
			@sgc-blur="markTouched"
			ref="hourrange"
		></sgc-hour-range>
		<sgc-search-id
			v-else-if="type === 'search-id'"
			v-model:value="value"
			v-model:label="extraValue"
			:searchType="searchType"
			:params="params"
			@sgc-change="changeValue"
			@sgc-blur="markTouched"
			ref="searchid"
		>
		</sgc-search-id>
		<ion-input
			v-else
			v-model="value"
			:placeholder="placeholder ? $t(placeholder) : ''"
			:type="type ?? 'text'"
			:readonly="readOnly || false"
			:clearInput="clearInput ? true : false"
			:minlength="minLength ?? 0"
			:maxlength="maxLength ?? 1000"
			@ion-change="changeValue"
			@ion-blur="markTouched"
			ref="text"
		></ion-input>
		<slot></slot>
		<ion-note slot="helper" v-if="helper">{{ helper }}</ion-note>
		<ion-note slot="error" v-if="error">{{ error }}</ion-note>
	</ion-item>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { IonItem, IonNote, IonSearchbar, IonLabel, IonInput, IonTextarea } from '@ionic/vue';
import commonService from './../../services/common.service';

import SgcCheckbox from './SgcCheckbox.vue';
import SgcDatetime from './SgcDatetime.vue';
import SgcDatetimeRange from './SgcDatetimeRange.vue';
import SgcHourRange from './SgcHourRange.vue';
import SgcRadio from './SgcRadio.vue';
import SgcSearchId from './SgcSearchId.vue';
import SgcSelect from './SgcSelect.vue';

export default defineComponent({
	name: 'SgcItemInput',
	components: {
		IonItem,
		IonNote,
		IonLabel,
		IonInput,
		IonSearchbar,
		IonTextarea,
		SgcRadio,
		SgcCheckbox,
		SgcSelect,
		SgcDatetime,
		SgcDatetimeRange,
		SgcHourRange,
		SgcSearchId,
	},
	props: [
		'label',
		'modelValue',
		'to',
		'type',
		'required',
		'readOnly',
		'minLength',
		'maxLength',
		'helper',
		'error',
		'addAll',
		'codeKey',
		'placeholder',
		'searchType',
		'params',
		'inValid',
		'clearInput',
		'hideClearButton',
		'interfaceOptions',
	],
	emits: ['update:modelValue', 'update:to', 'sgcChange', 'sgcBlur'],
	watch: {
		modelValue() {
			this.changeModel();
		},
	},
	mounted() {
		this.changeModel();
	},
	data() {
		return {
			value: null,
			extraValue: null,
		};
	},
	methods: {
		/** 내부 함수 REF 입력 객체 가져오기 */
		_getRefInput(methodName: string) {
			switch (this.type) {
				case 'search':
					return commonService.getRef(this.$refs, 'search', methodName);
				case 'radio':
					return commonService.getRef(this.$refs, 'radio', methodName);
				case 'checkbox':
					return commonService.getRef(this.$refs, 'checkbox', methodName);
				case 'select':
					return commonService.getRef(this.$refs, 'select', methodName);
				case 'datetime':
					return commonService.getRef(this.$refs, 'datetime', methodName);
				case 'datetime-range':
					return commonService.getRef(this.$refs, 'datetimerange', methodName);
				case 'hour-range':
					return commonService.getRef(this.$refs, 'hourrange', methodName);
				case 'search-id':
					return commonService.getRef(this.$refs, 'searchid', methodName);
				case 'textarea':
					return commonService.getRef(this.$refs, 'textarea', methodName);
				case 'text':
				default:
					return commonService.getRef(this.$refs, 'text', methodName);
			}
		},
		/** 선택된 CodeVO 가져오기 */
		getCodeVo() {
			return this._getRefInput('getCodeVo')?.getCodeVo();
		},
		/** 포커스 두기 */
		setFocus() {
			this.getRefsItem()?.$el.classList.add('ion-touched');
			this._getRefInput('setFocus')?.setFocus();
			this.checkValidate();
		},
		/** 비 활성화 실행 */
		setDisabled(disabled: boolean) {
			const refEl = this._getRefInput('setDisabled');
			if (refEl !== null && refEl !== undefined) {
				if (refEl.setDisabled) {
					refEl.setDisabled(disabled);
				} else if (refEl.disabled !== undefined) {
					refEl.disabled = disabled;
				}
			}
		},
		/** 모델 변경 */
		changeModel() {
			const refsItem = this.getRefsItem();
			refsItem?.$el.classList.add('item-interactive');
			switch (this.type) {
				case 'search':
				case 'radio':
				case 'select':
					this.value = '' + this.modelValue;
					break;
				case 'checkbox':
					if (Array.isArray(this.modelValue)) {
						this.value = this.modelValue;
					} else {
						this.value = [];
					}
					break;
				case 'number':
					this.value = this.modelValue || 0;
					break;
				default:
					this.value = this.modelValue || '';
					break;
			}
			switch (this.type) {
				case 'datetime-range':
				case 'hour-range':
				case 'search-id':
					this.extraValue = this.to;
					break;
			}
			this.modelValue ? refsItem?.$el.classList.add('item-has-value') : refsItem?.$el.classList.remove('item-has-value');
		},
		/** REF 아이템 가져오기 */
		getRefsItem(): any {
			return commonService.getRef(this.$refs, 'item');
		},
		/** 베리데이션 확인 */
		checkValidate(): void {
			window.setTimeout(() => {
				const value: any = this.value;
				const refsItem = this.getRefsItem();
				refsItem?.$el.classList.remove('ion-valid');
				refsItem?.$el.classList.remove('ion-invalid');
				let isValid = true && !this.inValid;
				if (typeof value === 'string') {
					if (this.required && isValid) {
						isValid = isValid && value?.length > 0;
					}
					if (this.minLength && isValid) {
						isValid = isValid && value?.length >= this.minLength;
					}
					if (this.maxLength && isValid) {
						isValid = isValid && value?.length <= this.maxLength;
					}
				} else if (Array.isArray(value)) {
					if (this.required && isValid) {
						isValid = isValid && value?.length > 0;
					}
				}
				isValid ? refsItem?.$el.classList.add('ion-valid') : refsItem?.$el.classList.add('ion-invalid');
			}, 500);
		},
		/** 값 변경 */
		changeValue() {
			let value: any = null;
			switch (this.type) {
				case 'search':
				case 'radio':
				case 'select':
					value = '' + this.value;
					break;
				case 'checkbox':
					if (Array.isArray(this.value)) {
						value = this.value;
					} else {
						value = [];
					}
					break;
				default:
					value = this.value || '';
					break;
			}
			this.$emit('update:modelValue', value);
			switch (this.type) {
				case 'datetime-range':
				case 'hour-range':
				case 'search-id':
					this.$emit('update:to', this.extraValue);
					break;
			}
			this.$emit('sgcChange', value);
			this.checkValidate();
		},
		/** 터치 마크 */
		markTouched() {
			this.getRefsItem()?.$el.classList.add('ion-touched');
			this.changeValue();
		},
	},
});
</script>
<style scoped lang="scss">
ion-item {
	ion-label {
		span {
			color: var(--ion-color-danger);
		}
	}
}
</style>
