// plugin/vue-renderer/component/nc-input/nc-input-component.js
// nc-input/nc-input-component.js
// /src/components/nc-input/nc-input-component.js
/* <template>
	<sui-input
		:style='calculatedStyle'
		:class='styleClass'
		:disabled='disabled'
		:value='recValueFormatted'
		@input='updateValue($event)'
		@focus='onFocus($event)'
		@blur='onBlur($event)'/>
</template> */

// import { ncValidate } from '/src/directives/nc-validate.js'
// import SuiInput from '/web_modules/semantic-ui-vue/dist/commonjs/elements/Input/Input.js'
import { inject, reactive, computed, toRefs } from '../../vuelib.js' // server component must have vue imports
import nc from '../../core/nc-util.js'
import peg from '../../core/nc-peg.js'
import dt from '../../core/nc-dt.js'
import { rowColStyle } from '../nc-form/nc-form-col-row.js'
const defaultDateFormat = null // 'dd.mm.yyyy' // TODO: fix defaultDateFormat

export const props = {
	clean: {
		type: [Boolean, String],
		default: undefined
	},
	containerStyle: {
		type: String,
		default: undefined
	},
	inputStyle: {
		type: String,
		default: undefined
	},
	labelStyle: {
		type: [String, Object],
		default: undefined
	},
	focus: {
		type: Function,
		default: undefined
	},
	blur: {
		type: Function,
		default: undefined
	},
	required: {
		type: Boolean,
		default: false
	},
	id: {
		type: String,
		default: undefined
	},
	name: {
		type: String,
		default: undefined
	},
	type: {
		type: String,
		default: 'text'
	},
	hdr: {
		type: String,
		default: undefined
	},
	model: {
		type: String,
		default: undefined
	},
	labelWidth: {
		type: String,
		default: undefined
	},
	inputWidth: {
		type: String,
		default: undefined
	},
	width: {
		type: String,
		default: undefined
	},
	height: {
		type: String,
		default: undefined
	},
	value: {
		type: [String, Number, Boolean],
		default: undefined
	},
	placeholder: {
		type: String,
		default: undefined
	},
	autocomplete: {
		type: String,
		default: undefined
	},
	disabled: {
		type: Boolean,
		default: undefined
	},
	readonly: {
		type: Boolean,
		default: undefined
	},
	calendarType: {
		type: String,
		default: undefined
	},
	startMode: {
		type: String,
		default: undefined
	},
	startCalendar: {
		type: String,
		default: undefined
	},
	endCalendar: {
		type: String,
		default: undefined
	},
	hover: {
		type: String,
		default: undefined
	},
	rows: {
		type: String,
		default: undefined
	}, // for textarea
	horizontal: {
		type: Boolean,
		default: true
	}
	/* editor: { type: String, default: undefined, required: false }, */
}

