import { Head, router } from '@inertiajs/react';
import { CalendarIcon, Eye, LogOut, PanelLeftClose, PanelLeftOpen, Search } from 'lucide-react';
import { useEffect, useState } from 'react';
import { AppSidebar } from '@/components/AppSidebar';
import { Button } from '@/components/ui/button';
import { Calendar } from '@/components/ui/calendar';
import {
    Dialog,
    DialogContent,
    DialogDescription,
    DialogHeader,
    DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import { Separator } from '@/components/ui/separator';
import { useAppSidebar } from '@/hooks/useAppSidebar';
import { stripPaginationLabel } from '@/lib/constants';
import { route } from '@/lib/route';
import { cn } from '@/lib/utils';

type ResultLogRow = {
    id: number;
    type: string;
    number: string;
    domains: string[];
    date: string;
    time: string;
    created_at: string;
    game_name: string;
    user_name: string;
};

type PaginatedLogs = {
    data: ResultLogRow[];
    current_page: number;
    last_page: number;
    per_page: number;
    total: number;
    from: number | null;
    to: number | null;
    links: Array<{ url: string | null; label: string; active: boolean }>;
};

type LogFilters = {
    search: string;
    date: string;
    type: string;
    domain: string;
    game_id: string;
};

type FilterOptions = {
    types: string[];
    domains: string[];
    games: Array<{ id: number; game_name: string }>;
};

const TYPE_LABELS: Record<string, string> = {
    open_result: 'Open result',
    close_result: 'Close result',
    open_bid_reverse: 'Open bid reverse',
    close_bid_reverse: 'Close bid reverse',
};

const selectClassName =
    'h-9 rounded-lg border border-border/80 bg-muted/40 px-3 text-sm shadow-none outline-none focus:border-border/80';

function parseLocalDate(isoDate: string): Date {
    const [y, m, d] = isoDate.split('-').map(Number);
    return new Date(y, (m ?? 1) - 1, d ?? 1);
}

function toIsoDate(date: Date): string {
    const y = date.getFullYear();
    const m = String(date.getMonth() + 1).padStart(2, '0');
    const d = String(date.getDate()).padStart(2, '0');
    return `${y}-${m}-${d}`;
}

function formatDisplayDate(isoDate: string): string {
    return parseLocalDate(isoDate).toLocaleDateString('en-GB', {
        day: '2-digit',
        month: '2-digit',
        year: 'numeric',
    });
}

function todayDate(): Date {
    const now = new Date();
    return new Date(now.getFullYear(), now.getMonth(), now.getDate());
}

function visitResultLog(params: Partial<LogFilters> & { page?: number }) {
    router.get(
        route('games.result-log'),
        {
            ...(params.search ? { search: params.search } : {}),
            ...(params.date ? { date: params.date } : {}),
            ...(params.type && params.type !== 'all' ? { type: params.type } : {}),
            ...(params.domain && params.domain !== 'all' ? { domain: params.domain } : {}),
            ...(params.game_id && params.game_id !== 'all' ? { game_id: params.game_id } : {}),
            ...(params.page && params.page > 1 ? { page: params.page } : {}),
        },
        { preserveState: true, replace: true, preserveScroll: true },
    );
}

function DetailRow({ label, value }: { label: string; value: string }) {
    return (
        <div>
            <p className="text-sm text-muted-foreground">{label}</p>
            <p className="mt-1 text-sm font-medium break-words">{value}</p>
        </div>
    );
}

export default function GameResultLog({
    auth,
    logs,
    filters,
    filterOptions,
}: {
    auth: { user: { first_name: string; last_name: string; email: string } | null };
    logs: PaginatedLogs;
    filters: LogFilters;
    filterOptions: FilterOptions;
}) {
    const { collapsed: sidebarCollapsed, mobileOpen, toggleSidebar, closeMobile, showOpenIcon } =
        useAppSidebar();
    const [viewing, setViewing] = useState<ResultLogRow | null>(null);
    const [search, setSearch] = useState(filters.search);
    const [dateOpen, setDateOpen] = useState(false);

    useEffect(() => {
        setSearch(filters.search);
    }, [filters.search]);

    useEffect(() => {
        const trimmed = search.trim();
        if (trimmed === filters.search) {
            return;
        }

        const id = window.setTimeout(() => {
            visitResultLog({
                search: trimmed,
                date: filters.date,
                type: filters.type,
                domain: filters.domain,
                game_id: filters.game_id,
            });
        }, 300);

        return () => window.clearTimeout(id);
    }, [search, filters]);

    const rows = logs.data;
    const hasActiveFilters =
        filters.search !== '' ||
        filters.date !== '' ||
        filters.type !== 'all' ||
        filters.domain !== 'all' ||
        filters.game_id !== 'all';

    return (
        <>
            <Head title="Game Result Log" />
            <div className="flex h-svh gap-3 overflow-hidden bg-background p-3">
                <AppSidebar
                    auth={auth}
                    collapsed={sidebarCollapsed}
                    mobileOpen={mobileOpen}
                    onMobileClose={closeMobile}
                    active="games-result-log"
                />

                <div className="flex min-w-0 flex-1 flex-col gap-3 overflow-hidden">
                    <header className="flex h-12 shrink-0 items-center justify-between gap-3 rounded-2xl border border-border bg-card px-4 shadow-sm">
                        <div className="flex min-w-0 items-center gap-3">
                            <Button
                                type="button"
                                variant="ghost"
                                size="icon"
                                className="cursor-pointer"
                                aria-label={showOpenIcon ? 'Open sidebar' : 'Close sidebar'}
                                onClick={toggleSidebar}
                            >
                                {showOpenIcon ? (
                                    <PanelLeftOpen className="size-4" aria-hidden />
                                ) : (
                                    <PanelLeftClose className="size-4" aria-hidden />
                                )}
                            </Button>

                            <div className="min-w-0">
                                <div className="truncate text-sm font-semibold">
                                    Game Result Log
                                </div>
                            </div>
                        </div>

                        <Button
                            type="button"
                            variant="ghost"
                            size="sm"
                            className="h-8 gap-1.5 text-xs"
                            onClick={() => router.post(route('logout'))}
                        >
                            <LogOut className="size-4" aria-hidden />
                            Sign out
                        </Button>
                    </header>

                    <main className="flex min-h-0 flex-1 flex-col gap-4 overflow-hidden rounded-2xl border border-border bg-card px-6 py-4 shadow-sm">
                        <div className="flex shrink-0 flex-wrap items-center gap-3">
                            <div className="relative w-full sm:min-w-56 sm:flex-1">
                                <Search
                                    className="pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2 text-muted-foreground"
                                    aria-hidden
                                />
                                <Input
                                    type="search"
                                    value={search}
                                    onChange={(e) => setSearch(e.target.value)}
                                    placeholder="Search by posted by user name"
                                    aria-label="Search by posted by user name"
                                    className="h-9 border-border/80 bg-muted/40 pr-3 pl-9 shadow-none outline-none focus-visible:border-border/80 focus-visible:ring-0"
                                />
                            </div>

                            <Popover open={dateOpen} onOpenChange={setDateOpen}>
                                <PopoverTrigger
                                    render={
                                        <Button
                                            type="button"
                                            variant="outline"
                                            aria-label="Filter by date"
                                            className="h-9 w-full justify-between border-border/80 bg-muted/40 px-3 text-sm font-normal shadow-none sm:w-40"
                                        />
                                    }
                                >
                                    <span
                                        className={cn(
                                            !filters.date && 'text-muted-foreground',
                                        )}
                                    >
                                        {filters.date
                                            ? formatDisplayDate(filters.date)
                                            : 'dd/mm/yyyy'}
                                    </span>
                                    <CalendarIcon
                                        className="size-3.5 text-muted-foreground"
                                        aria-hidden
                                    />
                                </PopoverTrigger>
                                <PopoverContent align="start" className="w-auto p-0">
                                    <Calendar
                                        mode="single"
                                        selected={
                                            filters.date
                                                ? parseLocalDate(filters.date)
                                                : undefined
                                        }
                                        defaultMonth={
                                            filters.date
                                                ? parseLocalDate(filters.date)
                                                : todayDate()
                                        }
                                        disabled={{ after: todayDate() }}
                                        onSelect={(date) => {
                                            if (!date) {
                                                return;
                                            }
                                            setDateOpen(false);
                                            visitResultLog({
                                                ...filters,
                                                search: search.trim(),
                                                date: toIsoDate(date),
                                            });
                                        }}
                                    />
                                    {filters.date && (
                                        <div className="border-t border-border p-2">
                                            <Button
                                                type="button"
                                                variant="ghost"
                                                size="sm"
                                                className="h-8 w-full cursor-pointer text-xs"
                                                onClick={() => {
                                                    setDateOpen(false);
                                                    visitResultLog({
                                                        ...filters,
                                                        search: search.trim(),
                                                        date: '',
                                                    });
                                                }}
                                            >
                                                Clear date
                                            </Button>
                                        </div>
                                    )}
                                </PopoverContent>
                            </Popover>

                            <select
                                value={filters.game_id}
                                onChange={(e) =>
                                    visitResultLog({
                                        ...filters,
                                        search: search.trim(),
                                        game_id: e.target.value,
                                    })
                                }
                                aria-label="Filter by game"
                                className={cn(selectClassName, 'w-full sm:w-44')}
                            >
                                <option value="all">All games</option>
                                {filterOptions.games.map((game) => (
                                    <option key={game.id} value={String(game.id)}>
                                        {game.game_name}
                                    </option>
                                ))}
                            </select>

                            <select
                                value={filters.type}
                                onChange={(e) =>
                                    visitResultLog({
                                        ...filters,
                                        search: search.trim(),
                                        type: e.target.value,
                                    })
                                }
                                aria-label="Filter by type"
                                className={cn(selectClassName, 'w-full sm:w-44')}
                            >
                                <option value="all">All types</option>
                                {filterOptions.types.map((type) => (
                                    <option key={type} value={type}>
                                        {TYPE_LABELS[type] ?? type}
                                    </option>
                                ))}
                            </select>

                            <select
                                value={filters.domain}
                                onChange={(e) =>
                                    visitResultLog({
                                        ...filters,
                                        search: search.trim(),
                                        domain: e.target.value,
                                    })
                                }
                                aria-label="Filter by domain"
                                className={cn(selectClassName, 'w-full sm:w-48')}
                            >
                                <option value="all">All domains</option>
                                {filterOptions.domains.map((domain) => (
                                    <option key={domain} value={domain}>
                                        {domain}
                                    </option>
                                ))}
                            </select>
                        </div>

                        <div className="flex min-h-0 flex-1 flex-col gap-3">
                            <div className="flex min-h-0 flex-1 flex-col overflow-hidden rounded-xl border border-border bg-background">
                                <div className="grid shrink-0 grid-cols-[minmax(0,1fr)_minmax(0,0.9fr)_minmax(0,1.2fr)_minmax(0,1.3fr)_minmax(0,1.2fr)_3.5rem] gap-3 bg-muted/40 px-4 py-2.5 text-sm font-medium">
                                    <div>Date</div>
                                    <div>Time</div>
                                    <div>Game</div>
                                    <div>Type</div>
                                    <div>Posted by</div>
                                    <div>Action</div>
                                </div>

                                <div className="flex min-h-0 flex-1 flex-col">
                                    {rows.length === 0 ? (
                                        <div className="flex flex-1 items-center justify-center px-4 text-sm text-muted-foreground">
                                            {hasActiveFilters
                                                ? 'No matching result logs.'
                                                : 'No result logs yet.'}
                                        </div>
                                    ) : (
                                        rows.map((log) => (
                                            <div
                                                key={log.id}
                                                className={cn(
                                                    'grid grid-cols-[minmax(0,1fr)_minmax(0,0.9fr)_minmax(0,1.2fr)_minmax(0,1.3fr)_minmax(0,1.2fr)_3.5rem] items-center gap-3 border-t border-border/50 px-4 text-sm',
                                                    rows.length >= logs.per_page
                                                        ? 'flex-1'
                                                        : 'shrink-0 py-2.5',
                                                )}
                                            >
                                                <div className="min-w-0 truncate">{log.date}</div>
                                                <div className="min-w-0 truncate text-muted-foreground">
                                                    {log.time}
                                                </div>
                                                <div className="min-w-0 truncate">
                                                    {log.game_name}
                                                </div>
                                                <div className="min-w-0 truncate">
                                                    {TYPE_LABELS[log.type] ?? log.type}
                                                </div>
                                                <div className="min-w-0 truncate text-muted-foreground">
                                                    {log.user_name}
                                                </div>
                                                <div>
                                                    <Button
                                                        type="button"
                                                        variant="ghost"
                                                        size="icon"
                                                        className="size-8 cursor-pointer"
                                                        aria-label="View log details"
                                                        onClick={() => setViewing(log)}
                                                    >
                                                        <Eye className="size-4" aria-hidden />
                                                    </Button>
                                                </div>
                                            </div>
                                        ))
                                    )}
                                </div>
                            </div>

                            <div className="flex shrink-0 flex-wrap items-center justify-between gap-3">
                                <p className="text-sm text-muted-foreground">
                                    Showing {logs.from ?? 0}–{logs.to ?? 0} of {logs.total}
                                </p>
                                {logs.last_page > 1 && (
                                    <nav className="flex flex-wrap gap-1" aria-label="Pagination">
                                        {logs.links.map((link, index) => {
                                            const label = stripPaginationLabel(link.label);

                                            if (!link.url) {
                                                return (
                                                    <span
                                                        key={`${label}-${index}`}
                                                        className="inline-flex h-8 min-w-8 items-center justify-center rounded-md px-2 text-sm text-muted-foreground"
                                                    >
                                                        {label}
                                                    </span>
                                                );
                                            }

                                            return (
                                                <Button
                                                    key={`${label}-${index}`}
                                                    type="button"
                                                    variant={link.active ? 'default' : 'outline'}
                                                    size="sm"
                                                    className="h-8 min-w-8 cursor-pointer px-2"
                                                    onClick={() =>
                                                        router.get(link.url!, {}, {
                                                            preserveState: true,
                                                            preserveScroll: true,
                                                        })
                                                    }
                                                >
                                                    {label}
                                                </Button>
                                            );
                                        })}
                                    </nav>
                                )}
                            </div>
                        </div>
                    </main>
                </div>
            </div>

            <Dialog
                open={viewing !== null}
                onOpenChange={(open) => {
                    if (!open) {
                        setViewing(null);
                    }
                }}
            >
                <DialogContent className="gap-0 overflow-hidden p-0 sm:max-w-md">
                    <DialogHeader className="rounded-t-xl border-b bg-muted/50 p-4">
                        <DialogTitle className="text-lg font-semibold">
                            Result log details
                        </DialogTitle>
                        <DialogDescription>
                            Full details for this result action.
                        </DialogDescription>
                    </DialogHeader>

                    {viewing && (
                        <div className="space-y-4 p-4">
                            <DetailRow label="Date" value={viewing.date} />
                            <Separator className="bg-border/60" />
                            <DetailRow label="Time" value={viewing.time} />
                            <Separator className="bg-border/60" />
                            <DetailRow label="Game" value={viewing.game_name} />
                            <Separator className="bg-border/60" />
                            <DetailRow
                                label="Type"
                                value={TYPE_LABELS[viewing.type] ?? viewing.type}
                            />
                            <Separator className="bg-border/60" />
                            <DetailRow label="Posted by" value={viewing.user_name} />
                            <Separator className="bg-border/60" />
                            <DetailRow label="Number" value={viewing.number} />
                            <Separator className="bg-border/60" />
                            <DetailRow
                                label="Domains"
                                value={
                                    viewing.domains.length > 0
                                        ? viewing.domains.join(', ')
                                        : '—'
                                }
                            />
                        </div>
                    )}
                </DialogContent>
            </Dialog>
        </>
    );
}
