<script setup lang="ts">
import { Layers, Trash2 } from '@lucide/vue';
import { computed } from 'vue';
import { DecimalInput } from '@/components/form/decimal-input';
import { NumberInput } from '@/components/form/number-input';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
    Field,
    FieldError,
    FieldLabel,
} from '@/components/ui/field';
import { formErrors } from '@/lib/form';
import type { FormWithErrors } from '@/lib/form';
import type { CuttingMaterialCartItem } from '@/types/cutting';

const props = defineProps<{
    form: FormWithErrors;
    materialCart: CuttingMaterialCartItem[];
}>();

const emit = defineEmits<{
    remove: [index: number];
    'sync-field': [index: number];
    'remove-combination': [combinationId: number];
    'sync-combination-result': [combinationId: number, result: number | null];
}>();

type MaterialGroup = {
    type: 'combination' | 'single';
    combinationId?: number;
    items: Array<{ item: CuttingMaterialCartItem; index: number }>;
};

const materialGroups = computed<MaterialGroup[]>(() => {
    const combinationMap = new Map<number, Array<{ item: CuttingMaterialCartItem; index: number }>>();
    const singleItems: Array<{ item: CuttingMaterialCartItem; index: number }> = [];

    props.materialCart.forEach((item, index) => {
        if (item.combination_id) {
            if (!combinationMap.has(item.combination_id)) {
                combinationMap.set(item.combination_id, []);
            }

            combinationMap.get(item.combination_id)!.push({ item, index });
        } else {
            singleItems.push({ item, index });
        }
    });

    const groups: MaterialGroup[] = [];

    for (const [combinationId, items] of combinationMap) {
        groups.push({
            type: 'combination',
            combinationId,
            items,
        });
    }

    if (singleItems.length > 0) {
        groups.push({
            type: 'single',
            items: singleItems,
        });
    }

    return groups;
});

function getCombinationResult(combinationId: number | undefined): number | null {
    if (!combinationId) {
        return null;
    }

    const item = props.materialCart.find(i => i.combination_id === combinationId);

    return item?.combination_material_result ?? null;
}

function setCombinationResult(combinationId: number | undefined, value: string) {
    if (!combinationId) {
        return;
    }

    const result = value ? Number(value) : null;
    emit('sync-combination-result', combinationId, result);
}
</script>

<template>
    <div class="space-y-2">
        <p class="text-sm font-medium">Bahan Baku</p>

        <div v-if="materialCart.length === 0"
            class="rounded-lg border border-dashed px-4 py-6 text-center text-sm text-muted-foreground">
            Belum ada bahan baku dipilih.
        </div>

        <div v-else class="scrollbar-thin max-h-80 space-y-3 overflow-y-auto overscroll-y-contain">
            <template v-for="group in materialGroups" :key="group.combinationId ?? `single-${group.items[0]?.index}`">
                <div v-if="group.type === 'combination'"
                    class="rounded-lg border-2 border-dashed border-primary/30 p-3">
                    <div class="mb-2 flex items-center justify-between">
                        <div class="flex items-center gap-2">
                            <Layers class="size-4 text-primary" />
                            <span class="text-sm font-medium text-primary">Kombinasi</span>
                            <Badge variant="secondary" class="text-xs">
                                {{ group.items.length }} bahan
                            </Badge>
                        </div>
                        <div class="flex items-center gap-1.5">
                            <div class="flex items-center gap-1" @click.stop>
                                <NumberInput
                                    :model-value="getCombinationResult(group.combinationId)"
                                    class="h-7 w-16"
                                    placeholder="Hasil"
                                    @update:model-value="setCombinationResult(group.combinationId, $event)"
                                />
                                <span class="text-[10px] text-muted-foreground">pcs</span>
                            </div>
                            <Button type="button" variant="ghost" size="icon"
                                class="size-7 shrink-0 text-destructive hover:text-destructive"
                                @click="group.combinationId && emit('remove-combination', group.combinationId)">
                                <Trash2 class="size-3.5" />
                            </Button>
                        </div>
                    </div>

                    <div class="space-y-2">
                        <div v-for="{ item, index } in group.items" :key="item.raw_material_price_id"
                            class="rounded-md border bg-background p-2.5">
                            <div class="mb-1.5 flex items-start justify-between gap-2">
                                <div class="min-w-0">
                                    <p class="truncate text-sm font-medium">
                                        {{ item.raw_material_name }}
                                    </p>
                                    <p class="truncate text-xs text-muted-foreground">
                                        {{ item.variant }} · Stok {{ item.stock_input }} {{ item.unit_abbreviation }}
                                    </p>
                                </div>
                                <Button type="button" variant="ghost" size="icon"
                                    class="size-6 shrink-0 text-destructive hover:text-destructive"
                                    @click="emit('remove', index)">
                                    <Trash2 class="size-3" />
                                </Button>
                            </div>

                            <Field
                                :data-invalid="formErrors(form, `materials.${index}.material_usage`).length > 0 ? 'true' : undefined">
                                <FieldLabel class="text-xs">
                                    Pemakaian ({{ item.unit_abbreviation }})
                                </FieldLabel>
                                <DecimalInput v-model="item.material_usage" class="h-7"
                                    :aria-invalid="formErrors(form, `materials.${index}.material_usage`).length > 0"
                                    @change="emit('sync-field', index)" />
                                <FieldError :errors="formErrors(form, `materials.${index}.material_usage`)"
                                    class="text-[10px] mt-0.5 leading-tight" />
                            </Field>
                        </div>
                    </div>
                </div>

                <div v-else v-for="{ item, index } in group.items" :key="item.raw_material_price_id"
                    class="rounded-lg border p-3">
                    <div class="mb-2 flex items-start justify-between gap-2">
                        <div class="min-w-0">
                            <p class="truncate text-sm font-medium">
                                {{ item.raw_material_name }}
                            </p>
                            <p class="truncate text-xs text-muted-foreground">
                                {{ item.variant }} · Stok {{ item.stock_input }} {{ item.unit_abbreviation }}
                            </p>
                        </div>
                        <Button type="button" variant="ghost" size="icon"
                            class="size-7 shrink-0 text-destructive hover:text-destructive"
                            @click="emit('remove', index)">
                            <Trash2 class="size-3.5" />
                        </Button>
                    </div>

                    <div class="grid grid-cols-2 gap-2">
                        <Field
                            :data-invalid="formErrors(form, `materials.${index}.material_usage`).length > 0 ? 'true' : undefined">
                            <FieldLabel class="text-xs">
                                Pemakaian ({{ item.unit_abbreviation }})
                            </FieldLabel>
                            <DecimalInput v-model="item.material_usage" class="h-8"
                                :aria-invalid="formErrors(form, `materials.${index}.material_usage`).length > 0"
                                @change="emit('sync-field', index)" />
                            <FieldError :errors="formErrors(form, `materials.${index}.material_usage`)"
                                class="text-[10px] mt-0.5 leading-tight" />
                        </Field>
                        <Field
                            :data-invalid="formErrors(form, `materials.${index}.material_result`).length > 0 ? 'true' : undefined">
                            <FieldLabel class="text-xs">
                                Hasil (pcs)
                            </FieldLabel>
                            <NumberInput v-model="item.material_result" class="h-8"
                                :aria-invalid="formErrors(form, `materials.${index}.material_result`).length > 0"
                                @change="emit('sync-field', index)" />
                            <FieldError :errors="formErrors(form, `materials.${index}.material_result`)"
                                class="text-[10px] mt-0.5 leading-tight" />
                        </Field>
                    </div>
                </div>
            </template>
        </div>
    </div>
</template>
