import { router } from '@inertiajs/react';
import { useEffect, useMemo } from 'react';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import {
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableHeader,
    TableRow,
} from '@/components/ui/table';
import { useLanguage } from '@/contexts/language-context';
import { useSyncedState } from '@/hooks/use-synced-state';

/**
 * @param {object} props
 * @param {import('@inertiajs/core').Paginator<any>} props.audits
 * @param {{ search: string, event: string, model: string, per_page: number }} props.filters
 * @param {Record<string, string>} props.labels
 * @param {Array<{ value: string, label: string }>} props.modelTypes
 * @param {(opts?: { query?: Record<string, string | number> }) => string} props.indexUrl
 */
export function UserAuditsTable({ audits, modelTypes = [], filters, labels, indexUrl }) {
    const { formatDateTime } = useLanguage();
    const [search, setSearch] = useSyncedState(filters.search ?? '');

    useEffect(() => {
        const handle = setTimeout(() => {
            const next = search.trim();
            const current = (filters.search ?? '').trim();
            if (next === current) {
                return;
            }
            router.get(
                indexUrl({
                    query: {
                        search: next,
                        event: filters.event,
                        model: filters.model,
                        per_page: filters.per_page,
                        page: 1,
                    },
                }),
                {},
                { preserveState: true, preserveScroll: true, replace: true },
            );
        }, 350);

        return () => clearTimeout(handle);
    }, [search, filters.event, filters.model, filters.per_page, filters.search, indexUrl]);

    const rows = audits?.data ?? [];
    const currentPage = audits?.current_page ?? 1;
    const lastPage = audits?.last_page ?? 1;
    const from = audits?.from;
    const to = audits?.to;
    const total = audits?.total ?? 0;

    const summaryText = useMemo(() => {
        if (total === 0) {
            return labels.summaryEmpty;
        }
        return labels.paginationSummary
            .replace('{from}', String(from ?? 0))
            .replace('{to}', String(to ?? 0))
            .replace('{total}', String(total));
    }, [from, to, total, labels.paginationSummary, labels.summaryEmpty]);

    const pagePositionText = useMemo(
        () =>
            labels.paginationPages
                .replace('{page}', String(currentPage))
                .replace('{pages}', String(lastPage)),
        [currentPage, lastPage, labels.paginationPages],
    );

    const goToPage = (page) => {
        router.get(
            indexUrl({
                query: {
                    search: filters.search,
                    event: filters.event,
                    model: filters.model,
                    per_page: filters.per_page,
                    page,
                },
            }),
            {},
            { preserveState: true, preserveScroll: true },
        );
    };

    const updateFilter = (key, value) => {
        router.get(
            indexUrl({
                query: {
                    search: filters.search,
                    event: key === 'event' ? value : filters.event,
                    model: key === 'model' ? value : filters.model,
                    per_page: key === 'per_page' ? value : filters.per_page,
                    page: 1,
                },
            }),
            {},
            { preserveState: true, preserveScroll: true, replace: true },
        );
    };

    const eventLabel = (event) => {
        const map = {
            created: labels.eventCreated,
            updated: labels.eventUpdated,
            deleted: labels.eventDeleted,
            restored: labels.eventRestored,
            sync: labels.eventSync,
        };
        return map[event] ?? event;
    };

    const modelLabel = (type) => {
        const match = modelTypes.find(
            (entry) => entry.label === type || entry.value === type.toLowerCase(),
        );
        if (match) {
            return match.label;
        }
        if (type === 'User') {
            return labels.modelUser;
        }
        if (type === 'Role') {
            return labels.modelRole;
        }
        if (type === 'PermanentEmployee') {
            return labels.modelPermanentEmployee;
        }
        if (type === 'TemporaryEmployee') {
            return labels.modelTemporaryEmployee;
        }
        return type;
    };

    return (
        <div className="space-y-4">
            <div className="grid w-full max-w-3xl gap-4 sm:grid-cols-2 lg:grid-cols-3">
                <div className="space-y-2 sm:col-span-2 lg:col-span-1">
                    <Label htmlFor="audit-search">{labels.searchLabel}</Label>
                    <Input
                        id="audit-search"
                        value={search}
                        onChange={(e) => setSearch(e.target.value)}
                        placeholder={labels.searchPlaceholder}
                    />
                </div>
                <div className="space-y-2">
                    <Label>{labels.filterEvent}</Label>
                    <Select
                        value={filters.event || 'all'}
                        onValueChange={(value) =>
                            updateFilter('event', value === 'all' ? '' : value)
                        }
                    >
                        <SelectTrigger>
                            <SelectValue />
                        </SelectTrigger>
                        <SelectContent>
                            <SelectItem value="all">{labels.filterAll}</SelectItem>
                            <SelectItem value="created">{labels.eventCreated}</SelectItem>
                            <SelectItem value="updated">{labels.eventUpdated}</SelectItem>
                            <SelectItem value="deleted">{labels.eventDeleted}</SelectItem>
                            <SelectItem value="restored">{labels.eventRestored}</SelectItem>
                            <SelectItem value="sync">{labels.eventSync}</SelectItem>
                        </SelectContent>
                    </Select>
                </div>
                <div className="space-y-2">
                    <Label>{labels.filterModel}</Label>
                    <Select
                        value={filters.model || 'all'}
                        onValueChange={(value) =>
                            updateFilter('model', value === 'all' ? '' : value)
                        }
                    >
                        <SelectTrigger>
                            <SelectValue />
                        </SelectTrigger>
                        <SelectContent>
                            <SelectItem value="all">{labels.filterAll}</SelectItem>
                            {modelTypes.map((entry) => (
                                <SelectItem key={entry.value} value={entry.value}>
                                    {entry.label}
                                </SelectItem>
                            ))}
                        </SelectContent>
                    </Select>
                </div>
            </div>

            <div className="overflow-x-auto rounded-lg border border-border">
                <Table>
                    <TableHeader>
                        <TableRow>
                            <TableHead className="w-14">{labels.colSerial}</TableHead>
                            <TableHead>{labels.colWhen}</TableHead>
                            <TableHead>{labels.colEvent}</TableHead>
                            <TableHead>{labels.colModel}</TableHead>
                            <TableHead>{labels.colSubject}</TableHead>
                            <TableHead>{labels.colActor}</TableHead>
                            <TableHead className="min-w-[14rem]">{labels.colChanges}</TableHead>
                        </TableRow>
                    </TableHeader>
                    <TableBody>
                        {rows.length === 0 ? (
                            <TableRow>
                                <TableCell
                                    colSpan={7}
                                    className="text-muted-foreground h-24 text-center"
                                >
                                    {labels.empty}
                                </TableCell>
                            </TableRow>
                        ) : (
                            rows.map((row, index) => (
                                <TableRow key={row.id}>
                                    <TableCell className="text-muted-foreground">
                                        {(from ?? 0) + index}
                                    </TableCell>
                                    <TableCell className="whitespace-nowrap text-sm">
                                        {formatDateTime(row.created_at)}
                                    </TableCell>
                                    <TableCell>
                                        <Badge variant="outline">{eventLabel(row.event)}</Badge>
                                    </TableCell>
                                    <TableCell>{modelLabel(row.model_type)}</TableCell>
                                    <TableCell
                                        className="max-w-[12rem] truncate"
                                        title={row.subject}
                                    >
                                        {row.subject}
                                    </TableCell>
                                    <TableCell className="max-w-[10rem]">
                                        <div className="truncate font-medium">
                                            {row.user_name ?? labels.systemActor}
                                        </div>
                                        {row.user_email ? (
                                            <div className="text-muted-foreground truncate text-xs">
                                                {row.user_email}
                                            </div>
                                        ) : null}
                                    </TableCell>
                                    <TableCell className="min-w-[14rem] max-w-xl align-top whitespace-normal break-words">
                                        {row.changes?.length ? (
                                            <ul className="space-y-1.5 text-xs">
                                                {row.changes.map((change) => (
                                                    <li
                                                        key={`${row.id}-${change.field}`}
                                                        className="break-words leading-relaxed"
                                                    >
                                                        <span className="font-medium">
                                                            {change.field}
                                                        </span>
                                                        {': '}
                                                        <span className="text-muted-foreground">
                                                            {change.old ?? labels.changeEmpty}
                                                        </span>
                                                        {' → '}
                                                        <span>
                                                            {change.new ?? labels.changeEmpty}
                                                        </span>
                                                    </li>
                                                ))}
                                            </ul>
                                        ) : (
                                            <span className="text-muted-foreground text-xs">
                                                {labels.noChanges}
                                            </span>
                                        )}
                                    </TableCell>
                                </TableRow>
                            ))
                        )}
                    </TableBody>
                </Table>
            </div>

            <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
                <p className="text-muted-foreground text-sm">{summaryText}</p>
                <div className="flex flex-wrap items-center gap-3">
                    <div className="flex items-center gap-2">
                        <Label htmlFor="audit-per-page" className="text-sm whitespace-nowrap">
                            {labels.rowsPerPage}
                        </Label>
                        <Select
                            value={String(filters.per_page)}
                            onValueChange={(value) => updateFilter('per_page', Number(value))}
                        >
                            <SelectTrigger id="audit-per-page" className="w-20">
                                <SelectValue />
                            </SelectTrigger>
                            <SelectContent>
                                {[10, 25, 50].map((n) => (
                                    <SelectItem key={n} value={String(n)}>
                                        {n}
                                    </SelectItem>
                                ))}
                            </SelectContent>
                        </Select>
                    </div>
                    <span className="text-muted-foreground text-sm">{pagePositionText}</span>
                    <div className="flex gap-2">
                        <Button
                            type="button"
                            variant="outline"
                            size="sm"
                            disabled={currentPage <= 1}
                            onClick={() => goToPage(currentPage - 1)}
                        >
                            {labels.paginationPrevious}
                        </Button>
                        <Button
                            type="button"
                            variant="outline"
                            size="sm"
                            disabled={currentPage >= lastPage}
                            onClick={() => goToPage(currentPage + 1)}
                        >
                            {labels.paginationNext}
                        </Button>
                    </div>
                </div>
            </div>
        </div>
    );
}
