import { Head, router } from '@inertiajs/react';
import { Medal, RefreshCw, Trophy } from 'lucide-react';
import { toast } from 'sonner';

import DashboardLayout from '@/components/dashboard/DashboardLayout';
import DataTable, { Column, Paginator } from '@/components/dashboard/DataTable';
import { DashboardPageHeader } from '@/components/dashboard/DashboardPageHeader';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import { useTranslation } from '@/contexts/LanguageContext';
import { formatDate, formatNumber } from '@/lib/format';

interface LbRow {
    id: number;
    game_id: number;
    user_id: number;
    username: string;
    high_score: number;
    score_count: number;
    rank_position: number;
    last_score_date: string;
    updated_at: string;
}

interface GameOption {
    id: number;
    title: string;
}

interface Props {
    rows: Paginator<LbRow>;
    filters: { game_id: string | null; search: string };
    gameOptions: GameOption[];
}

function fmt(iso: string): string {
    const d = new Date(iso);
    return Number.isNaN(d.getTime()) ? iso : formatDate(d);
}

export default function LeaderboardsIndex({ rows, filters, gameOptions }: Props) {
    const { t } = useTranslation();
    function selectGame(id: string) {
        router.get(
            '/dashboard/leaderboards',
            { game_id: id === 'all' ? undefined : id },
            { preserveScroll: true, preserveState: false },
        );
    }

    function recomputeAll() {
        router.post('/dashboard/leaderboards/recompute', {}, {
            preserveScroll: true,
            onSuccess: () => toast.success(t('All leaderboards recomputed')),
            onError: (errors) => toast.error((Object.values(errors)[0] as string) || t('Failed')),
        });
    }

    function recomputeOne() {
        if (!filters.game_id) return;
        router.post(`/dashboard/leaderboards/recompute/${filters.game_id}`, {}, {
            preserveScroll: true,
            onSuccess: () => toast.success(t('Leaderboard recomputed')),
            onError: (errors) => toast.error((Object.values(errors)[0] as string) || t('Failed')),
        });
    }

    const columns: Column<LbRow>[] = [
        {
            key: 'rank_position',
            label: t('Rank'),
            cell: (r) => {
                if (r.rank_position === 1) {
                    return (
                        <Badge className="bg-amber-500 text-white hover:bg-amber-500">
                            <Trophy className="me-1 h-3 w-3" />#1
                        </Badge>
                    );
                }
                if (r.rank_position === 2) {
                    return (
                        <Badge className="bg-zinc-400 text-white hover:bg-zinc-400">
                            <Medal className="me-1 h-3 w-3" />#2
                        </Badge>
                    );
                }
                if (r.rank_position === 3) {
                    return (
                        <Badge className="bg-orange-700 text-white hover:bg-orange-700">
                            <Medal className="me-1 h-3 w-3" />#3
                        </Badge>
                    );
                }
                return (
                    <span className="font-medium tabular-nums text-muted-foreground">
                        #{r.rank_position}
                    </span>
                );
            },
        },
        {
            key: 'username',
            label: t('User'),
            cell: (r) => (
                <a
                    href={`/profile/${r.username}`}
                    target="_blank"
                    rel="noreferrer"
                    className="font-medium text-primary underline-offset-2 hover:underline"
                >
                    {r.username}
                </a>
            ),
        },
        {
            key: 'high_score',
            label: t('High score'),
            cell: (r) => <span className="font-mono tabular-nums">{formatNumber(r.high_score)}</span>,
        },
        {
            key: 'score_count',
            label: t('Submissions'),
            cell: (r) => <span className="tabular-nums">{r.score_count}</span>,
        },
        {
            key: 'last_score_date',
            label: t('Last score'),
            cell: (r) => <span className="text-xs text-muted-foreground whitespace-nowrap">{fmt(r.last_score_date)}</span>,
        },
        {
            key: 'updated_at',
            label: t('Updated'),
            cell: (r) => <span className="text-xs text-muted-foreground whitespace-nowrap">{fmt(r.updated_at)}</span>,
        },
    ];

    return (
        <DashboardLayout>
            <Head title={t('Leaderboards')} />

            <DashboardPageHeader
                title={t('Leaderboards')}
                subtitle={t('High-score rankings per game. Recompute to recompute aggregates from raw game_scores rows.')}
                action={
                    <div className="flex gap-2">
                        <Button variant="outline" onClick={recomputeOne} disabled={!filters.game_id}>
                            <RefreshCw className="h-4 w-4 me-2" />
                            {t('Recompute current')}
                        </Button>
                        <Button variant="outline" onClick={recomputeAll}>
                            <RefreshCw className="h-4 w-4 me-2" />
                            {t('Recompute all')}
                        </Button>
                    </div>
                }
            />

            <DataTable
                rows={rows}
                columns={columns}
                searchPlaceholder={t('Search by username…')}
                initialSearch={filters.search}
                toolbar={
                    <Select value={filters.game_id ?? 'all'} onValueChange={selectGame}>
                        <SelectTrigger className="w-[220px]"><SelectValue placeholder={t('Pick a game…')} /></SelectTrigger>
                        <SelectContent>
                            <SelectItem value="all">{t('All games (mixed)')}</SelectItem>
                            {gameOptions.map((g) => (
                                <SelectItem key={g.id} value={String(g.id)}>{g.title}</SelectItem>
                            ))}
                        </SelectContent>
                    </Select>
                }
            />
        </DashboardLayout>
    );
}
