import { Head, router } from '@inertiajs/react';
import { RefreshCw, 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 DataTable, { Column, Paginator } from '@/components/dashboard/DataTable';
import StarRating from '@/components/dashboard/StarRating';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import {
    TableActionMenu,
    TableActionMenuContent,
    TableActionMenuItem,
    TableActionMenuLabel,
    TableActionMenuTrigger,
} from '@/components/ui/table-action-menu';
import { useTranslation } from '@/contexts/LanguageContext';
import { useAppDate } from '@/lib/date';
import { formatNumber } from '@/lib/format';

interface RawRow {
    id: number;
    game_id: number;
    user_id: number;
    rating: number;
    ip_address: string | null;
    is_duplicate: boolean;
    created_at: string;
    user: { id: number; username: string } | null;
    game: { id: number; title: string; slug: string } | null;
}

interface AggregateRow {
    id: number;
    game_id: number;
    game_title: string;
    game_slug: string;
    count: number;
    avg_rating: number;
    five_star_count: number;
    five_star_pct: number;
    last_rated_at: string;
}

interface Props {
    rows: Paginator<RawRow> | Paginator<AggregateRow>;
    view: 'raw' | 'aggregate';
    filters: {
        search: string;
        rating: string | null;
        game_id: string | null;
        user_id: string | null;
    };
}

export default function RatingsIndex({ rows, view, filters }: Props) {
    const { t } = useTranslation();
    const { formatDateTime } = useAppDate();
    const [selected, setSelected] = useState<number[]>([]);

    function switchView(next: 'raw' | 'aggregate') {
        router.get(
            '/dashboard/ratings',
            { view: next },
            { preserveState: false, preserveScroll: true },
        );
    }

    function bulkDelete() {
        if (selected.length === 0) return;
        const count = selected.length;
        router.post(
            '/dashboard/ratings/bulk-delete',
            { ids: selected },
            {
                preserveScroll: true,
                onSuccess: () => {
                    setSelected([]);
                    toast.success(t(':count rating(s) deleted', { count }));
                },
                onError: (errors) => toast.error((Object.values(errors)[0] as string) || t('Failed')),
            },
        );
    }

    function recompute() {
        router.post('/dashboard/ratings/recompute-averages', {}, {
            preserveScroll: true,
            onSuccess: () => toast.success(t('Averages recomputed')),
            onError: (errors) => toast.error((Object.values(errors)[0] as string) || t('Recompute failed')),
        });
    }

    function deleteRating(id: number) {
        router.delete(`/dashboard/ratings/${id}`, {
            preserveScroll: true,
            onSuccess: () => toast.success(t('Rating deleted')),
            onError: (errors) => toast.error((Object.values(errors)[0] as string) || t('Delete failed')),
        });
    }

    const rawColumns: Column<RawRow>[] = [
        {
            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: 'rating',
            label: t('Rating'),
            cell: (row) => <StarRating value={row.rating} />,
        },
        {
            key: 'ip_address',
            label: t('IP'),
            cell: (row) => (
                <div className="flex items-center gap-2">
                    <code className="rounded bg-muted px-2 py-0.5 font-mono text-xs">
                        {row.ip_address ?? '—'}
                    </code>
                    {row.is_duplicate && (
                        <Badge variant="outline" className="border-amber-500 text-amber-700 dark:text-amber-400">
                            {t('Duplicate')}
                        </Badge>
                    )}
                </div>
            ),
        },
        {
            key: 'created_at',
            label: t('Date'),
            cell: (row) => (
                <span className="text-sm text-muted-foreground">
                    {formatDateTime(row.created_at)}
                </span>
            ),
        },
    ];

    const aggColumns: Column<AggregateRow>[] = [
        {
            key: 'game_title',
            label: t('Game'),
            cell: (row) => (
                <a
                    href={`/play/${row.game_slug}`}
                    target="_blank"
                    rel="noreferrer"
                    className="text-primary underline-offset-2 hover:underline"
                >
                    {row.game_title}
                </a>
            ),
        },
        {
            key: 'count',
            label: t('Ratings'),
            cell: (row) => <Badge variant="secondary">{row.count}</Badge>,
        },
        {
            key: 'avg_rating',
            label: t('Average'),
            cell: (row) => (
                <div className="flex items-center gap-2">
                    <span className="font-medium">{row.avg_rating.toFixed(2)}</span>
                    <StarRating value={row.avg_rating} />
                </div>
            ),
        },
        {
            key: 'five_star_pct',
            label: t('5★ %'),
            cell: (row) => <Badge variant="outline">{row.five_star_pct}%</Badge>,
        },
        {
            key: 'last_rated_at',
            label: t('Last rated'),
            cell: (row) => (
                <span className="text-sm text-muted-foreground">
                    {formatDateTime(row.last_rated_at)}
                </span>
            ),
        },
    ];

    return (
        <DashboardLayout>
            <Head title={t('Ratings')} />
            <DashboardPageHeader
                title={t('Ratings')}
                subtitle={`${formatNumber(rows.total)} ${view === 'raw' ? (rows.total === 1 ? t('rating') : t('ratings')) : (rows.total === 1 ? t('rated game') : t('rated games'))} — ${t('Switch view to see raw rows or per-game aggregates. Recompute rebuilds averages from raw rows.')}`}
                action={
                    <Button variant="outline" onClick={recompute}>
                        <RefreshCw className="me-2 h-4 w-4" />
                        {t('Recompute averages')}
                    </Button>
                }
            />

            {view === 'raw' ? (
                <>
                    <DataTable
                        rows={rows as Paginator<RawRow>}
                        columns={rawColumns}
                        searchPlaceholder={t('Search by user or game…')}
                        initialSearch={filters.search}
                        selection={{ selected, onSelectionChange: setSelected }}
                        toolbar={
                            <Select value={view} onValueChange={(v) => switchView(v as 'raw' | 'aggregate')}>
                                <SelectTrigger className="w-[200px]"><SelectValue /></SelectTrigger>
                                <SelectContent>
                                    <SelectItem value="raw">{t('Raw ratings')}</SelectItem>
                                    <SelectItem value="aggregate">{t('Per-game aggregate')}</SelectItem>
                                </SelectContent>
                            </Select>
                        }
                        rowActions={(row) => (
                            <div className="flex justify-end">
                                <TableActionMenu>
                                    <TableActionMenuTrigger />
                                    <TableActionMenuContent>
                                        <TableActionMenuLabel>{t('Actions')}</TableActionMenuLabel>
                                        <TableActionMenuItem
                                            variant="destructive"
                                            onClick={() => deleteRating(row.id)}
                                        >
                                            <Trash2 className="h-4 w-4" />
                                            {t('Delete')}
                                        </TableActionMenuItem>
                                    </TableActionMenuContent>
                                </TableActionMenu>
                            </div>
                        )}
                    />
                    <BulkActionBar selectedCount={selected.length} onClear={() => setSelected([])}>
                        <Button size="sm" variant="destructive" onClick={bulkDelete}>
                            {t('Delete selected')}
                        </Button>
                    </BulkActionBar>
                </>
            ) : (
                <DataTable
                    rows={rows as Paginator<AggregateRow>}
                    columns={aggColumns}
                    searchPlaceholder={t('Search by game title…')}
                    initialSearch={filters.search}
                    toolbar={
                        <Select value={view} onValueChange={(v) => switchView(v as 'raw' | 'aggregate')}>
                            <SelectTrigger className="w-[200px]"><SelectValue /></SelectTrigger>
                            <SelectContent>
                                <SelectItem value="raw">{t('Raw ratings')}</SelectItem>
                                <SelectItem value="aggregate">{t('Per-game aggregate')}</SelectItem>
                            </SelectContent>
                        </Select>
                    }
                />
            )}
        </DashboardLayout>
    );
}
