<template>
	<template v-if="(options_schedule) && (x_modelValue)">
		<div :class="multi ? 'col-4' : 'col-5'">
			<div class="mb-3">
				<Autocomplete label="Dosage" :items="options_med_dosage.map(x => x.text)" v-model="x_dose" />
			</div>
		</div>
		<div class="col-2">
			<div class="mb-3">
				<Autocomplete label="Route" :items="options_med_route.map(x => x.text)" v-model="x_route" />
			</div>
		</div>
		<div class="col-3">
			<div v-if="options_schedule" class="mb-3">
				<Autocomplete label="Schedule" :items="options_schedule.map(x => x.value)" v-model="x_modelValue.SCHEDULE" />
			</div>
		</div>
		<div :class="multi ? 'col-3' : 'col-2'">
			<div v-if="multi" class="input-group mb-1">
				<input type="number" class="form-control" placeholder="Duration" v-model="duration_num">
				<select v-if="duration_num" class="form-select" v-model="duration_unit">
					<option value="MONTH">month{{duration_num == 1 ? '' : 's'}}</option>
					<option value="WEEK">week{{duration_num == 1 ? '' : 's'}}</option>
					<option value="DAY" selected>day{{duration_num == 1 ? '' : 's'}}</option>
					<option value="HOUR">hour{{duration_num == 1 ? '' : 's'}}</option>
					<option value="MINUTE">minute{{duration_num == 1 ? '' : 's'}}</option>
				</select>
				<select v-if="more" class="form-select" v-model="x_modelValue.CONJ">
					<option value="A">and</option>
					<option value="T">then</option>
				</select>
			</div>
			<div class="widgets mb-3">
				<button type="button" class="btn" :class="{ 'btn-primary': x_modelValue.SCHTYPE == 'P', 'btn-outline-secondary': x_modelValue.SCHTYPE != 'P' }" @click="e => x_modelValue.SCHTYPE = x_modelValue.SCHTYPE == 'P' ? '' : 'P'">PRN</button>
				<button v-if="multi" type="button" class="btn btn-outline-danger" @click="e => $emit('remove')">🗑</button>
				<button type="button" class="btn btn-outline-success" @click="e => $emit('add')">➕</button>
			</div>
		</div>
	</template>
</template>

<style scoped>
	.widgets {
		display: flex;
		flex-flow: row wrap;
		justify-content: space-between;
		gap: 0.25rem;
	}
	.widgets > button {
		flex-grow: 1;
		flex-shrink: 1;
	}
</style>

<script>
	import { debounce, groupByArray } from './util.mjs';

	import Autocomplete from './Autocomplete.vue';

	export default {
		components: {
			Autocomplete
		},
		props: {
			dlgdef: Object,
			options_med: Object,
			options_schedule: Object,
			loadrsp_group: Object,
			multi: Boolean,
			more: Boolean,
			modelValue: Object
		},
		emits: [
			'add',
			'remove',
			'update:modelValue'
		],
		data() {
			return {
				duration_num: (this.modelValue) && (this.modelValue.DAYS) ? parseFloat(this.modelValue.DAYS) : null,
				duration_unit: (this.modelValue) && (this.modelValue.DAYS) ? this.modelValue.DAYS.replace(/^\s*([+-]?(?:\d+|\d+\.\d+))\s*|S\b|\s+$/g, '') : 'DAY',
				x_modelValue: this.modelValue ? Object.assign({}, this.modelValue) : {}
			};
		},
		computed: {
			options_med_dosage() {
				return (this.options_med) && (this.options_med['Dosage']) ? this.options_med['Dosage'].items : [];
			},
			options_med_route() {
				if((this.options_med) && (this.options_med['Route'])) {
					var opt, rsp, res = this.options_med['Route'].items.slice();
					res.mapping = res.reduce((acc, val) => (acc[val.value] = val, acc), {});
					if((this.loadrsp_group) && (rsp = this.loadrsp_group['ROUTE']) && (!res.find(x => x.value == rsp.iValue))) res.push({ value: rsp.iValue, text: rsp.eValue, abbr: rsp.eValue, sig: rsp.eValue });
					return res;
				} else return [];
			},
			x_dose: {
				get() {
					var text = this.x_modelValue.DOSE;
					return this.findopt('Dosage', (x => x.value == text), 'text') || text;
				},
				set(value) {
					this.x_modelValue.DOSE = this.findopt('Dosage', (x => x.text == value), 'value') || value;
				}
			},
			x_route: {
				get() {
					var text = this.x_modelValue.ROUTE;
					return (this.options_med_route.find(x => x.value == text) || { text }).text;
				},
				set(value) {
					this.x_modelValue.ROUTE = (this.options_med_route.find(x => x.text == value) || { value }).value;
				}
			}
		},
		watch: {
			x_modelValue: {
				handler(value) { this.$emit('update:modelValue', value); }, deep: true
			}
		},
		methods: {
			findopt(section, predicate, key) {
				try {
					return this.options_med[section].items.find(predicate)[key];
				} catch(ex) {}
			}
		},
		created() {
			this.$watch(
				() => (this.dlgdef, this.modelValue, {}),
				() => {
					if(this.dlgdef) {
						var res = this.dlgdef.reduce((acc, val) => (acc[val.promptID] = acc[val.promptID], acc), {});
						if(this.loadrsp_group) Object.assign(res, this.loadrsp_group.reduce((acc, val) => (acc[val.promptID] = val.iValue != '^WP^' ? val.iValue : val.eValue, acc), {}));
						if(this.modelValue) Object.assign(res, this.modelValue);
						this.x_modelValue = this.x_modelValue ? Object.assign(this.x_modelValue, res) : res;
					} else this.x_modelValue = null;
				},
				{ deep: true, immediate: true }
			);
			this.$watch(
				() => (this.more, this.x_modelValue, {}),
				() => {
					if(this.x_modelValue) {
						if(this.more) {
							if(!this.x_modelValue.CONJ) this.x_modelValue.CONJ = 'T';
						} else {
							if(this.x_modelValue.CONJ) this.x_modelValue.CONJ = '';
						}
					}
				},
				{ immediate: true }
			);
			this.$watch(
				() => (this.duration_num, this.duration_unit, this.x_modelValue, {}),
				debounce(() => {
					var value = this.duration_num ? this.duration_num + ' ' + this.duration_unit + (this.duration_num == 1 ? '' : 'S') : '';
					if((this.x_modelValue) && (this.x_modelValue.DAYS != value)) this.x_modelValue.DAYS = value;
				}, 250),
				{ immediate: true }
			);
		}
	};
</script>
