import { Head, Link, useForm } from '@inertiajs/react';
import { ArrowLeft, Check, ImagePlus, Loader, Minus, Plus, Save, Search, ShoppingCart, Tag, Trash2, X } from 'lucide-react';
import React, { useMemo, useState } from 'react';
import { NumericFormat } from 'react-number-format';
import { toast } from 'sonner';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import {
    Dialog,
    DialogContent,
    DialogFooter,
    DialogHeader,
    DialogTitle,
} from "@/components/ui/dialog";
import { Field, FieldError } from "@/components/ui/field";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { ScrollArea } from '@/components/ui/scroll-area';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from "@/components/ui/select";
import {
    Sheet,
    SheetContent,
    SheetTrigger
} from "@/components/ui/sheet";
import { cn } from '@/lib/utils';
import { formatCurrency, formatNumber } from '@/lib/formatters';
import * as orderRoutes from '@/routes/order';
import type { Product } from '@/types';
import type { Order } from '@/types/order';

type EnumOption = { value: string, label: string };

export default function OrderEdit({ order, products, orderStatus, orderChannels, paymentMethods, priceTypes }: {
    order: Order,
    products: Product[],
    orderStatus: EnumOption[],
    orderChannels: EnumOption[],
    paymentMethods: EnumOption[],
    priceTypes: EnumOption[]
}) {
    const [search, setSearch] = useState('');
    const [selectedCategory, setSelectedCategory] = useState<string>('all');
    const [qtyDialogIndex, setQtyDialogIndex] = useState<{ product_id: number, price_type: string } | null>(null);
    const [qtyInputValue, setQtyInputValue] = useState('');
    const [globalPriceType, setGlobalPriceType] = useState<string>('retail');

    const categories = useMemo(() => {
        const map = new Map<number, string>();
        products.forEach(p => p.categories?.forEach(c => map.set(c.id, c.name)));

        return Array.from(map.entries()).map(([id, name]) => ({ id, name }));
    }, [products]);

    const { data, setData, patch, processing, errors } = useForm({
        invoice_number: order.invoice_number,
        customer_name: order.customer_name,
        discount: order.discount,
        payment: order.payment,
        payment_method: order.payment_method,
        order_status: order.order_status,
        order_channel: order.order_channel,
        items: (order.items?.map(item => ({
            product_id: item.product_id,
            qty: item.qty,
            price: item.price,
            total: item.total,
            price_type: item.price_type,
            product: products.find(p => p.id === item.product_id) || item.product
        })) ?? []) as any[],
    });

    const filteredProducts = products.filter(p => {
        const matchesSearch = p.name.toLowerCase().includes(search.toLowerCase());
        const matchesCategory = selectedCategory === 'all' || p.categories?.some(c => String(c.id) === selectedCategory);

        return matchesSearch && matchesCategory;
    });

    const findItemIndex = (productId: number, priceType: string) =>
        data.items.findIndex(item => item.product_id === productId && item.price_type === priceType);

    const getProductPrice = (product: Product, priceType: string) => {
        return product.prices?.find(p => p.price_type === priceType)?.price || 0;
    };

    const addToCart = (product: Product, priceType: string) => {
        const index = findItemIndex(product.id, priceType);
        const price = getProductPrice(product, priceType);

        if (index > -1) {
            const newItems = [...data.items];
            newItems[index].qty += 1;
            newItems[index].total = newItems[index].qty * newItems[index].price;
            setData('items', newItems);
        } else {
            setData('items', [
                ...data.items,
                {
                    product_id: product.id,
                    qty: 1,
                    price: price,
                    total: price,
                    price_type: priceType,
                    product: product
                }
            ]);
        }
    };

    const decreaseQuantity = (productId: number, priceType: string, e: React.MouseEvent) => {
        e.stopPropagation();
        const index = findItemIndex(productId, priceType);

        if (index === -1) {
return;
}

        const newItems = [...data.items];

        if (newItems[index].qty <= 1) {
            newItems.splice(index, 1);
        } else {
            newItems[index].qty -= 1;
            newItems[index].total = newItems[index].qty * newItems[index].price;
        }

        setData('items', newItems);
    };

    const increaseQuantity = (productId: number, priceType: string, e: React.MouseEvent) => {
        e.stopPropagation();
        const product = products.find(p => p.id === productId);

        if (product) {
addToCart(product, priceType);
}
    };

    const removeFromCart = (productId: number, priceType: string) => {
        const newItems = data.items.filter(item => !(item.product_id === productId && item.price_type === priceType));
        setData('items', newItems);
    };

    const updateCartQuantity = (productId: number, priceType: string, qty: number) => {
        if (qty < 1) {
return;
}

        const index = findItemIndex(productId, priceType);

        if (index > -1) {
            const newItems = [...data.items];
            newItems[index].qty = qty;
            newItems[index].total = qty * newItems[index].price;
            setData('items', newItems);
        }
    };

    const openQtyDialog = (item: any, e: React.MouseEvent) => {
        e.stopPropagation();
        setQtyInputValue(String(item.qty));
        setQtyDialogIndex({ product_id: item.product_id, price_type: item.price_type });
    };

    const confirmQty = () => {
        const val = parseInt(qtyInputValue);

        if (!isNaN(val) && val >= 1 && qtyDialogIndex) {
            updateCartQuantity(qtyDialogIndex.product_id, qtyDialogIndex.price_type, val);
        }

        setQtyDialogIndex(null);
    };

    const onSubmit = (e: React.FormEvent) => {
        e.preventDefault();

        if (data.items.length === 0) {
            toast.error('Pilih minimal satu produk');

            return;
        }

        patch(orderRoutes.update(order.id).url, {
            onSuccess: (response: any) => {
                toast.success(response.props.flash.success);
            },
        });
    };

    const subtotal = useMemo(() => {
        return data.items.reduce((acc, item) => acc + item.total, 0);
    }, [data.items]);

    const total = subtotal - data.discount;
    const change = data.payment - total;
    const cartTotalItems = data.items.reduce((a, i) => a + i.qty, 0);

    const PriceTypeLabel = ({ type }: { type: string }) => {
        const option = priceTypes.find(opt => opt.value === type);

        return option ? option.label : type;
    };

    const CartFormContent = () => (
        <div className="flex flex-col h-full">
            <CardHeader className="border-b py-4 flex-row items-center justify-between shrink-0">
                <CardTitle className="flex items-center gap-2 text-base">
                    <ShoppingCart className="h-4 w-4" />
                    Keranjang
                </CardTitle>
                <Badge className="rounded-full font-bold">
                    {cartTotalItems} pcs
                </Badge>
            </CardHeader>

            <ScrollArea className="flex-1 min-h-0">
                <CardContent className="p-0">
                    {data.items.length === 0 ? (
                        <div className="py-16 text-center text-muted-foreground">
                            <ShoppingCart className="h-10 w-10 mx-auto mb-3 opacity-20" />
                            <p className="text-sm">Keranjang masih kosong</p>
                        </div>
                    ) : (
                        <div className="divide-y divide-border">
                            {data.items.map((item, idx) => (
                                <div key={idx} className="p-4 space-y-2.5">
                                    <div className="flex gap-3">
                                        <div className="h-11 w-11 rounded-md bg-muted overflow-hidden shrink-0 border">
                                            {item.product?.thumbnail_url ? (
                                                <img src={item.product.thumbnail_url} className="h-full w-full object-cover" alt={item.product.name} />
                                            ) : (
                                                <div className="h-full w-full flex items-center justify-center">
                                                    <ImagePlus className="h-4 w-4 text-muted-foreground/50" />
                                                </div>
                                            )}
                                        </div>
                                        <div className="flex-1 min-w-0">
                                            <h4 className="text-sm font-semibold leading-tight line-clamp-1">{item.product?.name}</h4>
                                            <div className="flex items-center gap-1.5 mt-0.5">
                                                <Badge variant="outline" className="text-[10px] px-1 py-0 h-4 bg-primary/5 border-primary/20 text-primary">
                                                    <PriceTypeLabel type={item.price_type} />
                                                </Badge>
                                                <p className="text-xs text-primary font-medium">
                                                    {formatCurrency(item.total)}
                                                </p>
                                            </div>
                                        </div>
                                        <Button
                                            type="button"
                                            variant="ghost"
                                            size="icon"
                                            className="h-7 w-7 shrink-0 text-muted-foreground hover:text-red-500 hover:bg-red-50 dark:hover:bg-red-950/20"
                                            onClick={() => removeFromCart(item.product_id, item.price_type)}
                                        >
                                            <Trash2 className="h-3.5 w-3.5" />
                                        </Button>
                                    </div>
                                    <div className="flex items-center gap-2 text-xs text-muted-foreground">
                                        <div className="flex items-center bg-muted/50 rounded-lg border px-1">
                                            <button type="button" onClick={(e) => decreaseQuantity(item.product_id, item.price_type, e)} className="p-1 hover:text-primary"><Minus className="h-3 w-3" /></button>
                                            <span className="px-2 font-medium text-foreground">{item.qty}</span>
                                            <button type="button" onClick={(e) => increaseQuantity(item.product_id, item.price_type, e)} className="p-1 hover:text-primary"><Plus className="h-3 w-3" /></button>
                                        </div>
                                        <span>×</span>
                                        <span className="font-mono">
                                            {formatCurrency(item.price)}
                                        </span>
                                    </div>
                                </div>
                            ))}
                        </div>
                    )}
                </CardContent>
            </ScrollArea>

            <div className="p-4 border-t bg-muted/10 space-y-3 shrink-0">
                <div className="grid grid-cols-2 gap-3">
                    <Field>
                        <Label htmlFor='customer_name' className="text-xs text-muted-foreground" required>Pelanggan</Label>
                        <Input id='customer_name' className="h-8 text-xs" value={data.customer_name} onChange={e => setData('customer_name', e.target.value)} />
                        <FieldError error={errors.customer_name} label="Pelanggan" className="text-xs" />
                    </Field>
                    <Field>
                        <Label className="text-xs text-muted-foreground" required>Channel</Label>
                        <Select value={data.order_channel} onValueChange={val => setData('order_channel', val as any)}>
                            <SelectTrigger className="h-8 text-xs"><SelectValue /></SelectTrigger>
                            <SelectContent>
                                {orderChannels.map(opt => (
                                    <SelectItem key={opt.value} value={opt.value}>{opt.label}</SelectItem>
                                ))}
                            </SelectContent>
                        </Select>
                        <FieldError error={errors.order_channel} label="Channel" className="text-xs" />
                    </Field>
                </div>

                <div className="grid grid-cols-2 gap-3">
                    <Field>
                        <Label className="text-xs text-muted-foreground" required>Metode Bayar</Label>
                        <Select value={data.payment_method} onValueChange={val => setData('payment_method', val as any)}>
                            <SelectTrigger className="h-8 text-xs"><SelectValue /></SelectTrigger>
                            <SelectContent>
                                {paymentMethods.map(opt => (
                                    <SelectItem key={opt.value} value={opt.value}>{opt.label}</SelectItem>
                                ))}
                            </SelectContent>
                        </Select>
                        <FieldError error={errors.payment_method} label="Metode Bayar" className="text-xs" />
                    </Field>
                    <Field>
                        <Label className="text-xs text-muted-foreground" required>Status</Label>
                        <Select value={data.order_status} onValueChange={val => setData('order_status', val as any)}>
                            <SelectTrigger className="h-8 text-xs"><SelectValue /></SelectTrigger>
                            <SelectContent>
                                {orderStatus.map(opt => (
                                    <SelectItem key={opt.value} value={opt.value}>{opt.label}</SelectItem>
                                ))}
                            </SelectContent>
                        </Select>
                        <FieldError error={errors.order_status} label="Status" className="text-xs" />
                    </Field>
                </div>

                <div className="space-y-1.5 pt-2 border-t border-dashed text-xs">
                    <div className="flex justify-between">
                        <span className="text-muted-foreground">Subtotal</span>
                        <span className="font-medium">{formatCurrency(subtotal)}</span>
                    </div>
                    <div className="flex justify-between items-center">
                        <span className="text-muted-foreground">Potongan / Diskon</span>
                        <div className="flex items-center gap-2">
                            <NumericFormat
                                id="discount"
                                customInput={Input}
                                thousandSeparator="."
                                decimalSeparator=","
                                prefix="Rp "
                                value={data.discount}
                                onValueChange={(values) => {
                                    setData('discount', values.floatValue || 0)
                                }}
                                placeholder="Rp 0"
                                autoComplete='off'
                            />
                        </div>
                        <FieldError error={errors.discount} label="Potongan / Diskon" className="text-xs" />
                    </div>
                </div>

                <div className="flex justify-between text-lg font-bold border-t pt-2">
                    <span className="">Total</span>
                    <span className="font-medium">{formatCurrency(total)}</span>
                </div>

                <div className="space-y-2">
                    <Field>
                        <Label className="text-xs text-muted-foreground">Uang Bayar</Label>
                        <NumericFormat
                            id="payment"
                            customInput={Input}
                            thousandSeparator="."
                            decimalSeparator=","
                            prefix="Rp "
                            value={data.payment}
                            onValueChange={(values) => {
                                setData('payment', values.floatValue || 0)
                            }}
                            placeholder="Rp 0"
                            autoComplete='off'
                        />
                    </Field>
                    {change >= 0 && data.payment > 0 && (
                        <div className="flex justify-between items-center p-2 rounded bg-green-500/10 border border-green-500/20 text-green-600 dark:text-green-400">
                            <span className="text-xs font-bold uppercase">Kembalian</span>
                            <span className="text-lg font-bold">{formatCurrency(change)}</span>
                        </div>
                    )}
                </div>

                <Button
                    type="submit"
                    className="w-full h-10 font-semibold shadow gap-2"
                    disabled={processing || data.items.length === 0}
                    onClick={() => {
                        if (data.items.length > 0) {
                            onSubmit({ preventDefault: () => { } } as any)
                        }
                    }}
                >
                    {processing ? <Loader className="h-4 w-4 animate-spin" /> : <Save className="h-4 w-4" />}
                    {processing ? 'Menyimpan...' : 'Simpan'}
                </Button>
            </div>
        </div>
    );

    return (
        <div className="flex flex-col gap-6 p-6 lg:h-[calc(100vh-64px)] lg:overflow-hidden">
            <Head title="Ubah Pesanan" />

            <div className="flex items-center justify-between shrink-0">
                <h1 className="text-3xl font-bold tracking-tight">Ubah Pesanan</h1>
                <Link href={orderRoutes.index().url}>
                    <Button variant='outline' className="gap-2">
                        <ArrowLeft className="size-4" />
                        Kembali
                    </Button>
                </Link>
            </div>

            <div className="flex-1 min-h-0 grid grid-cols-1 lg:grid-cols-12 gap-6 pb-20 lg:pb-0">
                <div className="lg:col-span-8 flex flex-col gap-5 h-full min-h-0">
                    <div className="flex flex-col sm:flex-row gap-2 shrink-0">
                        <div className="relative flex-1">
                            <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground pointer-events-none" />
                            <Input
                                placeholder="Cari nama produk..."
                                className="pl-10 h-10"
                                value={search}
                                onChange={e => setSearch(e.target.value)}
                            />
                        </div>
                        <div className="flex gap-2">
                            <Select value={selectedCategory} onValueChange={setSelectedCategory}>
                                <SelectTrigger className="w-full sm:w-40 h-10">
                                    <SelectValue placeholder="Kategori" />
                                </SelectTrigger>
                                <SelectContent>
                                    <SelectItem value="all">Semua</SelectItem>
                                    {categories.map(cat => (
                                        <SelectItem key={cat.id} value={String(cat.id)}>{cat.name}</SelectItem>
                                    ))}
                                </SelectContent>
                            </Select>
                            <Select value={globalPriceType} onValueChange={setGlobalPriceType}>
                                <SelectTrigger className="w-full sm:w-40 h-10 bg-primary/5 text-primary border-primary/20 font-bold">
                                    <Tag className="mr-2 h-4 w-4" />
                                    <SelectValue />
                                </SelectTrigger>
                                <SelectContent>
                                    {priceTypes.filter(t => t.value !== 'purchase').map(opt => (
                                        <SelectItem key={opt.value} value={opt.value}>{opt.label}</SelectItem>
                                    ))}
                                </SelectContent>
                            </Select>
                        </div>
                    </div>

                    <ScrollArea className="flex-1 h-full pr-4">
                        <div className="grid grid-cols-2 sm:grid-cols-3 xl:grid-cols-4 gap-4 pb-10">
                            {filteredProducts.map((product) => {
                                const index = findItemIndex(product.id, globalPriceType);
                                const cartItem = index > -1 ? data.items[index] : null;
                                const currentPrice = getProductPrice(product, globalPriceType);

                                return (
                                    <Card
                                        key={product.id}
                                        className={cn(
                                            "group cursor-pointer transition-all duration-200 bg-card border p-0",
                                            "hover:shadow-lg",
                                            cartItem
                                                ? "border-primary shadow-md"
                                                : "shadow-sm hover:border-primary/50"
                                        )}
                                        onClick={() => addToCart(product, globalPriceType)}
                                    >
                                        <CardContent className="p-4 flex flex-col gap-3">
                                            <div className="-mx-4 -mt-4 aspect-[4/3] overflow-hidden bg-muted/50 rounded-t-xl relative">
                                                {product.thumbnail_url ? (
                                                    <img
                                                        src={product.thumbnail_url}
                                                        alt={product.name}
                                                        className="h-full w-full object-cover transition-transform duration-300 group-hover:scale-110"
                                                    />
                                                ) : (
                                                    <div className="h-full w-full flex items-center justify-center">
                                                        <ImagePlus className="h-10 w-10 text-muted-foreground/30" />
                                                    </div>
                                                )}
                                                {cartItem && (
                                                    <div className="absolute top-2 right-2 flex items-center justify-center bg-primary text-primary-foreground text-[10px] font-bold h-6 min-w-6 px-1 rounded-full shadow-lg">
                                                        {cartItem.qty}
                                                    </div>
                                                )}
                                            </div>

                                            <div>
                                                <div className="flex flex-wrap gap-1 mb-1.5">
                                                    {product.categories?.map(cat => (
                                                        <Badge key={cat.id} variant="outline" className="text-[10px] h-4 px-1.5 bg-muted/50">
                                                            {cat.name}
                                                        </Badge>
                                                    ))}
                                                </div>
                                                <h3 className="font-bold text-sm leading-snug line-clamp-2 min-h-[2.5rem]">
                                                    {product.name}
                                                </h3>
                                            </div>

                                            {/* Price + Stepper */}
                                            <div
                                                className="flex flex-col sm:flex-row sm:items-center justify-between gap-3 mt-auto pt-2 border-t"
                                                onClick={e => e.stopPropagation()}
                                            >
                                                <div className="flex flex-col flex-1 min-w-0">
                                                    <span className="text-[10px] uppercase font-bold text-muted-foreground">Harga</span>
                                                    <span className="text-sm font-bold text-primary tabular-nums truncate block">
                                                        {formatCurrency(currentPrice)}
                                                    </span>
                                                </div>
                                                <div className="flex items-center gap-1 bg-muted/50 rounded-xl sm:rounded-full p-1 sm:p-0.5 shrink-0 w-full sm:w-auto justify-between sm:justify-end border border-transparent hover:border-primary/20 transition-colors">
                                                    <button
                                                        type="button"
                                                        className={cn(
                                                            "h-8 w-8 sm:h-6 sm:w-6 rounded-lg sm:rounded-full flex items-center justify-center transition-all",
                                                            cartItem
                                                                ? "bg-background text-primary shadow-sm hover:bg-primary hover:text-primary-foreground"
                                                                : "text-muted-foreground/30 cursor-not-allowed"
                                                        )}
                                                        disabled={!cartItem}
                                                        onClick={(e) => cartItem && decreaseQuantity(product.id, globalPriceType, e)}
                                                    >
                                                        <Minus className="h-3.5 w-3.5 sm:h-3 sm:w-3" />
                                                    </button>
                                                    <button
                                                        type="button"
                                                        className={cn(
                                                            "flex-1 sm:flex-none sm:min-w-[36px] px-1 text-center text-sm font-bold tabular-nums transition-colors",
                                                            cartItem ? "text-foreground hover:text-primary cursor-pointer" : "text-muted-foreground/40 cursor-default"
                                                        )}
                                                        onClick={(e) => {
                                                            if (!cartItem) {
return;
}

                                                            openQtyDialog(cartItem, e);
                                                        }}
                                                    >
                                                        {cartItem?.qty ?? 0}
                                                    </button>
                                                    <button
                                                        type="button"
                                                        className="h-8 w-8 sm:h-6 sm:w-6 rounded-lg sm:rounded-full bg-primary text-primary-foreground flex items-center justify-center hover:bg-primary/80 transition-all shadow-sm"
                                                        onClick={(e) => {
                                                            e.stopPropagation();
                                                            cartItem ? increaseQuantity(product.id, globalPriceType, e) : addToCart(product, globalPriceType);
                                                        }}
                                                    >
                                                        <Plus className="h-3.5 w-3.5 sm:h-3 sm:w-3" />
                                                    </button>
                                                </div>
                                            </div>
                                        </CardContent>
                                    </Card>
                                );
                            })}
                        </div>
                    </ScrollArea>
                </div>

                <div className="hidden lg:block lg:col-span-4 h-full min-h-0">
                    <Card className="border shadow-2xl bg-card overflow-hidden h-full flex flex-col border-primary/10">
                        {CartFormContent()}
                    </Card>
                </div>

                <div className="lg:hidden fixed bottom-6 left-0 right-0 px-6 z-50 pointer-events-none">
                    <div className="max-w-md mx-auto pointer-events-auto">
                        <Sheet>
                            <SheetTrigger asChild>
                                <Button
                                    size="lg"
                                    className="w-full rounded-full shadow-2xl h-14 flex items-center justify-between px-6 bg-primary"
                                >
                                    <div className="flex items-center gap-3">
                                        <div className="bg-primary-foreground/20 rounded-full h-8 w-8 flex items-center justify-center">
                                            <ShoppingCart className="h-4 w-4" />
                                        </div>
                                        <div className="text-left leading-tight">
                                            <p className="text-[10px] opacity-80 uppercase font-bold tracking-wider">Keranjang</p>
                                            <p className="text-sm font-bold">{cartTotalItems} Item</p>
                                        </div>
                                    </div>
                                    <div className="text-right">
                                        <p className="text-[10px] opacity-80 uppercase font-bold tracking-wider">Total</p>
                                        <p className="text-sm font-bold">{formatCurrency(total)}</p>
                                    </div>
                                </Button>
                            </SheetTrigger>
                            <SheetContent side="bottom" showCloseButton={false} className="p-0 !h-[90vh] rounded-t-[2.5rem] flex flex-col overflow-hidden">
                                {CartFormContent()}
                            </SheetContent>
                        </Sheet>
                    </div>
                </div>
            </div>

            {/* Quantity Input Dialog */}
            <Dialog open={qtyDialogIndex !== null} onOpenChange={(open) => {
 if (!open) {
setQtyDialogIndex(null);
} 
}}>
                <DialogContent className="max-w-xs">
                    <DialogHeader>
                        <DialogTitle>Ubah Jumlah</DialogTitle>
                    </DialogHeader>
                    <div className="py-2">
                        <Label className="text-sm mb-2 block">
                            {qtyDialogIndex !== null ? data.items.find(i => i.product_id === qtyDialogIndex.product_id && i.price_type === qtyDialogIndex.price_type)?.product?.name : ''}
                        </Label>
                        <Input
                            type="number"
                            min="1"
                            value={qtyInputValue}
                            onChange={e => setQtyInputValue(e.target.value)}
                            onKeyDown={e => {
 if (e.key === 'Enter') {
confirmQty();
} 
}}
                            className="text-lg font-bold"
                            autoFocus
                        />
                    </div>
                    <DialogFooter>
                        <Button variant="outline" className="gap-2" onClick={() => setQtyDialogIndex(null)}>
                            <X className="size-4" />
                            Batal
                        </Button>
                        <Button className="gap-2" onClick={confirmQty}>
                            <Check className="size-4" />
                            Konfirmasi
                        </Button>
                    </DialogFooter>
                </DialogContent>
            </Dialog>
        </div>
    );
}

OrderEdit.layout = {
    breadcrumbs: [
        { title: 'Kelola' },
    ],
};
