<script setup lang="ts">
import { useForm } from '@inertiajs/vue3';
import { Plus, Save, Scissors, Search, Trash2 } from '@lucide/vue';
import { computed, ref, watch } from 'vue';
import { toast } from 'vue-sonner';
import MediaThumbnailCell from '@/components/media/MediaThumbnailCell.vue';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import {
    Empty,
    EmptyDescription,
    EmptyHeader,
    EmptyTitle,
} from '@/components/ui/empty';
import {
    Field,
    FieldError,
    FieldGroup,
    FieldLabel,
    FieldSet,
} from '@/components/ui/field';
import { Input } from '@/components/ui/input';
import { Separator } from '@/components/ui/separator';
import {
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableHeader,
    TableRow,
} from '@/components/ui/table';
import { Textarea } from '@/components/ui/textarea';
import type {
    CuttingMaterialCartItem,
    CuttingProductCatalogItem,
    CuttingRawMaterialCatalogItem,
    CuttingResultCartItem,
} from '@/types/cutting';

const props = defineProps<{
    rawMaterialCatalog: CuttingRawMaterialCatalogItem[];
    productCatalog: CuttingProductCatalogItem[];
    initialData?: {
        description: string;
        materials: CuttingMaterialCartItem[];
        results: CuttingResultCartItem[];
    };
    submitUrl: string;
    method: 'post' | 'put';
    submitLabel: string;
}>();

const materialSearch = ref('');
const productSearch = ref('');
const materialCart = ref<CuttingMaterialCartItem[]>([]);
const resultCart = ref<CuttingResultCartItem[]>([]);

const form = useForm({
    description: '',
});

function populateForm() {
    if (!props.initialData) {
        return;
    }

    form.description = props.initialData.description;
    materialCart.value = props.initialData.materials.map((item) => ({ ...item }));
    resultCart.value = props.initialData.results.map((item) => ({ ...item }));
}

watch(
    () => props.initialData,
    () => {
        populateForm();
    },
    { immediate: true },
);

type CatalogPrice = CuttingRawMaterialCatalogItem['prices'][number];

const filteredRawMaterials = computed(() => {
    const keyword = materialSearch.value.trim().toLowerCase();

    if (!keyword) {
        return props.rawMaterialCatalog;
    }

    return props.rawMaterialCatalog.filter((rawMaterial) =>
        rawMaterial.name.toLowerCase().includes(keyword)
        || rawMaterial.prices.some((price) => price.variant.toLowerCase().includes(keyword)),
    );
});

const filteredProducts = computed(() => {
    const keyword = productSearch.value.trim().toLowerCase();

    if (!keyword) {
        return props.productCatalog;
    }

    return props.productCatalog.filter((product) =>
        product.name.toLowerCase().includes(keyword)
        || product.variants.some((variant) => variant.name.toLowerCase().includes(keyword)),
    );
});

function addMaterial(rawMaterial: CuttingRawMaterialCatalogItem, price: CatalogPrice) {
    const existing = materialCart.value.find(
        (item) => item.raw_material_price_id === price.id,
    );

    if (existing) {
        toast.error('Bahan baku ini sudah ditambahkan.');

        return;
    }

    materialCart.value.push({
        raw_material_price_id: price.id,
        raw_material_name: rawMaterial.name,
        variant: price.variant,
        unit_abbreviation: rawMaterial.unit_abbreviation,
        stock_input: price.stock_input,
        material_usage: '1',
        remaining_material: '0',
        images: price.images ?? [],
    });
}

function removeMaterial(index: number) {
    materialCart.value.splice(index, 1);
}

function addResult(product: CuttingProductCatalogItem, variant: CuttingProductCatalogItem['variants'][number]) {
    const existing = resultCart.value.find(
        (item) => item.product_variant_id === variant.id,
    );

    if (existing) {
        toast.error('Varian produk ini sudah ditambahkan.');

        return;
    }

    resultCart.value.push({
        product_variant_id: variant.id,
        product_name: product.name,
        variant_name: variant.name,
        stock: variant.stock,
        cutting_result: '1',
        warehouse_stock: '1',
        cutting_reject: '0',
        images: variant.images ?? [],
    });
}

function removeResult(index: number) {
    resultCart.value.splice(index, 1);
}

function syncResultTotals(item: CuttingResultCartItem) {
    const total = Number(item.cutting_result) || 0;
    const warehouse = Number(item.warehouse_stock) || 0;
    const reject = Math.max(total - warehouse, 0);

    item.cutting_reject = String(reject);
}

