import { Head, router } from '@inertiajs/react';
import {
    createColumnHelper,
    type ColumnDef,
    type PaginationState,
    type SortingState,
} from '@tanstack/react-table';
import { Pencil, Plus, Trash2 } from 'lucide-react';
import { useEffect, useMemo, useRef, useState } from 'react';
import ServiceController from '@/actions/App/Http/Controllers/Admin/ServiceController';
import { ConfirmDialog } from '@/components/confirm-dialog';
import {
    DataTable,
    DataTableBulkDelete,
    DataTableColumnHeader,
    withSelectionColumn,
} from '@/components/data-table';
import Heading from '@/components/heading';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { useCan, useHasRole } from '@/hooks/use-can';
import { formatCurrency, formatDate } from '@/lib/utils';
import { index } from '@/routes/admin/services';
import { dashboard } from '@/routes';
import type { Paginated, TableFilters } from '@/types';
import {
    ServiceFormModal,
    type CategoryOption,
    type ServiceFormValues,
    type UnitOption,
    type UserOption,
} from './service-form-modal';

type AdminService = Omit<ServiceFormValues, 'category_id' | 'responsible_id'> & {
    category: { id: number; name: string } | null;
    responsible: { id: number; name: string } | null;
    unit_label: string;
    created_at: string | null;
};

const columnHelper = createColumnHelper<AdminService>();

function visitServices(params: {
    search: string;
    sort: string;
    direction: 'asc' | 'desc';
    page: number;
    per_page: number;
}) {
    router.get(
        index.url(),
        {
            search: params.search || undefined,
            sort: params.sort,
            direction: params.direction,
            page: params.page > 1 ? params.page : undefined,
            per_page: params.per_page !== 15 ? params.per_page : undefined,
        },
        {
            preserveState: true,
            replace: true,
            preserveScroll: true,
        },
    );
}

