import { ConfirmDialog } from '@/components/confirm-dialog';
import type { PaginationState } from '@/components/data-table';
import { DataTable } from '@/components/data-table';
import InputError from '@/components/input-error';
import { PhoneNumberInput } from '@/components/phone-number-input';
import { Button } from '@/components/ui/button';
import {
    Dialog,
    DialogContent,
    DialogFooter,
    DialogHeader,
    DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
    index as customerIndex,
    destroy,
    store,
    update,
} from '@/routes/admin/master/customers';
import { Form, Head, router } from '@inertiajs/react';
import { Plus } from 'lucide-react';
import { useCallback, useState } from 'react';
import type { Customer } from './columns';
import { createCustomerColumns } from './columns';

type Props = {
    customers: {
        data: Customer[];
        current_page: number;
        last_page: number;
        per_page: number;
        total: number;
    };
};

export default function CustomerIndex({ customers }: Props) {
    const [createOpen, setCreateOpen] = useState(false);
    const [editing, setEditing] = useState<Customer | null>(null);
    const [deleting, setDeleting] = useState<Customer | null>(null);
    const [search, setSearch] = useState('');
    const pagination: PaginationState = {
        current_page: customers.current_page,
        last_page: customers.last_page,
        per_page: customers.per_page,
        total: customers.total,
    };

    function handlePageChange(page: number) {
        router.get(
            customerIndex.url(),
            {
                page,
                per_page: pagination.per_page,
                search,
            },
            {
                preserveState: true,
                replace: true,
            },
        );
    }

    function handlePerPageChange(perPage: number) {
        router.get(
            customerIndex.url(),
            {
                page: 1,
                per_page: perPage,
                search,
            },
            {
                preserveState: true,
                replace: true,
            },
        );
    }

    const handleSearchChange = useCallback(
        (value: string) => {
            setSearch(value);
            router.get(
                customerIndex.url(),
                {
                    page: 1,
                    per_page: pagination.per_page,
                    search: value,
                },
                {
                    preserveState: true,
                    replace: true,
                },
            );
        },
        [pagination.per_page],
    );

    function handleDelete() {
        if (!deleting) {
            return;
        }

        router.delete(destroy(deleting.id), {
            onSuccess: () => setDeleting(null),
        });
    }

    const columns = createCustomerColumns({
        handleEdit: (customer) => setEditing(customer),
        handleDeleteClick: (customer) => setDeleting(customer),
    });

    return (
        <>
            <Head title="Customer" />

            <div className="flex h-full flex-1 flex-col gap-6 overflow-x-auto p-4 md:p-6">
                <div className="flex items-center justify-between">
                    <div>
                        <h2 className="text-2xl font-semibold tracking-tight">
                            Customer
                        </h2>
                    </div>
                    <Dialog open={createOpen} onOpenChange={setCreateOpen}>
                        <Button asChild>
                            <button
                                type="button"
                                onClick={() => setCreateOpen(true)}
                            >
                                <Plus className="h-4 w-4" />
                                Tambah
                            </button>
                        </Button>
                        <DialogContent>
                            <Form
                                action={store()}
                                resetOnSuccess
                                onSuccess={() => setCreateOpen(false)}
                            >
                                {({ errors, processing }) => {
                                    return (
                                        <>
                                            <DialogHeader>
                                                <DialogTitle>
                                                    Tambah Customer
                                                </DialogTitle>
                                            </DialogHeader>
                                            <div className="grid gap-4 py-4">
                                                <div className="grid gap-2">
                                                    <Label htmlFor="name">
                                                        Nama{' '}
                                                        <span className="text-destructive">
                                                            *
                                                        </span>
                                                    </Label>
                                                    <Input
                                                        id="name"
                                                        name="name"
                                                        placeholder="Masukkan nama customer"
                                                    />
                                                    <InputError
                                                        message={errors.name}
                                                    />
                                                </div>
                                                <div className="grid gap-2">
                                                    <Label htmlFor="phone_number">
                                                        No. Telepon
                                                    </Label>
                                                    <PhoneNumberInput name="phone_number" />
                                                    <InputError
                                                        message={
                                                            errors.phone_number
                                                        }
                                                    />
                                                </div>
                                                <div className="grid gap-2">
                                                    <Label htmlFor="address">
                                                        Alamat
                                                    </Label>
                                                    <Input
                                                        id="address"
                                                        name="address"
                                                        placeholder="Masukkan alamat"
                                                    />
                                                    <InputError
                                                        message={errors.address}
                                                    />
                                                </div>
                                            </div>
                                            <DialogFooter>
                                                <Button
                                                    type="button"
                                                    variant="outline"
                                                    onClick={() =>
                                                        setCreateOpen(false)
                                                    }
                                                >
                                                    Batal
                                                </Button>
                                                <Button
                                                    type="submit"
                                                    disabled={processing}
                                                >
                                                    {processing
                                                        ? 'Menyimpan...'
                                                        : 'Simpan'}
                                                </Button>
                                            </DialogFooter>
                                        </>
                                    );
                                }}
                            </Form>
                        </DialogContent>
                    </Dialog>
                </div>

                <DataTable
                    columns={columns}
                    data={customers.data}
                    searchKey="name"
                    searchPlaceholder="Cari customer..."
                    emptyText="Belum ada data customer."
                    pagination={pagination}
                    onPageChange={handlePageChange}
                    onPerPageChange={handlePerPageChange}
                    onSearchChange={handleSearchChange}
                    searchValue={search}
                />

                <Dialog
                    open={editing !== null}
                    onOpenChange={(open) => {
                        if (!open) {
                            setEditing(null);
                        }
                    }}
                >
                    <DialogContent>
                        {editing && (
                            <Form
                                action={update(editing.id)}
                                resetOnSuccess
                                onSuccess={() => setEditing(null)}
                            >
                                {({ errors, processing }) => {
                                    return (
                                        <>
                                            <DialogHeader>
                                                <DialogTitle>
                                                    Edit Customer
                                                </DialogTitle>
                                            </DialogHeader>
                                            <div className="grid gap-4 py-4">
                                                <div className="grid gap-2">
                                                    <Label htmlFor="edit-name">
                                                        Nama{' '}
                                                        <span className="text-destructive">
                                                            *
                                                        </span>
                                                    </Label>
                                                    <Input
                                                        id="edit-name"
                                                        name="name"
                                                        placeholder="Masukkan nama customer"
                                                        defaultValue={
                                                            editing.name
                                                        }
                                                    />
                                                    <InputError
                                                        message={errors.name}
                                                    />
                                                </div>
                                                <div className="grid gap-2">
                                                    <Label htmlFor="edit-phone_number">
                                                        No. Telepon
                                                    </Label>
                                                    <PhoneNumberInput name="phone_number" defaultValue={editing.phone_number} />
                                                    <InputError
                                                        message={
                                                            errors.phone_number
                                                        }
                                                    />
                                                </div>
                                                <div className="grid gap-2">
                                                    <Label htmlFor="edit-address">
                                                        Alamat
                                                    </Label>
                                                    <Input
                                                        id="edit-address"
                                                        name="address"
                                                        placeholder="Masukkan alamat"
                                                        defaultValue={
                                                            editing.address ??
                                                            ''
                                                        }
                                                    />
                                                    <InputError
                                                        message={errors.address}
                                                    />
                                                </div>
                                            </div>
                                            <DialogFooter>
                                                <Button
                                                    type="button"
                                                    variant="outline"
                                                    onClick={() => {
                                                        setEditing(null);
                                                    }}
                                                >
                                                    Batal
                                                </Button>
                                                <Button
                                                    type="submit"
                                                    disabled={processing}
                                                >
                                                    {processing
                                                        ? 'Menyimpan...'
                                                        : 'Simpan'}
                                                </Button>
                                            </DialogFooter>
                                        </>
                                    );
                                }}
                            </Form>
                        )}
                    </DialogContent>
                </Dialog>

                <ConfirmDialog
                    open={deleting !== null}
                    onOpenChange={(open) => {
                        if (!open) {
                            setDeleting(null);
                        }
                    }}
                    title="Hapus Customer"
                    description={`Apakah Anda yakin ingin menghapus customer "${deleting?.name}"? Tindakan ini tidak dapat dibatalkan.`}
                    confirmLabel="Hapus"
                    onConfirm={handleDelete}
                />
            </div>
        </>
    );
}
