<script setup lang="ts">
import { ListFilter, Search } from '@lucide/vue';
import { computed } from 'vue';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
    Popover,
    PopoverContent,
    PopoverTrigger,
} from '@/components/ui/popover';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import type { DataTableFilterDef } from '@/types/data-table';

const props = defineProps<{
    filterDefs?: DataTableFilterDef[];
    filterValues?: Record<string, string>;
    searchPlaceholder?: string;
}>();

const search = defineModel<string>('search', { default: '' });

const emit = defineEmits<{
    'filter-change': [key: string, value: string];
    'filters-reset': [];
}>();

const activeFilterCount = computed(() => {
    if (!props.filterDefs?.length || !props.filterValues) {
        return 0;
    }

    return props.filterDefs.filter((filter) => {
        const value = props.filterValues?.[filter.key];

        return value !== undefined && value !== '';
    }).length;
});

function filterValue(key: string): string {
    return props.filterValues?.[key] ?? '';
}

function onFilterChange(key: string, value: string): void {
    emit('filter-change', key, value === 'all' ? '' : value);
}

function resetFilters(): void {
    emit('filters-reset');
}
</script>

<template>
    <div class="flex items-center justify-between gap-4">
        <div class="relative w-full max-w-sm">
            <Search class="text-muted-foreground absolute top-1/2 left-3 size-4 -translate-y-1/2" />
            <Input
                v-model="search"
                type="search"
                :placeholder="searchPlaceholder ?? 'Cari...'"
                class="pl-9"
            />
        </div>

        <Popover v-if="filterDefs?.length">
            <PopoverTrigger as-child>
                <Button variant="outline" class="shrink-0">
                    <ListFilter class="size-4" />
                    Filter
                    <Badge
                        v-if="activeFilterCount > 0"
                        variant="secondary"
                        class="ml-1 size-5 rounded-full px-1 text-xs"
                    >
                        {{ activeFilterCount }}
                    </Badge>
                </Button>
            </PopoverTrigger>
            <PopoverContent align="end" class="w-80 space-y-4 p-4">
                <div class="space-y-1">
                    <h4 class="text-sm font-medium">
                        Filter
                    </h4>
                    <p class="text-muted-foreground text-xs">
                        Sesuaikan filter untuk mempersempit data.
                    </p>
                </div>

                <div
                    v-for="filter in filterDefs"
                    :key="filter.key"
                    class="space-y-2"
                >
                    <Label :for="`filter-${filter.key}`">{{ filter.label }}</Label>

                    <Input
                        v-if="filter.type === 'text'"
                        :id="`filter-${filter.key}`"
                        :model-value="filterValue(filter.key)"
                        :placeholder="filter.placeholder ?? `Filter ${filter.label.toLowerCase()}`"
                        @update:model-value="onFilterChange(filter.key, String($event ?? ''))"
                    />

                    <Select
                        v-else
                        :model-value="filterValue(filter.key) || 'all'"
                        @update:model-value="onFilterChange(filter.key, String($event ?? ''))"
                    >
                        <SelectTrigger :id="`filter-${filter.key}`" class="w-full">
                            <SelectValue :placeholder="filter.placeholder ?? 'Semua'" />
                        </SelectTrigger>
                        <SelectContent>
                            <SelectItem value="all">
                                Semua
                            </SelectItem>
                            <SelectItem
                                v-for="option in filter.options"
                                :key="option.value"
                                :value="option.value"
                            >
                                {{ option.label }}
                            </SelectItem>
                        </SelectContent>
                    </Select>
                </div>

                <Button
                    v-if="activeFilterCount > 0"
                    variant="ghost"
                    size="sm"
                    class="w-full"
                    @click="resetFilters"
                >
                    Reset Filter
                </Button>
            </PopoverContent>
        </Popover>
    </div>
</template>