function submit() {
    if (materialCart.value.length === 0) {
        toast.error('Tambahkan minimal satu bahan baku.');

        return;
    }

    if (resultCart.value.length === 0) {
        toast.error('Tambahkan minimal satu hasil produk.');

        return;
    }

    for (const item of resultCart.value) {
        const total = Number(item.cutting_result) || 0;
        const warehouse = Number(item.warehouse_stock) || 0;
        const reject = Number(item.cutting_reject) || 0;

        if (warehouse + reject !== total) {
            toast.error(`Hasil cutting ${item.product_name} - ${item.variant_name} harus sama dengan stok gudang + reject.`);

            return;
        }
    }

    const payload = {
        description: form.description,
        materials: materialCart.value.map((item) => ({
            raw_material_price_id: item.raw_material_price_id,
            material_usage: item.material_usage,
            remaining_material: item.remaining_material,
        })),
        results: resultCart.value.map((item) => ({
            product_variant_id: item.product_variant_id,
            cutting_result: item.cutting_result,
            warehouse_stock: item.warehouse_stock,
            cutting_reject: item.cutting_reject,
        })),
    };

    if (props.method === 'put') {
        form.transform(() => payload).put(props.submitUrl, {
            onError: () => {
                toast.error('Gagal menyimpan data. Periksa kembali formulir.');
            },
        });

        return;
    }

    form.transform(() => payload).post(props.submitUrl, {
        onError: () => {
            toast.error('Gagal menyimpan data. Periksa kembali formulir.');
        },
    });
}
</script>

