<template>
    <div class="input-group input-group-sm">
        <div v-if="inputType === 'checkbox'" class="input-group-prepend">
            <div :class="['input-group-text', 'bg-transparent', showBorder ? 'border-secondary' : 'border-0']">
                <input
                    :id="id"
                    ref="checkboxInput"
                    type="checkbox"
                    autocomplete="off"
                    :checked="isChecked"
                    :disabled="disabled"
                    @change="handleCheckboxChange"
                >
            </div>
            <input type="text" class="form-control" value="" disabled style="display: none">
        </div>

        <select
            v-else-if="inputType === 'select'"
            :id="id"
            class="form-control form-control-sm"
            :value="displayValue"
            :disabled="disabled"
            @change="handleSelectChange"
        >
            <option value="">{{ disabled ? '-' : '(not set)' }}</option>
            <option v-for="option in schema.options || []" :key="option" :value="option">{{ option }}</option>
        </select>

        <input
            v-else-if="inputType === 'number'"
            :id="id"
            type="number"
            class="form-control form-control-sm"
            :value="displayValue"
            :disabled="disabled"
            :min="schema.validation_rules ? schema.validation_rules.min : undefined"
            :max="schema.validation_rules ? schema.validation_rules.max : undefined"
            :placeholder="disabled ? '' : '(not set)'"
            @input="handleNumberInput"
        >

        <input
            v-else-if="inputType === 'text'"
            :id="id"
            type="text"
            class="form-control form-control-sm"
            :value="displayValue"
            :disabled="disabled"
            :placeholder="disabled ? '' : '(not set)'"
            @input="handleTextInput"
        >

        <textarea
            v-else-if="inputType === 'json'"
            :id="id"
            class="form-control form-control-sm"
            rows="3"
            style="font-family: monospace; font-size: 0.8rem"
            :value="jsonDisplayValue"
            :disabled="disabled"
            :placeholder="disabled ? '' : '(not set)'"
            @input="handleJsonInput"
        ></textarea>

        <div v-if="showClear" class="input-group-append">
            <button class="btn btn-outline-secondary" type="button" title="Clear preference" @click="handleClear">
                x
            </button>
        </div>
    </div>
</template>

<script>
export default {
    name: 'PreferenceInput',
    props: {
        id: {type: String, required: true},
        schema: {type: Object, required: true},
        value: {default: null},
        disabled: {type: Boolean, default: false},
    },
    emits: ['input', 'clear'],
    computed: {
        inputType() {
            const typeMapping = {
                boolean: 'checkbox',
                integer: 'number',
                float: 'number',
                enum: 'select',
                string: 'text',
                json: 'json',
            }
            return typeMapping[this.schema.type] || 'text'
        },
        isSet() {
            return this.value !== null && this.value !== undefined
        },
        isChecked() {
            return this.isSet ? Boolean(this.value) : false
        },
        showBorder() {
            return this.inputType === 'checkbox' && this.isSet && !this.disabled
        },
        showClear() {
            return !this.disabled && this.isSet
        },
        displayValue() {
            return this.value ?? ''
        },
        jsonDisplayValue() {
            if (this.value === null || this.value === undefined) {
                return ''
            }
            return typeof this.value === 'object' ? JSON.stringify(this.value, null, 2) : this.value
        },
    },
    mounted() {
        this.updateCheckboxIndeterminate()
    },
    updated() {
        this.updateCheckboxIndeterminate()
    },
    methods: {
        updateCheckboxIndeterminate() {
            if (this.inputType !== 'checkbox') {
                return
            }
            const input = this.$refs.checkboxInput
            if (input) {
                input.indeterminate = !this.isSet
            }
        },
        handleCheckboxChange(e) {
            this.$emit('input', e.target.checked)
        },
        handleSelectChange(e) {
            const val = e.target.value
            this.$emit('input', val === '' ? null : val)
        },
        handleNumberInput(e) {
            const raw = e.target.value
            const val = raw === '' ? null : parseFloat(raw)
            this.$emit('input', Number.isNaN(val) ? null : val)
        },
        handleTextInput(e) {
            const val = e.target.value
            this.$emit('input', val === '' ? null : val)
        },
        handleJsonInput(e) {
            const val = e.target.value.trim()
            if (val === '') {
                this.$emit('input', null)
                return
            }
            try {
                this.$emit('input', JSON.parse(val))
            } catch {
                this.$emit('input', val)
            }
        },
        handleClear() {
            this.$emit('clear')
        },
    },
}
</script>

