import { Head, router } from '@inertiajs/react';
import { Eye, EyeOff, Trash2 } from 'lucide-react';
import { useState } from 'react';
import { toast } from 'sonner';

import DashboardLayout from '@/components/dashboard/DashboardLayout';
import { DashboardPageHeader } from '@/components/dashboard/DashboardPageHeader';
import BulkActionBar from '@/components/dashboard/BulkActionBar';
import ConfirmDialog from '@/components/dashboard/ConfirmDialog';
import DataTable, { Column, Paginator } from '@/components/dashboard/DataTable';
import InfoDialog from '@/components/dashboard/InfoDialog';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Switch } from '@/components/ui/switch';
import {
    TableActionMenu,
    TableActionMenuContent,
    TableActionMenuItem,
    TableActionMenuLabel,
    TableActionMenuSeparator,
    TableActionMenuTrigger,
} from '@/components/ui/table-action-menu';
import { useTranslation } from '@/contexts/LanguageContext';
import { useAppDate } from '@/lib/date';
import { formatNumber } from '@/lib/format';

interface CommentRow {
    id: number;
    comment: string;
    is_active: boolean;
    created_at: string;
    user: { id: number; username: string } | null;
    game: { id: number; title: string; slug: string } | null;
}

interface Props {
    rows: Paginator<CommentRow>;
    filters: {
        search: string;
        is_active: string | null;
        game_id: string | null;
        user_id: string | null;
    };
}

function truncate(text: string, length = 120): string {
    if (text.length <= length) return text;
    return text.slice(0, length).trimEnd() + '…';
}