<template>
    <div class="grid gap-4 xl:grid-cols-[1fr_400px]">
        <div class="space-y-4">
        <Card class="min-w-0">
            <CardHeader class="pb-3">
                <CardTitle class="text-base">Pilih Bahan Baku</CardTitle>
            </CardHeader>
            <CardContent>
                    <div class="space-y-4">
                        <div class="relative">
                            <Search class="absolute top-1/2 left-3 size-4 -translate-y-1/2 text-muted-foreground" />
                            <Input v-model="materialSearch" placeholder="Cari bahan baku..." class="pl-9" />
                        </div>

                        <div v-if="filteredRawMaterials.length === 0" class="py-8">
                            <Empty>
                                <EmptyHeader>
                                    <EmptyTitle>Tidak ada bahan baku ditemukan</EmptyTitle>
                                    <EmptyDescription>
                                        Silakan lakukan pencarian untuk menemukan bahan baku.
                                    </EmptyDescription>
                                </EmptyHeader>
                            </Empty>
                        </div>

                        <div v-else class="space-y-4">
                            <div v-for="rawMaterial in filteredRawMaterials" :key="rawMaterial.id"
                                class="overflow-hidden rounded-md border">
                                <div class="border-b bg-muted/30 px-4 py-3">
                                    <div class="flex flex-wrap items-center gap-2">
                                        <h3 class="font-medium leading-tight">
                                            {{ rawMaterial.name }}
                                        </h3>
                                        <Badge variant="secondary">
                                            {{ rawMaterial.unit_label }}
                                        </Badge>
                                    </div>
                                </div>

                                <Table>
                                    <TableHeader>
                                        <TableRow>
                                            <TableHead>Varian</TableHead>
                                            <TableHead>Stok</TableHead>
                                            <TableHead>Foto</TableHead>
                                            <TableHead class="w-24 text-right" />
                                        </TableRow>
                                    </TableHeader>
                                    <TableBody>
                                        <TableRow v-for="price in rawMaterial.prices" :key="price.id"
                                            class="cursor-pointer hover:bg-muted/30"
                                            @click="addMaterial(rawMaterial, price)">
                                            <TableCell class="font-medium">
                                                {{ price.variant }}
                                            </TableCell>
                                            <TableCell class="tabular-nums">
                                                {{ price.stock_formatted }}
                                            </TableCell>
                                            <TableCell>
                                                <MediaThumbnailCell :items="price.images ?? []" />
                                            </TableCell>
                                            <TableCell class="text-right">
                                                <Button type="button" variant="outline" size="sm"
                                                    @click.stop="addMaterial(rawMaterial, price)">
                                                    <Plus class="size-3.5" />
                                                    Tambah
                                                </Button>
                                            </TableCell>
                                        </TableRow>
                                    </TableBody>
                                </Table>
                            </div>
                        </div>
                    </div>
            </CardContent>
        </Card>

        <Card class="min-w-0">
            <CardHeader class="pb-3">
                <CardTitle class="text-base">Pilih Produk Hasil</CardTitle>
            </CardHeader>
            <CardContent>
                    <div class="space-y-4">
                        <div class="relative">
                            <Search class="absolute top-1/2 left-3 size-4 -translate-y-1/2 text-muted-foreground" />
                            <Input v-model="productSearch" placeholder="Cari produk..." class="pl-9" />
                        </div>

                        <div v-if="filteredProducts.length === 0" class="py-8">
                            <Empty>
                                <EmptyHeader>
                                    <EmptyTitle>Tidak ada produk ditemukan</EmptyTitle>
                                    <EmptyDescription>
                                        Silakan lakukan pencarian untuk menemukan produk.
                                    </EmptyDescription>
                                </EmptyHeader>
                            </Empty>
                        </div>

                        <div v-else class="space-y-4">
                            <div v-for="product in filteredProducts" :key="product.id"
                                class="overflow-hidden rounded-md border">
                                <div class="border-b bg-muted/30 px-4 py-3">
                                    <h3 class="font-medium leading-tight">
                                        {{ product.name }}
                                    </h3>
                                </div>

                                <Table>
                                    <TableHeader>
                                        <TableRow>
                                            <TableHead>Varian</TableHead>
                                            <TableHead>Stok</TableHead>
                                            <TableHead>Foto</TableHead>
                                            <TableHead class="w-24 text-right" />
                                        </TableRow>
                                    </TableHeader>
                                    <TableBody>
                                        <TableRow v-for="variant in product.variants" :key="variant.id"
                                            class="cursor-pointer hover:bg-muted/30"
                                            @click="addResult(product, variant)">
                                            <TableCell class="font-medium">
                                                {{ variant.name }}
                                            </TableCell>
                                            <TableCell class="tabular-nums">
                                                {{ variant.stock }} pcs
                                            </TableCell>
                                            <TableCell>
                                                <MediaThumbnailCell :items="variant.images ?? []" />
                                            </TableCell>
                                            <TableCell class="text-right">
                                                <Button type="button" variant="outline" size="sm"
                                                    @click.stop="addResult(product, variant)">
                                                    <Plus class="size-3.5" />
                                                    Tambah
                                                </Button>
                                            </TableCell>
                                        </TableRow>
                                    </TableBody>
                                </Table>
                            </div>
                        </div>
                    </div>
            </CardContent>
        </Card>
        </div>

        <Card class="h-fit xl:sticky xl:top-4">
            <CardHeader class="pb-3">
                <CardTitle class="flex items-center gap-2 text-base">
                    <Scissors class="size-4" />
                    Ringkasan Cutting
                </CardTitle>
            </CardHeader>
            <CardContent>
                <form @submit.prevent="submit">
                    <FieldGroup>
                        <FieldSet class="grid gap-4">
                            <Field>
                                <FieldLabel for="description">Keterangan</FieldLabel>
                                <Textarea id="description" v-model="form.description"
                                    placeholder="Contoh: Cutting batch pagi" rows="2" />
                                <FieldError :errors="form.errors.description ? [form.errors.description] : []" />
                            </Field>

                            <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="space-y-3">
                                    <div v-for="(item, index) in materialCart" :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="text-destructive hover:text-destructive size-7 shrink-0"
                                                @click="removeMaterial(index)">
                                                <Trash2 class="size-3.5" />
                                            </Button>
                                        </div>

                                        <div class="grid grid-cols-2 gap-2">
                                            <Field>
                                                <FieldLabel class="text-xs">
                                                    Pemakaian ({{ item.unit_abbreviation }})
                                                </FieldLabel>
                                                <Input v-model="item.material_usage" type="number" min="0.0001"
                                                    step="any" class="h-8" />
                                            </Field>
                                            <Field>
                                                <FieldLabel class="text-xs">
                                                    Sisa ({{ item.unit_abbreviation }})
                                                </FieldLabel>
                                                <Input v-model="item.remaining_material" type="number" min="0"
                                                    step="any" class="h-8" />
                                            </Field>
                                        </div>
                                    </div>
                                </div>
                            </div>

                            <Separator />

                            <div class="space-y-2">
                                <p class="text-sm font-medium">
                                    Hasil Produk
                                </p>

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

                                <div v-else class="space-y-3">
                                    <div v-for="(item, index) in resultCart" :key="item.product_variant_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.product_name }}
                                                </p>
                                                <p class="truncate text-xs text-muted-foreground">
                                                    {{ item.variant_name }} · Stok {{ item.stock }} pcs
                                                </p>
                                            </div>
                                            <Button type="button" variant="ghost" size="icon"
                                                class="text-destructive hover:text-destructive size-7 shrink-0"
                                                @click="removeResult(index)">
                                                <Trash2 class="size-3.5" />
                                            </Button>
                                        </div>

                                        <div class="grid grid-cols-3 gap-2">
                                            <Field>
                                                <FieldLabel class="text-xs">Hasil</FieldLabel>
                                                <Input v-model="item.cutting_result" type="number" min="1"
                                                    class="h-8" @change="syncResultTotals(item)" />
                                            </Field>
                                            <Field>
                                                <FieldLabel class="text-xs">Gudang</FieldLabel>
                                                <Input v-model="item.warehouse_stock" type="number" min="0"
                                                    class="h-8" @change="syncResultTotals(item)" />
                                            </Field>
                                            <Field>
                                                <FieldLabel class="text-xs">Reject</FieldLabel>
                                                <Input v-model="item.cutting_reject" type="number" min="0"
                                                    class="h-8" />
                                            </Field>
                                        </div>
                                    </div>
                                </div>
                            </div>

                            <Button type="submit" class="w-full"
                                :disabled="form.processing || materialCart.length === 0 || resultCart.length === 0">
                                <Save class="size-4" />
                                {{ form.processing ? 'Menyimpan...' : submitLabel }}
                            </Button>
                        </FieldSet>
                    </FieldGroup>
                </form>
            </CardContent>
        </Card>
    </div>
</template>
