import { Head, Link, router } from '@inertiajs/react';
import { createColumnHelper, type ColumnDef } from '@tanstack/react-table';
import { Pencil, Plus, Trash2 } from 'lucide-react';
import { useMemo } from 'react';
import RoleController from '@/actions/App/Http/Controllers/Admin/RoleController';
import { AnimatedAction } from '@/components/animated-action';
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 { formatDate } from '@/lib/utils';
import { create, edit, index } from '@/routes/admin/roles';
import { dashboard } from '@/routes';

type AdminRole = {
    id: number;
    name: string;
    label: string;
    is_system: boolean;
    is_protected: boolean;
    permissions: string[];
    users_count: number;
    created_at: string | null;
};

const columnHelper = createColumnHelper<AdminRole>();

export default function RolesIndex({ roles }: { roles: AdminRole[] }) {
    const canCreate = useCan('roles.create');
    const canUpdate = useCan('roles.update');
    const canDelete = useCan('roles.delete') || useHasRole('super-admin');

    const columns = useMemo(
        () =>
            withSelectionColumn([
                columnHelper.accessor('label', {
                    header: ({ column }) => (
                        <DataTableColumnHeader column={column} title="Rôle" />
                    ),
                    meta: { label: 'Rôle' },
                    cell: ({ row }) => (
                        <div>
                            <div className="flex items-center gap-2">
                                <span className="font-medium">
                                    {row.original.label}
                                </span>
                                {row.original.is_system && (
                                    <Badge variant="outline">système</Badge>
                                )}
                            </div>
                            <p className="text-xs text-muted-foreground">
                                {row.original.name}
                            </p>
                        </div>
                    ),
                    filterFn: (row, _columnId, filterValue: string) => {
                        const query = filterValue.toLowerCase();

                        return (
                            row.original.label.toLowerCase().includes(query) ||
                            row.original.name.toLowerCase().includes(query)
                        );
                    },
                }),
                columnHelper.accessor((row) => row.permissions.length, {
                    id: 'permissions_count',
                    header: ({ column }) => (
                        <DataTableColumnHeader
                            column={column}
                            title="Permissions"
                        />
                    ),
                    meta: { label: 'Permissions' },
                    cell: (info) => (
                        <span className="text-muted-foreground">
                            {info.getValue()}
                        </span>
                    ),
                }),
                columnHelper.accessor('users_count', {
                    header: ({ column }) => (
                        <DataTableColumnHeader
                            column={column}
                            title="Utilisateurs"
                        />
                    ),
                    meta: { label: 'Utilisateurs' },
                    cell: (info) => (
                        <span className="text-muted-foreground">
                            {info.getValue()}
                        </span>
                    ),
                }),
                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 role = row.original;

                        return (
                            <div className="flex justify-end gap-1">
                                <AnimatedAction title={canUpdate && !role.is_protected ? 'Modifier' : 'Voir'} asChild>
                                    <Link href={edit(role.id)}>
                                        <Pencil className="size-4" />
                                        <span className="sr-only">
                                            {canUpdate && !role.is_protected
                                                ? 'Modifier'
                                                : 'Voir'}
                                        </span>
                                    </Link>
                                </AnimatedAction>
                                {canDelete && !role.is_system && (
                                    <ConfirmDialog
                                        trigger={
                                            <AnimatedAction title="Supprimer" className="hover:text-destructive hover:bg-destructive/10">
                                                <Trash2 className="size-4" />
                                                <span className="sr-only">Supprimer</span>
                                            </AnimatedAction>
                                        }
                                        title={`Supprimer le rôle ${role.label} ?`}
                                        description="Cette action est irréversible."
                                        confirmLabel="Supprimer"
                                        onConfirm={() => {
                                            router.delete(
                                                RoleController.destroy.url(
                                                    role.id,
                                                ),
                                            );
                                        }}
                                    />
                                )}
                            </div>
                        );
                    },
                }),
            ] as ColumnDef<AdminRole>[]),
        [canUpdate, canDelete],
    );

    return (
        <>
            <Head title="Rôles" />

            <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="Rôles"
                        description="Gérer les rôles et leurs permissions"
                    />
                    {canCreate && (
                        <Button asChild>
                            <Link href={create()}>
                                <Plus />
                                Nouveau rôle
                            </Link>
                        </Button>
                    )}
                </div>

                <DataTable
                    id="admin-roles"
                    columns={columns}
                    data={roles}
                    getRowId={(row) => String(row.id)}
                    searchPlaceholder="Rechercher un rôle…"
                    emptyMessage="Aucun rôle."
                    bulkActions={
                        canDelete
                            ? ({ rows, clearSelection }) => {
                                  const deletable = rows.filter(
                                      (row) => !row.is_system,
                                  );

                                  if (deletable.length === 0) {
                                      return (
                                          <p className="text-sm text-muted-foreground">
                                              Aucun rôle personnalisé
                                              sélectionné.
                                          </p>
                                      );
                                  }

                                  return (
                                      <DataTableBulkDelete
                                          count={deletable.length}
                                          label="Supprimer"
                                          confirmTitle={`Supprimer ${deletable.length} rôle${deletable.length > 1 ? 's' : ''} ?`}
                                          onDelete={() => {
                                              router.delete(
                                                  RoleController.bulkDestroy.url(),
                                                  {
                                                      data: {
                                                          ids: deletable.map(
                                                              (row) => row.id,
                                                          ),
                                                      },
                                                      preserveScroll: true,
                                                      onSuccess: () =>
                                                          clearSelection(),
                                                  },
                                              );
                                          }}
                                      />
                                  );
                              }
                            : undefined
                    }
                />
            </div>
        </>
    );
}

RolesIndex.layout = {
    breadcrumbs: [
        { title: 'Tableau de bord', href: dashboard() },
        { title: 'Rôles', href: index() },
    ],
};
