<template>
    <component v-if="!asChild" :is="as" :class="cx('root')" v-bind="attrs" />
    <slot v-else :a11yAttrs="a11yAttrs" :class="cx('root')" />
</template>

<script>
import { cn } from '@primeuix/utils';
import { mergeProps, withKeys } from 'vue';
import BaseInputColorInput from './BaseInputColorInput.vue';

export default {
    name: 'InputColorInput',
    extends: BaseInputColorInput,
    inheritAttrs: false,
    inject: ['$pcInputColor'],
    data() {
        return {
            pendingValue: null
        };
    },
    methods: {
        updateInputValue(value) {
            return this.$pcInputColor.updateChannel(this.channel, value);
        },
        flushPendingValue(event) {
            if (this.pendingValue === null || !event || !event.target) return false;

            const value = this.pendingValue;

            this.pendingValue = null;

            return this.updateInputValue(value);
        },
        emitInputValueChangeEnd(event) {
            if (this.flushPendingValue(event)) {
                this.$pcInputColor.emitValueChangeEnd(event);
            }
        },
        onInput(event) {
            if (!event || !event.target) return;

            this.pendingValue = event.target.value;

            if (!this.isTextChannel) this.flushPendingValue(event);
        },
        onChange(event) {
            if (this.isTextChannel) return;

            this.$pcInputColor.emitValueChangeEnd(event);
        },
        onBlur(event) {
            if (this.isTextChannel) this.emitInputValueChangeEnd(event);
        },
        onKeyDown(event) {
            if (event.defaultPrevented) return;

            event.preventDefault();

            if (this.isTextChannel) {
                this.emitInputValueChangeEnd(event);
            } else {
                this.$pcInputColor.emitValueChangeEnd(event);
            }
        }
    },
    computed: {
        isTextChannel() {
            return this.channel === 'hex' || this.channel === 'css';
        },
        resolvedType() {
            return this.isTextChannel ? 'text' : 'number';
        },
        displayValue() {
            if (this.$pcInputColor.d_value == null || this.$pcInputColor.d_value == undefined) return '';

            return this.$pcInputColor.getInputChannelValue(this.channel);
        },
        range() {
            return this.$pcInputColor.getInputChannelRange(this.channel) ?? {};
        },
        attrs() {
            return mergeProps(this.a11yAttrs, this.ptmi('root'));
        },
        a11yAttrs() {
            return {
                type: this.resolvedType,
                defaultValue: this.displayValue,
                min: this.range.min,
                max: this.range.max,
                step: this.range.step,
                'aria-label': this.channel,
                'data-channel': this.channel,
                'data-p': this.dataP,
                disabled: this.$pcInputColor.disabled || undefined,
                autocomplete: 'off',
                spellcheck: false,
                onInput: this.onInput,
                onChange: this.onChange,
                onBlur: this.onBlur,
                onKeydown: withKeys(this.onKeyDown, ['enter'])
            };
        },
        dataP() {
            return cn({
                disabled: this.$pcInputColor.disabled,
                text: this.isTextChannel,
                numeric: !this.isTextChannel
            });
        }
    }
};
</script>
