import { Head, router } from '@inertiajs/react';
import { motion } from 'framer-motion';
import {
    createColumnHelper,
    type ColumnDef,
    type PaginationState,
    type SortingState,
} from '@tanstack/react-table';
import { useEffect, useRef, useState } from 'react';
import { DataTable, DataTableColumnHeader, getSelectionColumn } from '@/components/data-table';
import Heading from '@/components/heading';
import { Badge } from '@/components/ui/badge';
import { Download, Eye, Calendar, User, Activity, Globe, AlignLeft, Code, ShieldCheck } from 'lucide-react';
import {
    Dialog,
    DialogContent,
    DialogHeader,
    DialogTitle,
    DialogTrigger,
} from '@/components/ui/dialog';

import { Button } from '@/components/ui/button';
import { DateRangePicker } from '@/components/ui/date-range-picker';
import type { DateRange } from 'react-day-picker';
import { format } from 'date-fns';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import { formatDate } from '@/lib/utils';
import { dashboard } from '@/routes';
import { index } from '@/routes/admin/audit-logs';
import type { Paginated } from '@/types';

type AuditLogItem = {
    id: number;
    event: string;
    description: string;
    user: { id: number; name: string } | null;
    ip_address: string | null;
    properties?: Record<string, unknown> | null;
    created_at: string | null;
};

type Filters = {
    search: string;
    event: string;
    date_from?: string;
    date_to?: string;
    sort_by?: string;
    sort_dir?: string;
    per_page: number;
};

const columnHelper = createColumnHelper<AuditLogItem>();

const EVENT_VARIANTS: Record<string, 'default' | 'secondary' | 'destructive'> =
{
    'login.success': 'secondary',
    logout: 'secondary',
    'login.failed': 'destructive',
    'user.deleted': 'destructive',
    'user.deactivated': 'destructive',
    'role.deleted': 'destructive',
};

function visitLogs(params: {
    search: string;
    date_from?: string;
    date_to?: string;
    sort_by?: string;
    sort_dir?: string;
    page: number;
    per_page: number;
}) {
    router.get(
        index.url(),
        {
            search: params.search || undefined,
            date_from: params.date_from || undefined,
            date_to: params.date_to || undefined,
            sort_by: params.sort_by || undefined,
            sort_dir: params.sort_dir || undefined,
            page: params.page > 1 ? params.page : undefined,
            per_page: params.per_page !== 25 ? params.per_page : undefined,
        },
        { preserveState: true, replace: true, preserveScroll: true },
    );
}

function ViewDetailsModal({ log }: { log: AuditLogItem }) {
    return (
        <Dialog>
            <DialogTrigger asChild>
                <Button variant="ghost" size="icon" className="h-8 w-8 text-muted-foreground hover:text-foreground transition-colors" asChild>
                    <motion.button whileHover={{ scale: 1.15 }} whileTap={{ scale: 0.9 }}>
                        <Eye className="w-4 h-4" />
                        <span className="sr-only">Voir les détails</span>
                    </motion.button>
                </Button>
            </DialogTrigger>
            {/* Outer Container */}
            <DialogContent className="max-w-xl sm:rounded-[32px] p-1 border border-border/10 shadow-2xl bg-gray-200 dark:bg-gray-800">
                {/* Inner Container */}
                <motion.div
                    initial={{ opacity: 0, scale: 0.96, y: 15 }}
                    animate={{ opacity: 1, scale: 1, y: 0 }}
                    transition={{ duration: 0.5, ease: [0.22, 1, 0.36, 1] }}
                    className="bg-background w-full h-full sm:rounded-[26px] p-6 sm:p-8 shadow-sm border border-border/30"
                >
                    <DialogHeader className="mb-4 pb-4 border-b border-border">
                        <DialogTitle className="text-xl font-bold tracking-tight text-destructive">Détail de l'activité</DialogTitle>
                    </DialogHeader>

                    <div className="space-y-5 text-[13px]">
                        <div className="grid grid-cols-1 gap-y-3">
                            <div className="grid grid-cols-[100px_1fr] sm:grid-cols-[140px_1fr] gap-4 items-baseline">
                                <span className="text-muted-foreground">Action</span>
                                <div className="font-medium text-destructive bg-destructive/10 px-2 py-0.5 rounded-md w-fit">
                                    {log.event}
                                </div>
                            </div>

                            <div className="grid grid-cols-[100px_1fr] sm:grid-cols-[140px_1fr] gap-4 items-baseline">
                                <span className="text-muted-foreground">Date</span>
                                <div className="text-foreground">
                                    {log.created_at ? formatDate(log.created_at) : '—'}
                                </div>
                            </div>

                            <div className="grid grid-cols-[100px_1fr] sm:grid-cols-[140px_1fr] gap-4 items-baseline">
                                <span className="text-muted-foreground">Auteur</span>
                                <div className="text-foreground">
                                    {log.user?.name ?? 'Système automatisé'}
                                </div>
                            </div>

                            <div className="grid grid-cols-[100px_1fr] sm:grid-cols-[140px_1fr] gap-4 items-baseline">
                                <span className="text-muted-foreground">Réseau</span>
                                <div className="text-muted-foreground font-mono text-[11px] tracking-wider">
                                    {log.ip_address ?? '—'}
                                </div>
                            </div>
                        </div>

                        <div className="w-full h-px bg-border"></div>

                        <div className="space-y-3">
                            <span className="text-muted-foreground">Description</span>
                            <p className="text-foreground text-sm leading-relaxed font-light">{log.description}</p>
                        </div>

                        {log.properties && Object.keys(log.properties).length > 0 && (
                            <div className="space-y-3 pt-2">
                                <span className="text-muted-foreground">Métadonnées</span>
                                <div className="p-4 rounded-xl bg-muted/40 overflow-x-auto">
                                    <pre className="text-[11px] font-mono text-muted-foreground leading-relaxed">
                                        {JSON.stringify(log.properties, null, 2)}
                                    </pre>
                                </div>
                            </div>
                        )}
                    </div>
                </motion.div>
            </DialogContent>
        </Dialog>
    );
}

