<script setup>
import { markRaw, computed, defineModel } from 'vue';
import { QCheckbox } from 'quasar';
import { useArrayData } from 'composables/useArrayData';

/* basic input */
import VnSelect from 'components/common/VnSelect.vue';
import VnInput from 'components/common/VnInput.vue';
import VnInputDate from 'components/common/VnInputDate.vue';
import VnInputTime from 'components/common/VnInputTime.vue';
import VnTableColumn from 'components/VnTable/VnColumn.vue';

const $props = defineProps({
    column: {
        type: Object,
        required: true,
    },
    showTitle: {
        type: Boolean,
        default: false,
    },
    dataKey: {
        type: String,
        required: true,
    },
    searchUrl: {
        type: String,
        default: 'params',
    },
});

defineExpose({ addFilter, props: $props });

const model = defineModel(undefined, { required: true });
const arrayData = useArrayData($props.dataKey, { searchUrl: $props.searchUrl });
const columnFilter = computed(() => $props.column?.columnFilter);

const updateEvent = { 'update:modelValue': addFilter };
const enterEvent = {
    'keyup.enter': () => addFilter(model.value),
    remove: () => addFilter(null),
};

const defaultAttrs = {
    filled: !$props.showTitle,
    class: 'q-px-xs q-pb-xs q-pt-none fit',
    dense: true,
};

const forceAttrs = {
    label: $props.showTitle ? '' : columnFilter.value?.label ?? $props.column.label,
};

const selectComponent = {
    component: markRaw(VnSelect),
    event: updateEvent,
    attrs: {
        class: 'q-px-sm q-pb-xs q-pt-none fit',
        dense: true,
        filled: !$props.showTitle,
    },
    forceAttrs,
};

const components = {
    input: {
        component: markRaw(VnInput),
        event: enterEvent,
        attrs: {
            ...defaultAttrs,
            clearable: true,
        },
        forceAttrs,
    },
    number: {
        component: markRaw(VnInput),
        event: enterEvent,
        attrs: {
            ...defaultAttrs,
            clearable: true,
            type: 'number',
        },
        forceAttrs,
    },
    date: {
        component: markRaw(VnInputDate),
        event: updateEvent,
        attrs: {
            ...defaultAttrs,
            style: 'min-width: 150px',
        },
        forceAttrs,
    },
    time: {
        component: markRaw(VnInputTime),
        event: updateEvent,
        attrs: {
            ...defaultAttrs,
            disable: !$props.isEditable,
        },
        forceAttrs: {
            label: $props.showLabel && $props.column.label,
        },
    },
    checkbox: {
        component: markRaw(QCheckbox),
        event: updateEvent,
        attrs: {
            dense: true,
            class: $props.showTitle ? 'q-py-sm q-mt-md' : 'q-px-md q-py-xs fit',
            'toggle-indeterminate': true,
        },
        forceAttrs,
    },
    select: selectComponent,
    rawSelect: selectComponent,
};

async function addFilter(value, name) {
    value ??= undefined;
    if (value && typeof value === 'object') value = model.value;
    value = value === '' ? undefined : value;
    let field = columnFilter.value?.name ?? $props.column.name ?? name;

    if (columnFilter.value?.inWhere) {
        if (columnFilter.value.alias) field = columnFilter.value.alias + '.' + field;
        return await arrayData.addFilterWhere({ [field]: value });
    }
    await arrayData.addFilter({ params: { [field]: value } });
}

function alignRow() {
    switch ($props.column.align) {
        case 'left':
            return 'justify-start items-start';
        case 'right':
            return 'justify-end items-end';
        default:
            return 'flex-center';
    }
}

const showFilter = computed(
    () => $props.column?.columnFilter !== false && $props.column.name != 'tableActions'
);
</script>
<template>
    <div
        v-if="showFilter"
        class="full-width"
        :class="alignRow()"
        style="max-height: 45px; overflow: hidden"
    >
        <VnTableColumn
            :column="$props.column"
            default="input"
            v-model="model"
            :components="components"
            component-prop="columnFilter"
        />
    </div>
</template>