export default function CommentsIndex({ rows, filters }: Props) {
    const { t } = useTranslation();
    const { formatDateTime } = useAppDate();
    const [selected, setSelected] = useState<number[]>([]);
    const [viewTarget, setViewTarget] = useState<CommentRow | null>(null);
    const [deleteTarget, setDeleteTarget] = useState<CommentRow | null>(null);

    function toggleVisibility(row: CommentRow) {
        router.patch(
            `/dashboard/comments/${row.id}`,
            { is_active: !row.is_active },
            {
                preserveScroll: true,
                preserveState: true,
                only: ['rows', 'flash'],
                onSuccess: () => toast.success(row.is_active ? t('Comment hidden') : t('Comment visible')),
                onError: (errors) => toast.error((Object.values(errors)[0] as string) || t('Failed')),
            },
        );
    }

    function runBulk(action: 'delete' | 'hide' | 'unhide') {
        if (selected.length === 0) return;
        const count = selected.length;
        router.post(
            '/dashboard/comments/bulk',
            { action, ids: selected },
            {
                preserveScroll: true,
                onSuccess: () => {
                    setSelected([]);
                    const messages: Record<typeof action, string> = {
                        delete: t(':count comment(s) deleted', { count }),
                        hide: t(':count comment(s) hidden', { count }),
                        unhide: t(':count comment(s) unhidden', { count }),
                    };
                    toast.success(messages[action]);
                },
                onError: (errors) => toast.error((Object.values(errors)[0] as string) || t('Failed')),
            },
        );
    }

    const columns: Column<CommentRow>[] = [
        {
            key: 'user',
            label: t('User'),
            cell: (row) =>
                row.user ? (
                    <a href={`/profile/${row.user.username}`} target="_blank" rel="noreferrer" className="font-medium text-primary underline-offset-2 hover:underline">{row.user.username}</a>
                ) : (
                    <span className="text-muted-foreground">—</span>
                ),
        },
        {
            key: 'game',
            label: t('Game'),
            cell: (row) =>
                row.game ? (
                    <a
                        href={`/play/${row.game.slug}`}
                        target="_blank"
                        rel="noreferrer"
                        className="text-primary underline-offset-2 hover:underline"
                    >
                        {row.game.title}
                    </a>
                ) : (
                    <span className="text-muted-foreground">—</span>
                ),
        },
        {
            key: 'comment',
            label: t('Comment'),
            cell: (row) => (
                <button
                    type="button"
                    className="text-start text-sm hover:underline"
                    onClick={() => setViewTarget(row)}
                    title={t('View full')}
                >
                    {truncate(row.comment)}
                </button>
            ),
        },
        {
            key: 'is_active',
            label: t('Visibility'),
            cell: (row) => (
                <div className="flex items-center gap-2">
                    <Switch checked={row.is_active} onCheckedChange={() => toggleVisibility(row)} />
                    <Badge variant={row.is_active ? 'default' : 'secondary'}>
                        {row.is_active ? t('Visible') : t('Hidden')}
                    </Badge>
                </div>
            ),
        },
        {
            key: 'created_at',
            label: t('Date'),
            cell: (row) => (
                <span className="text-sm text-muted-foreground">
                    {formatDateTime(row.created_at)}
                </span>
            ),
        },
    ];

    return (
        <DashboardLayout>
            <Head title={t('Comments')} />
            <DashboardPageHeader
                title={t('Comments')}
                subtitle={`${formatNumber(rows.total)} ${rows.total === 1 ? t('comment') : t('comments')} — ${t('Moderate user discussion across all games. Toggle visibility to hide without deleting.')}`}
            />

            <DataTable
                rows={rows}
                columns={columns}
                searchPlaceholder={t('Search by text, user, or game…')}
                initialSearch={filters.search}
                selection={{ selected, onSelectionChange: setSelected }}
                rowActions={(row) => (
                    <div className="flex justify-end">
                        <TableActionMenu>
                            <TableActionMenuTrigger />
                            <TableActionMenuContent>
                                <TableActionMenuLabel>{t('Actions')}</TableActionMenuLabel>
                                <TableActionMenuItem onClick={() => setViewTarget(row)}>
                                    <Eye className="h-4 w-4" />
                                    {t('View full')}
                                </TableActionMenuItem>
                                <TableActionMenuItem onClick={() => toggleVisibility(row)}>
                                    {row.is_active ? (
                                        <EyeOff className="h-4 w-4" />
                                    ) : (
                                        <Eye className="h-4 w-4" />
                                    )}
                                    {row.is_active ? t('Hide') : t('Unhide')}
                                </TableActionMenuItem>
                                <TableActionMenuSeparator />
                                <TableActionMenuItem
                                    variant="destructive"
                                    onClick={() => setDeleteTarget(row)}
                                >
                                    <Trash2 className="h-4 w-4" />
                                    {t('Delete')}
                                </TableActionMenuItem>
                            </TableActionMenuContent>
                        </TableActionMenu>
                    </div>
                )}
            />

            <BulkActionBar selectedCount={selected.length} onClear={() => setSelected([])}>
                <Button size="sm" variant="outline" onClick={() => runBulk('hide')}>
                    {t('Hide')}
                </Button>
                <Button size="sm" variant="outline" onClick={() => runBulk('unhide')}>
                    {t('Unhide')}
                </Button>
                <Button size="sm" variant="destructive" onClick={() => runBulk('delete')}>
                    {t('Delete')}
                </Button>
            </BulkActionBar>

            <InfoDialog
                open={viewTarget !== null}
                onOpenChange={(open) => !open && setViewTarget(null)}
                title={t('Comment')}
                description={
                    viewTarget
                        ? t(':username on :game', {
                              username: viewTarget.user?.username ?? t('unknown'),
                              game: viewTarget.game?.title ?? t('unknown game'),
                          })
                        : ''
                }
            >
                {viewTarget && (
                    <div className="space-y-2">
                        <p className="whitespace-pre-wrap text-sm">{viewTarget.comment}</p>
                        <p className="text-xs text-muted-foreground">
                            {formatDateTime(viewTarget.created_at)} ·{' '}
                            {viewTarget.is_active ? t('Visible') : t('Hidden')}
                        </p>
                    </div>
                )}
            </InfoDialog>

            <ConfirmDialog
                open={deleteTarget !== null}
                onOpenChange={(open) => !open && setDeleteTarget(null)}
                title={t('Delete this comment?')}
                description={t('This cannot be undone.')}
                confirmLabel={t('Delete')}
                onConfirm={() => {
                    if (!deleteTarget) return;
                    router.delete(`/dashboard/comments/${deleteTarget.id}`, {
                        preserveScroll: true,
                        onSuccess: () => {
                            toast.success(t('Comment deleted'));
                            setDeleteTarget(null);
                        },
                        onError: (errors) => {
                            toast.error((Object.values(errors)[0] as string) || t('Delete failed'));
                            setDeleteTarget(null);
                        },
                    });
                }}
            />
        </DashboardLayout>
    );
}