export default function AuditLogsIndex({
    logs,
    filters,
    events,
}: {
    logs: Paginated<AuditLogItem>;
    filters: Filters;
    events: string[];
}) {
    const isFirstSearchEffect = useRef(true);
    const [isLoading, setIsLoading] = useState(false);
    const [search, setSearch] = useState(filters.search);
    const [date, setDate] = useState<DateRange | undefined>({
        from: filters.date_from ? new Date(filters.date_from) : undefined,
        to: filters.date_to ? new Date(filters.date_to) : undefined,
    });
    const [sorting, setSorting] = useState<SortingState>([
        {
            id: filters.sort_by || 'created_at',
            desc: filters.sort_dir === 'desc' || !filters.sort_dir, // Default to desc for created_at
        },
    ]);
    const [pagination, setPagination] = useState<PaginationState>({
        pageIndex: logs.current_page - 1,
        pageSize: logs.per_page,
    });

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

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

    useEffect(() => {
        // eslint-disable-next-line react-hooks/set-state-in-effect -- sync from props
        setSearch(filters.search);
        setDate({
            from: filters.date_from ? new Date(filters.date_from) : undefined,
            to: filters.date_to ? new Date(filters.date_to) : undefined,
        });
        setSorting([
            {
                id: filters.sort_by || 'created_at',
                desc: filters.sort_dir === 'desc' || !filters.sort_dir,
            },
        ]);
        setPagination({
            pageIndex: logs.current_page - 1,
            pageSize: logs.per_page,
        });
    }, [filters, logs.current_page, logs.per_page]);

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

            return;
        }

        const timeout = window.setTimeout(() => {
            visitLogs({
                search,
                date_from: date?.from ? format(date.from, 'yyyy-MM-dd') : undefined,
                date_to: date?.to ? format(date.to, 'yyyy-MM-dd') : undefined,
                sort_by: sorting[0]?.id,
                sort_dir: sorting[0] ? (sorting[0].desc ? 'desc' : 'asc') : undefined,
                page: 1,
                per_page: pagination.pageSize,
            });
        }, 300);

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

    function applyDateRangeFilter(range: DateRange | undefined) {
        setDate(range);
        visitLogs({
            search,
            date_from: range?.from ? format(range.from, 'yyyy-MM-dd') : undefined,
            date_to: range?.to ? format(range.to, 'yyyy-MM-dd') : undefined,
            sort_by: sorting[0]?.id,
            sort_dir: sorting[0] ? (sorting[0].desc ? 'desc' : 'asc') : undefined,
            page: 1,
            per_page: pagination.pageSize,
        });
    }

    const handleExport = (ids?: number[]) => {
        const form = document.createElement('form');
        form.method = 'POST';
        form.action = '/admin/audit-logs/export';

        const csrfToken = document.head.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
        if (csrfToken) {
            const input = document.createElement('input');
            input.type = 'hidden';
            input.name = '_token';
            input.value = csrfToken;
            form.appendChild(input);
        }

        if (ids && ids.length > 0) {
            ids.forEach(id => {
                const input = document.createElement('input');
                input.type = 'hidden';
                input.name = 'ids[]';
                input.value = String(id);
                form.appendChild(input);
            });
        } else {
            if (search) {
                const input = document.createElement('input');
                input.type = 'hidden';
                input.name = 'search';
                input.value = search;
                form.appendChild(input);
            }
            if (date?.from) {
                const input = document.createElement('input');
                input.type = 'hidden';
                input.name = 'date_from';
                input.value = format(date.from, 'yyyy-MM-dd');
                form.appendChild(input);
            }
            if (date?.to) {
                const input = document.createElement('input');
                input.type = 'hidden';
                input.name = 'date_to';
                input.value = format(date.to, 'yyyy-MM-dd');
                form.appendChild(input);
            }
        }

        document.body.appendChild(form);
        form.submit();
        document.body.removeChild(form);
    };

    const columns: ColumnDef<AuditLogItem, unknown>[] = [
        getSelectionColumn(),
        columnHelper.accessor('created_at', {
            header: ({ column }) => (
                <DataTableColumnHeader column={column} title="Date" />
            ),
            cell: (info) => (
                <span className="whitespace-nowrap text-muted-foreground">
                    {formatDate(info.getValue())}
                </span>
            ),
        }),

        columnHelper.accessor('description', {
            header: ({ column }) => (
                <DataTableColumnHeader column={column} title="Description" />
            ),
            cell: (info) => (
                <span className="block max-w-md">{info.getValue()}</span>
            ),
        }),
        columnHelper.accessor('user', {
            header: 'Auteur',
            enableSorting: false, // User is a relationship, sorting might be complex without join
            cell: (info) => info.getValue()?.name ?? '—',
        }),
        columnHelper.accessor('ip_address', {
            header: ({ column }) => (
                <DataTableColumnHeader column={column} title="IP" />
            ),
            cell: (info) => (
                <span className="font-mono text-xs text-muted-foreground">
                    {info.getValue() ?? '—'}
                </span>
            ),
        }),
        columnHelper.display({
            id: 'actions',
            header: () => <span className="sr-only">Actions</span>,
            cell: ({ row }) => (
                <div className="flex justify-end">
                    <ViewDetailsModal log={row.original} />
                </div>
            ),
        }),
    ] as ColumnDef<AuditLogItem, unknown>[];

    return (
        <>
            <Head title="Journal d'audit" />

            <div className="flex h-full flex-1 flex-col gap-6 p-4 md:p-6">
                <Heading
                    title="Journal d'audit"
                    description="Connexions et actions sensibles sur les comptes, rôles et permissions"
                />

                <DataTable
                    id="admin-audit-logs"
                    columns={columns}
                    data={logs.data}
                    getRowId={(row) => String(row.id)}
                    isLoading={isLoading}
                    searchValue={search}
                    onSearchChange={setSearch}
                    searchPlaceholder="Rechercher par description ou auteur…"
                    emptyMessage="Aucun événement."
                    toolbarRight={
                        <div className="flex gap-2 items-center">
                            {/* Event filter removed as requested */}

                            <DateRangePicker
                                date={date}
                                setDate={applyDateRangeFilter}
                            />

                            {date?.from && (
                                <Button variant="ghost" size="sm" onClick={() => applyDateRangeFilter(undefined)}>
                                    Effacer
                                </Button>
                            )}

                            <Button variant="outline" size="sm" onClick={() => handleExport()} className="ml-2 w-9 h-9 p-0 bg-background/50 border-border/60" title="Exporter en PDF">
                                <Download className="w-4 h-4" />
                            </Button>
                        </div>
                    }
                    bulkActions={({ rows, clearSelection }) => (
                        <Button
                            variant="default"
                            size="sm"
                            onClick={() => {
                                handleExport(rows.map(r => r.id));
                                clearSelection();
                            }}
                        >
                            <Download className="w-4 h-4 mr-2" />
                            Exporter la sélection ({rows.length})
                        </Button>
                    )}
                    sorting={sorting}
                    onSortingChange={(updater) => {
                        const next =
                            typeof updater === 'function'
                                ? updater(sorting)
                                : updater;
                        setSorting(next);
                        const sort = next[0];
                        visitLogs({
                            search,
                            date_from: date?.from ? format(date.from, 'yyyy-MM-dd') : undefined,
                            date_to: date?.to ? format(date.to, 'yyyy-MM-dd') : undefined,
                            sort_by: sort?.id,
                            sort_dir: sort ? (sort.desc ? 'desc' : 'asc') : undefined,
                            page: 1, // Reset to first page on sort
                            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;
                        }

                        visitLogs({
                            search,
                            date_from: date?.from ? format(date.from, 'yyyy-MM-dd') : undefined,
                            date_to: date?.to ? format(date.to, 'yyyy-MM-dd') : undefined,
                            sort_by: sorting[0]?.id,
                            sort_dir: sorting[0] ? (sorting[0].desc ? 'desc' : 'asc') : undefined,
                            page: sizeChanged ? 1 : next.pageIndex + 1,
                            per_page: next.pageSize,
                        });
                    }}
                    manualPagination
                    pageCount={logs.last_page}
                    totalRows={logs.total}
                />
            </div>
        </>
    );
}

AuditLogsIndex.layout = {
    breadcrumbs: [
        { title: 'Tableau de bord', href: dashboard() },
        { title: "Journal d'audit", href: index() },
    ],
};