export default function createComponent(name) {
	return {
		name: name,
		// directives: { ncValidate },
		props: props,
		setup(props, { emit, attrs }) {
			const state = inject(`state`)
			const data = reactive({
				style: '',
				styleClass: name === 'NcTextarea' ? 'nc-textarea' : 'nc-input',
				isCalendar: false,
				textIsChanged: false,
				dateFormat: null,
				useValue: false,
				prevValidDate: false,
				recName: null,
				recName2: null
			})

			const calculatedStyle = computed(() => {
				let style = data.style
				if (props.inputStyle) {
					style += props.inputStyle + ';'
				}
				return style
			})
			const hdrModel = computed(() => {
				if (props.hdr) return props.hdr
				if (props.model == null) return ''
				let pos = props.model.indexOf('.')
				return 'hdr.' + props.model.substring(pos + 1) // part after "rec."
			})
			const recValue = computed(() => {
				if (data.useValue) {
					return props.value // data.fieldRec[data.fieldName] # props.value
				}
				return nc.recData(state.rec, data.recName)
			})
			const recValue2 = computed(() => {
				return nc.recData(state.rec, data.recName2)
			})
			const recValueFormatted = computed(() => {
				if (data.useValue) {
					return props.value
				}
				if (data.recName == null) {
					return null
				}
				let val = nc.recData(state.rec, data.recName)
				if (nc.isDate(val)) {
					data.prevValidDate = val
					data.dateFormat = data.dateFormat || defaultDateFormat
					val = dt.dateToString(val, data.dateFormat) // timestamp.fromJSDate(val).format(data.dateFormat)
				}
				return val
			})

			// onMounted(() => {
			function init() {
				data.recName = null
				data.style = rowColStyle(props, true) // true == set default
				if (!nc.isNil(props.value)) {
					data.useValue = true
					return
				}
				if (props.model == null) {
					if (props.value === undefined) {
						// null is valid
						if (attrs && attrs[':value']) {
							data.useValue = true
							return
						}
						console.warn(`input component '${name}', model or value does not exist`)
						data.useValue = true // prevent more errors
						// debugger // eslint-disable-line
						return
					}
					return
				}
				let pos = props.model.indexOf('.')
				data.recName = props.model.substring(pos + 1) // part after "rec."
				if (!nc.isNil(props.startCalendar)) {
					pos = props.startCalendar.indexOf('.')
					data.recName2 = props.startCalendar.substring(pos + 1)
				} else if (!nc.isNil(props.endCalendar)) {
					pos = props.endCalendar.indexOf('.')
					data.recName2 = props.endCalendar.substring(pos + 1)
				}
				if (props.model.indexOf('rec.') !== 0) {
					console.warn(`input component '${name}' model '${props.model}' does not start with 'rec.'`, props)
				}
				data.isCalendar = props.type === 'date'
				if (nc.isDate(recValue)) {
					// const locale = window.navigator.userLanguage || window.navigator.language // use nc language
					// dt.setLocale(locale) // timestamp.fromJSDate.locale(locale)
					data.dateFormat = defaultDateFormat
					if (props.calendarType === 'timestamp') {
						const timeFormat = dt.timeFormat()
						data.dateFormat = data.dateFormat + ' ' + timeFormat
					}
					// props.type = 'date' // TODO: timestamp?
					data.isCalendar = true
					// data.setupDone = true
				}
			}
			init()

			function inputValueChanged(newValue, event) {
				if (data.useValue) {
					return
				}
				if (data.recName == null) {
					return
				}
				nc.setPrevRec(state, data.recName, 'nc-input')
				nc.setRec(state, data.recName, newValue, 'inputValueChanged', event)
			}

			function choseDay(newDate) {
				// datepicker date has been chosen
				updateValue(newDate)
			}

			function updateValue(event) {
				/* _.debounce () ->
					props.value = event.target.value
				, 300 */
				let newValue = event
				const isDate = nc.isDate(newValue)
				if (isDate) {
					data.dateFormat = data.dateFormat || defaultDateFormat
					newValue = dt.dateToString(newValue, data.dateFormat)
				} else if (typeof event === 'object') {
					newValue = event.target.value
				}
				if (typeof newValue === 'string') {
					if (!isDate && typeof event === 'object') {
						event.target.value = newValue
					}
				}
				inputValueChanged(newValue, event)
				emit('change', newValue)
			}

			function onEnterKey(event) {
				let runDefault = true
				if (props.focus) {
					runDefault = props.focus(event)
				}
				if (runDefault) {
					emit('enterKey', event)
				}
			}

			function onFocus(event) {
				let runDefault = true
				if (props.focus) {
					runDefault = props.focus(event)
				}
				if (runDefault) {
					emit('focus', event)
				}
			}

			function onBlur(event) {
				let runDefault = true
				if (props.blur) {
					runDefault = props.blur(event)
				}
				let newValue = event
				if (typeof event === 'object') {
					newValue = event.target.value
				}
				if (data.dateFormat) {
					const oldValue = nc.recData(state.rec, data.recName)
					let date = dt.textToDate(oldValue)
					data.prevValidDate = date
					newValue = dt.dateToString(date, data.dateFormat)
				} else if (typeof newValue === 'string') {
					if (props.clean !== 'false' && (props.clean === undefined || props.clean)) {
						newValue = peg.cleanBeforeAfterDoubleSpace(newValue)
					}
					if (typeof event === 'object') {
						event.target.value = newValue
					}
				}
				inputValueChanged(newValue, event)
				if (runDefault) {
					emit('blur', event)
				}
			}

			const ret = Object.assign(
				{
					calculatedStyle,
					hdrModel,
					recValue,
					recValue2,
					recValueFormatted,
					choseDay,
					updateValue,
					onEnterKey,
					onFocus,
					onBlur,
					inputValueChanged
				},
				toRefs(data)
			)
			return ret
		}
	}
}

/* 	watch: {
recValue(newValue, oldValue) {
	let locale, timeFormat
	if (data.useValue) {
		return
	}
	console.debug('newValue', newValue)
	if (nc.isDate(newValue)) {
		if (!data.setupDone && oldValue == null) {
			data.isCalendar = true
			locale = window.navigator.userLanguage || window.navigator.language // use ma language
			dt.setLocale(locale) // timestamp.fromJSDate.locale(locale)
			data.dateFormat = defaultDateFormat
			if (props.calendarType === 'timestamp') {
				timeFormat = dt.timeFormat()
				data.dateFormat = data.dateFormat + ' ' + timeFormat
			}
			// props.type = 'date' // TODO: timestamp?
			data.setupDone = true
		}
	}
} */

/* function debouncedRef(value, delay = 200) {
	let timeout
	return customRef((track, trigger) => {
		return {
			get() {
				track()
				return value
			},
			set(newValue) {
				clearTimeout(timeout)
				timeout = setTimeout(() => {
					value = newValue
					trigger()
				}, delay)
			}
		}
	})
} */

/* semantic-ui-vue/src/elements/Input.jsx
	props: {
		action: String,
		disabled: Boolean,
		error: Boolean,
		focus: Boolean,
		icon: String,
		iconPosition: Enum(['left', 'right']),
		inverted: Boolean,
		loading: Boolean,
		transparent: Boolean,
		type: {
			description: 'The HTML input type.',
			default: 'text',
			type: String,
		},
		value: [String, Number],
	},
	events: {
		input: {
			custom: true,
		},
		blur: {
			custom: true,
		},
	},
	methods: {
		handleChange(event) {
			const eventValue = event.target.value;
			const value = props.type === 'number' ? Number(eventValue) : eventValue;
			emit('input', value);
		},
	},

	class={data.classes(
		'ui',
		data.action && 'action',
		props.disabled && 'disabled',
		data.error && 'error',
		props.focus && 'focus',
		data.transparent && 'transparent',
		data.inverted && 'inverted',
		data.loading && 'loading',
		data.iconPosition === 'left' && 'left',
		(data.loading || data.icon) && 'icon',
		'input',
	)}
>
	<input
		value={props.value}
		onInput={data.handleChange}
		onBlur={e => emit('blur', e)}
		ref="input"
		type={props.type}
		{...{ attrs: attrs }}
	/>
	{icon}
	{data.action && <SuiButton content={data.action} />}
*/