export default function ServicesIndex({
    services,
    filters,
    categories,
    units,
    users,
}: {
    services: Paginated<AdminService>;
    filters: TableFilters;
    categories: CategoryOption[];
    units: UnitOption[];
    users: UserOption[];
}) {
    const canCreate = useCan('services.create');
    const canUpdate = useCan('services.update');
    const canDelete = useCan('services.delete') || useHasRole('super-admin');
    const isFirstSearchEffect = useRef(true);
    const [isLoading, setIsLoading] = useState(false);
    const [modalOpen, setModalOpen] = useState(false);
    const [editingService, setEditingService] =
        useState<ServiceFormValues | null>(null);

    const [search, setSearch] = useState(filters.search);
    const [sorting, setSorting] = useState<SortingState>([
        {
            id: filters.sort,
            desc: filters.direction === 'desc',
        },
    ]);
    const [pagination, setPagination] = useState<PaginationState>({
        pageIndex: services.current_page - 1,
        pageSize: services.per_page,
    });

    useEffect(() => {
        const removeStart = router.on('start', () => setIsLoading(true));
        const removeFinish = router.on('finish', () => setIsLoading(false));

        return () => {
            removeStart();
            removeFinish();
        };
    }, []);

    useEffect(() => {
        setSearch(filters.search);
        setSorting([
            {
                id: filters.sort,
                desc: filters.direction === 'desc',
            },
        ]);
        setPagination({
            pageIndex: services.current_page - 1,
            pageSize: services.per_page,
        });
    }, [filters, services.current_page, services.per_page]);

    useEffect(() => {
        if (isFirstSearchEffect.current) {
            isFirstSearchEffect.current = false;
            return;
        }

        const timeout = window.setTimeout(() => {
            const sort = sorting[0];

            visitServices({
                search,
                sort: sort?.id ?? 'created_at',
                direction: sort?.desc === false ? 'asc' : 'desc',
                page: 1,
                per_page: pagination.pageSize,
            });
        }, 300);

        return () => window.clearTimeout(timeout);
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [search]);

    function openCreateModal() {
        setEditingService(null);
        setModalOpen(true);
    }

    function openEditModal(service: AdminService) {
        setEditingService({
            id: service.id,
            code: service.code,
            name: service.name,
            category_id: service.category?.id ?? 0,
            responsible_id: service.responsible?.id ?? null,
            description: service.description,
            price: service.price,
            unit: service.unit,
            is_active: service.is_active,
        });
        setModalOpen(true);
    }

    const columns = useMemo(
        () =>
            withSelectionColumn([
                columnHelper.accessor('name', {
                    header: ({ column }) => (
                        <DataTableColumnHeader column={column} title="Nom" />
                    ),
                    meta: { label: 'Nom' },
                    cell: (info) => (
                        <span className="font-medium">{info.getValue()}</span>
                    ),
                }),
                columnHelper.accessor('category', {
                    header: 'Pôle d’activité',
                    enableSorting: false,
                    meta: { label: 'Pôle d’activité' },
                    cell: (info) => (
                        <span className="text-muted-foreground">
                            {info.getValue()?.name ?? '—'}
                        </span>
                    ),
                }),
                columnHelper.accessor('responsible', {
                    header: 'Responsable',
                    enableSorting: false,
                    meta: { label: 'Responsable' },
                    cell: (info) => (
                        <span className="text-muted-foreground">
                            {info.getValue()?.name ?? '—'}
                        </span>
                    ),
                }),
                columnHelper.accessor('price', {
                    header: ({ column }) => (
                        <DataTableColumnHeader column={column} title="Prix" />
                    ),
                    meta: { label: 'Prix' },
                    cell: (info) => (
                        <span className="font-medium tabular-nums">
                            {formatCurrency(Number(info.getValue()))}
                        </span>
                    ),
                }),
                columnHelper.accessor('unit_label', {
                    header: 'Unité',
                    enableSorting: false,
                    meta: { label: 'Unité' },
                    cell: (info) => (
                        <span className="text-muted-foreground">
                            {info.getValue()}
                        </span>
                    ),
                }),
                columnHelper.accessor('is_active', {
                    header: ({ column }) => (
                        <DataTableColumnHeader column={column} title="Statut" />
                    ),
                    meta: { label: 'Statut' },
                    cell: (info) =>
                        info.getValue() ? (
                            <Badge variant="secondary">Actif</Badge>
                        ) : (
                            <Badge variant="outline">Inactif</Badge>
                        ),
                }),
                columnHelper.accessor('created_at', {
                    header: ({ column }) => (
                        <DataTableColumnHeader
                            column={column}
                            title="Créé le"
                        />
                    ),
                    meta: { label: 'Créé le' },
                    cell: (info) => (
                        <span className="text-muted-foreground">
                            {formatDate(info.getValue())}
                        </span>
                    ),
                }),
                columnHelper.display({
                    id: 'actions',
                    enableSorting: false,
                    enableHiding: false,
                    header: () => <div className="text-right">Actions</div>,
                    cell: ({ row }) => {
                        const service = row.original;

                        return (
                            <div className="flex justify-end gap-2">
                                {canUpdate && (
                                    <Button
                                        variant="outline"
                                        size="icon"
                                        title="Modifier"
                                        onClick={() => openEditModal(service)}
                                    >
                                        <Pencil />
                                    </Button>
                                )}
                                {canDelete && (
                                    <ConfirmDialog
                                        trigger={
                                            <Button
                                                variant="destructive"
                                                size="icon"
                                                title="Supprimer"
                                            >
                                                <Trash2 />
                                            </Button>
                                        }
                                        title={`Supprimer la prestation ${service.name} ?`}
                                        description="Cette action est irréversible."
                                        confirmLabel="Supprimer"
                                        onConfirm={() => {
                                            router.delete(
                                                ServiceController.destroy.url(
                                                    service.id,
                                                ),
                                                { preserveScroll: true },
                                            );
                                        }}
                                    />
                                )}
                            </div>
                        );
                    },
                }),
            ] as ColumnDef<AdminService>[]),
        [canUpdate, canDelete],
    );

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

            <div className="flex h-full flex-1 flex-col gap-6 p-4 md:p-6">
                <div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
                    <Heading
                        title="Prestations"
                        description="Gérer le catalogue des services proposés par l’entreprise"
                    />
                    {canCreate && (
                        <Button onClick={openCreateModal}>
                            <Plus />
                            Nouvelle prestation
                        </Button>
                    )}
                </div>

                <DataTable
                    id="admin-services"
                    columns={columns}
                    data={services.data}
                    getRowId={(row) => String(row.id)}
                    isLoading={isLoading}
                    searchValue={search}
                    onSearchChange={setSearch}
                    searchPlaceholder="Rechercher par code ou nom…"
                    emptyMessage="Aucune prestation."
                    sorting={sorting}
                    onSortingChange={(updater) => {
                        const next =
                            typeof updater === 'function'
                                ? updater(sorting)
                                : updater;
                        setSorting(next);

                        const sort = next[0];
                        visitServices({
                            search,
                            sort: sort?.id ?? 'created_at',
                            direction: sort?.desc === false ? 'asc' : 'desc',
                            page: 1,
                            per_page: pagination.pageSize,
                        });
                    }}
                    manualSorting
                    pagination={pagination}
                    onPaginationChange={(updater) => {
                        const next =
                            typeof updater === 'function'
                                ? updater(pagination)
                                : updater;
                        const pageChanged =
                            next.pageIndex !== pagination.pageIndex;
                        const sizeChanged =
                            next.pageSize !== pagination.pageSize;

                        setPagination(next);

                        if (!pageChanged && !sizeChanged) {
                            return;
                        }

                        const sort = sorting[0];
                        visitServices({
                            search,
                            sort: sort?.id ?? 'created_at',
                            direction: sort?.desc === false ? 'asc' : 'desc',
                            page: sizeChanged ? 1 : next.pageIndex + 1,
                            per_page: next.pageSize,
                        });
                    }}
                    manualPagination
                    pageCount={services.last_page}
                    totalRows={services.total}
                    bulkActions={
                        canDelete
                            ? ({ rows, clearSelection }) => (
                                  <DataTableBulkDelete
                                      count={rows.length}
                                      label="Supprimer"
                                      confirmTitle={`Supprimer ${rows.length} prestation${rows.length > 1 ? 's' : ''} ?`}
                                      onDelete={() => {
                                          router.delete(
                                              ServiceController.bulkDestroy.url(),
                                              {
                                                  data: {
                                                      ids: rows.map(
                                                          (row) => row.id,
                                                      ),
                                                  },
                                                  preserveScroll: true,
                                                  onSuccess: () =>
                                                      clearSelection(),
                                              },
                                          );
                                      }}
                                  />
                              )
                            : undefined
                    }
                />
            </div>

            <ServiceFormModal
                open={modalOpen}
                onOpenChange={setModalOpen}
                categories={categories}
                units={units}
                users={users}
                service={editingService}
            />
        </>
    );
}

ServicesIndex.layout = {
    breadcrumbs: [
        { title: 'Tableau de bord', href: dashboard() },
        { title: 'Prestations', href: index() },
    ],
};
