import { Head, router, usePage } from '@inertiajs/react';
import {
    CalendarIcon,
    LogOut,
    PanelLeftClose,
    PanelLeftOpen,
} from 'lucide-react';
import { useEffect, useState, type ReactNode } from 'react';
import { toast, Toaster } from 'sonner';
import { AppSidebar } from '@/components/AppSidebar';
import { Button } from '@/components/ui/button';
import { Calendar } from '@/components/ui/calendar';
import {
    Dialog,
    DialogContent,
    DialogDescription,
    DialogFooter,
    DialogHeader,
    DialogTitle,
} from '@/components/ui/dialog';
import { Field, FieldError, FieldGroup, FieldLabel } from '@/components/ui/field';
import { Input } from '@/components/ui/input';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import {
    Tooltip,
    TooltipContent,
    TooltipProvider,
    TooltipTrigger,
} from '@/components/ui/tooltip';
import { useAppSidebar } from '@/hooks/useAppSidebar';
import { calcAnk, DIGITS_ONLY_REGEX, isValidPana, NON_DIGITS_REGEX } from '@/lib/constants';
import { route } from '@/lib/route';
import { cn } from '@/lib/utils';

type GameCard = {
    id: number;
    game_name: string;
    open_time2: string;
    close_time2: string;
    open_status: boolean;
    close_status: boolean;
    game_on_off: string;
    days: string;
    price: number;
    has_open: boolean;
    has_close: boolean;
    result_id: number | null;
    open_pana: string | null;
    open_ank: string | null;
    close_pana: string | null;
    close_ank: string | null;
};

type ResultAction = 'open' | 'close';
type ReverseMarket = 'open' | 'close';

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 isScheduledOnDate(days: string, isoDate: string): boolean {
    const weekday = parseLocalDate(isoDate).getDay();
    return days.split('-').includes(String(weekday));
}

function startsCollapsed(game: GameCard, isoDate: string): boolean {
    return game.has_close || !isScheduledOnDate(game.days, isoDate);
}

function ResultActionButton({
    disabled,
    tooltip,
    onClick,
    children,
}: {
    disabled: boolean;
    tooltip?: string;
    onClick: () => void;
    children: ReactNode;
}) {
    const button = (
        <Button
            type="button"
            size="sm"
            variant="outline"
            className="h-6 rounded-full border-0 bg-sky-500 px-3 text-[10px] font-medium text-white shadow-none hover:bg-sky-600 disabled:bg-sky-500 disabled:text-white disabled:opacity-100"
            disabled={disabled}
            onClick={onClick}
        >
            {children}
        </Button>
    );

    if (!disabled || !tooltip) {
        return button;
    }

    return (
        <Tooltip>
            <TooltipTrigger render={<span className="inline-flex cursor-pointer" />}>
                {button}
            </TooltipTrigger>
            <TooltipContent side="top">{tooltip}</TooltipContent>
        </Tooltip>
    );
}

export default function Games({
    auth,
    canManageGames,
    activeDomainCount,
    games,
    filters,
}: {
    auth: {
        user: {
            first_name: string;
            last_name: string;
            email: string;
            is_sub_admin?: boolean;
            is_super_admin?: boolean;
        } | null;
    };
    canManageGames: boolean;
    activeDomainCount: number;
    games: GameCard[];
    filters: { date: string };
}) {
    const { flash } = usePage().props as {
        flash?: { success?: string | null; error?: string | null };
    };

    const { collapsed: sidebarCollapsed, mobileOpen, toggleSidebar, closeMobile, showOpenIcon } =
        useAppSidebar();

    const [posting, setPosting] = useState<{
        action: ResultAction;
        game: GameCard;
    } | null>(null);
    const [pana, setPana] = useState('');
    const [panaError, setPanaError] = useState<string | null>(null);
    const [busy, setBusy] = useState(false);
    const [dateOpen, setDateOpen] = useState(false);
    const [reversing, setReversing] = useState<{
        market: ReverseMarket;
        game: GameCard;
    } | null>(null);
    const [reverseBusy, setReverseBusy] = useState(false);
    const [openedClosedIds, setOpenedClosedIds] = useState<number[]>([]);

    const hideSidebar = auth.user?.is_sub_admin === true;
    const openResultReport = (game: GameCard, market: 'open' | 'close') => {
        router.get(route('report'), {
            date: filters.date,
            game_id: game.id,
            open_close: market,
            filter: 1,
        });
    };

    useEffect(() => {
        if (flash?.success) {
            toast.success(flash.success, { duration: 8000 });
        }
        if (flash?.error) {
            toast.error(flash.error);
        }
    }, [flash?.success, flash?.error]);

    useEffect(() => {
        setOpenedClosedIds([]);
    }, [filters.date]);

    function toggleClosedGame(gameId: number) {
        setOpenedClosedIds((ids) =>
            ids.includes(gameId) ? ids.filter((id) => id !== gameId) : [...ids, gameId],
        );
    }

    const ankPreview =
        pana.length === 3 && isValidPana(pana) ? calcAnk(pana) : pana.length === 3 ? 'Invalid' : '';

    function openPostDialog(action: ResultAction, game: GameCard) {
        if (!canManageGames) {
            return;
        }
        setPana('');
        setPanaError(null);
        setPosting({ action, game });
    }

    function submitBidReverse() {
        if (!reversing || !canManageGames) {
            return;
        }

        setReverseBusy(true);
        router.post(
            route('games.results.bid-reverse'),
            {
                game_id: reversing.game.id,
                date: filters.date,
                open_close: reversing.market,
            },
            {
                preserveScroll: true,
                onFinish: () => setReverseBusy(false),
                onSuccess: () => setReversing(null),
                onError: (errors) => {
                    toast.error(
                        errors.open_close ?? errors.game_id ?? 'Could not reverse result.',
                    );
                },
            },
        );
    }

    function submitResult() {
        if (!posting) {
            return;
        }

        if (!isValidPana(pana)) {
            setPanaError('Invalid Pana.');
            return;
        }

        setBusy(true);
        const url =
            posting.action === 'open'
                ? route('games.results.open')
                : route('games.results.close');

        router.post(
            url,
            {
                game_id: posting.game.id,
                date: filters.date,
                pana,
            },
            {
                preserveScroll: true,
                onFinish: () => setBusy(false),
                onSuccess: () => {
                    setPosting(null);
                    setPana('');
                    setPanaError(null);
                },
                onError: (errors) => {
                    setPanaError(errors.pana ?? 'Could not post result.');
                },
            },
        );
    }

    return (
        <TooltipProvider>
            <>
            <Head title="Game Result Out" />
            <Toaster
                position="bottom-right"
                toastOptions={{
                    classNames: {
                        success:
                            '!bg-green-600 !text-white !border-green-700 [&_[data-icon]]:!text-white',
                        error: '!bg-red-600 !text-white !border-red-700 [&_[data-icon]]:!text-white',
                    },
                }}
            />

            <div className="flex h-svh gap-3 overflow-hidden bg-background p-3">
                {!hideSidebar && (
                    <AppSidebar
                        auth={auth}
                        collapsed={sidebarCollapsed}
                        mobileOpen={mobileOpen}
                        onMobileClose={closeMobile}
                        active="games-result-out"
                    />
                )}

                <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">
                            {!hideSidebar && (
                                <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 Out
                                </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-y-auto rounded-2xl border border-border bg-card p-4 shadow-sm sm:p-6">
                        <div className="flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between">
                            <div>
                                <h2 className="mt-1 font-heading text-base font-semibold tracking-tight text-foreground">
                                    Active domains: {activeDomainCount}
                                </h2>
                            </div>

                            <div className="w-full sm:w-56">
                                <label
                                    htmlFor="result-date"
                                    className="mb-1.5 block text-xs font-medium text-muted-foreground"
                                >
                                    Date
                                </label>
                                <Popover open={dateOpen} onOpenChange={setDateOpen}>
                                    <PopoverTrigger
                                        render={
                                            <Button
                                                id="result-date"
                                                type="button"
                                                variant="outline"
                                                className="h-9 w-full justify-between border-border/80 bg-muted/40 px-3 text-sm font-normal shadow-none"
                                            />
                                        }
                                    >
                                        <span>{formatDisplayDate(filters.date)}</span>
                                        <CalendarIcon
                                            className="size-3.5 text-muted-foreground"
                                            aria-hidden
                                        />
                                    </PopoverTrigger>
                                    <PopoverContent
                                        align="end"
                                        className="w-auto p-0"
                                    >
                                        <Calendar
                                            mode="single"
                                            selected={parseLocalDate(filters.date)}
                                            defaultMonth={parseLocalDate(filters.date)}
                                            disabled={{ after: todayDate() }}
                                            onSelect={(date) => {
                                                if (!date) {
                                                    return;
                                                }
                                                setDateOpen(false);
                                                router.get(
                                                    route('games'),
                                                    { date: toIsoDate(date) },
                                                    {
                                                        preserveState: true,
                                                        replace: true,
                                                        preserveScroll: true,
                                                    },
                                                );
                                            }}
                                        />
                                    </PopoverContent>
                                </Popover>
                            </div>
                        </div>

                        {games.length === 0 ? (
                            <p className="text-sm text-muted-foreground">
                                No games found. Run the game seeder.
                            </p>
                        ) : (
                            <div className="grid grid-cols-1 gap-3">
                                {games.map((game) => {
                                    const collapsedByDefault = startsCollapsed(game, filters.date);
                                    const expanded =
                                        !collapsedByDefault ||
                                        openedClosedIds.includes(game.id);

                                    return (
                                    <div
                                        key={game.id}
                                        className="overflow-hidden rounded-lg border border-slate-200 bg-white shadow-md"
                                    >
                                        <div
                                            className={cn(
                                                'bg-[#ffa500] px-4 py-1.5 text-center text-slate-800',
                                                collapsedByDefault && 'cursor-pointer',
                                            )}
                                            role={collapsedByDefault ? 'button' : undefined}
                                            tabIndex={collapsedByDefault ? 0 : undefined}
                                            aria-expanded={
                                                collapsedByDefault ? expanded : undefined
                                            }
                                            onClick={() => {
                                                if (collapsedByDefault) {
                                                    toggleClosedGame(game.id);
                                                }
                                            }}
                                            onKeyDown={(e) => {
                                                if (
                                                    collapsedByDefault &&
                                                    (e.key === 'Enter' || e.key === ' ')
                                                ) {
                                                    e.preventDefault();
                                                    toggleClosedGame(game.id);
                                                }
                                            }}
                                        >
                                            <div className="font-heading text-sm font-bold uppercase leading-tight tracking-tight">
                                                {game.game_name}
                                            </div>
                                            <div className="mt-0.5 text-[10px] font-semibold leading-tight">
                                                {formatDisplayDate(filters.date)}
                                            </div>
                                        </div>

                                        {expanded && (
                                        <>
                                        <div className="grid grid-cols-2 bg-slate-800 text-white">
                                            <div className="py-0.5 text-center text-xs font-medium">
                                                Open
                                            </div>
                                            <div className="py-0.5 text-center text-xs font-medium">
                                                Close
                                            </div>
                                        </div>

                                        <div className="grid min-h-18 grid-cols-2 divide-x-2 divide-slate-600 bg-white">
                                            <div className="flex flex-col items-center gap-1 px-3 py-1 text-slate-800">
                                                <span className="text-xs leading-tight">
                                                    {game.open_time2}
                                                </span>
                                                {game.has_open ? (
                                                    <div className="flex flex-col items-center gap-1">
                                                        <span className="inline-flex h-6 items-center rounded-full bg-sky-500 px-3 text-[11px] font-semibold text-white">
                                                            {game.open_pana}-{game.open_ank}
                                                        </span>
                                                        {!game.has_close && (
                                                            <Button
                                                                type="button"
                                                                size="sm"
                                                                variant="destructive"
                                                                className="h-6 rounded-full px-3 text-[10px]"
                                                                disabled={
                                                                    !canManageGames ||
                                                                    activeDomainCount === 0
                                                                }
                                                                onClick={() =>
                                                                    setReversing({
                                                                        market: 'open',
                                                                        game,
                                                                    })
                                                                }
                                                            >
                                                                Bid Reverse
                                                            </Button>
                                                        )}
                                                    </div>
                                                ) : (
                                                    <ResultActionButton
                                                        disabled={
                                                            !canManageGames ||
                                                            activeDomainCount === 0
                                                        }
                                                        tooltip={
                                                            activeDomainCount === 0
                                                                ? 'Please add or activate a domain first.'
                                                                : undefined
                                                        }
                                                        onClick={() =>
                                                            openPostDialog('open', game)
                                                        }
                                                    >
                                                        Add Open Result
                                                    </ResultActionButton>
                                                )}
                                                {canManageGames && (
                                                    <Button
                                                        type="button"
                                                        size="sm"
                                                        className="h-6 rounded-full border-0 bg-[#2caf50] px-3 text-[10px] font-medium text-white shadow-none hover:bg-[#249241]"
                                                        onClick={() =>
                                                            openResultReport(game, 'open')
                                                        }
                                                    >
                                                        Open Report
                                                    </Button>
                                                )}
                                            </div>

                                            <div className="flex flex-col items-center gap-1 px-3 py-1 text-slate-800">
                                                <span className="text-xs leading-tight">
                                                    {game.close_time2}
                                                </span>
                                                {game.has_close ? (
                                                    <div className="flex flex-col items-center gap-1">
                                                        <span className="inline-flex h-6 items-center rounded-full bg-sky-500 px-3 text-[11px] font-semibold text-white">
                                                            {game.close_pana}-{game.close_ank}
                                                        </span>
                                                        <Button
                                                            type="button"
                                                            size="sm"
                                                            variant="destructive"
                                                            className="h-6 rounded-full px-3 text-[10px]"
                                                            disabled={
                                                                !canManageGames ||
                                                                activeDomainCount === 0
                                                            }
                                                            onClick={() =>
                                                                setReversing({
                                                                    market: 'close',
                                                                    game,
                                                                })
                                                            }
                                                        >
                                                            Bid Reverse
                                                        </Button>
                                                    </div>
                                                ) : (
                                                    <ResultActionButton
                                                        disabled={
                                                            !canManageGames ||
                                                            activeDomainCount === 0 ||
                                                            !game.has_open
                                                        }
                                                        tooltip={
                                                            activeDomainCount === 0
                                                                ? 'Please add or activate a domain first.'
                                                                : !game.has_open
                                                                  ? 'Please add open result first.'
                                                                  : undefined
                                                        }
                                                        onClick={() =>
                                                            openPostDialog('close', game)
                                                        }
                                                    >
                                                        Add Close Result
                                                    </ResultActionButton>
                                                )}
                                                {canManageGames && (
                                                    <Button
                                                        type="button"
                                                        size="sm"
                                                        className="h-6 rounded-full border-0 bg-[#2caf50] px-3 text-[10px] font-medium text-white shadow-none hover:bg-[#249241]"
                                                        onClick={() =>
                                                            openResultReport(game, 'close')
                                                        }
                                                    >
                                                        Close Report
                                                    </Button>
                                                )}
                                            </div>
                                        </div>
                                        </>
                                        )}
                                    </div>
                                    );
                                })}
                            </div>
                        )}
                    </main>
                </div>
            </div>

            <Dialog
                open={posting !== null}
                onOpenChange={(open) => {
                    if (!open && !busy) {
                        setPosting(null);
                        setPana('');
                        setPanaError(null);
                    }
                }}
            >
                <DialogContent
                    className="gap-0 overflow-hidden p-0 sm:max-w-sm"
                    showCloseButton
                >
                    <DialogHeader className="-mx-0 rounded-t-xl border-b bg-muted/50 p-4 pr-12">
                        <DialogTitle className="text-lg font-semibold">
                            {posting?.action === 'open' ? 'Open' : 'Close'} Result
                        </DialogTitle>
                        <DialogDescription>
                            {posting?.game.game_name} — {formatDisplayDate(filters.date)}
                        </DialogDescription>
                    </DialogHeader>

                    <FieldGroup className="gap-4 p-4">
                        <Field data-invalid={panaError ? true : undefined}>
                            <FieldLabel
                                htmlFor="pana"
                                className="text-xs font-medium uppercase tracking-wider text-muted-foreground"
                            >
                                Pana (3 digits)
                            </FieldLabel>
                            <Input
                                id="pana"
                                type="text"
                                inputMode="numeric"
                                pattern="[0-9]{3}"
                                maxLength={3}
                                autoComplete="off"
                                value={pana}
                                autoFocus
                                onBeforeInput={(e) => {
                                    const data = (e.nativeEvent as InputEvent).data ?? '';
                                    if (data === '') {
                                        return;
                                    }
                                    if (!DIGITS_ONLY_REGEX.test(data) || pana.length + data.length > 3) {
                                        e.preventDefault();
                                    }
                                }}
                                onChange={(e) => {
                                    setPana(e.target.value.replace(NON_DIGITS_REGEX, '').slice(0, 3));
                                    setPanaError(null);
                                }}
                                onPaste={(e) => {
                                    e.preventDefault();
                                    const pasted = e.clipboardData
                                        .getData('text')
                                        .replace(NON_DIGITS_REGEX, '')
                                        .slice(0, 3);
                                    setPana(pasted);
                                    setPanaError(null);
                                }}
                                onKeyDown={(e) => {
                                    if (e.key === 'Enter') {
                                        e.preventDefault();
                                        submitResult();
                                    }
                                }}
                                className="h-11 border-border/80 bg-muted/40 shadow-none outline-none transition-colors focus-visible:border-border/80 focus-visible:bg-background focus-visible:ring-0 aria-invalid:ring-0"
                            />
                            {ankPreview !== '' && (
                                <p
                                    className={cn(
                                        'text-xs',
                                        ankPreview === 'Invalid'
                                            ? 'text-destructive'
                                            : 'text-muted-foreground',
                                    )}
                                >
                                    Ank: {ankPreview}
                                </p>
                            )}
                            {panaError && <FieldError>{panaError}</FieldError>}
                        </Field>
                    </FieldGroup>

                    <DialogFooter className="mx-0 mb-0 gap-2 sm:justify-end">
                        <Button
                            type="button"
                            variant="outline"
                            className="h-10"
                            disabled={busy}
                            onClick={() => {
                                setPosting(null);
                                setPana('');
                                setPanaError(null);
                            }}
                        >
                            Cancel
                        </Button>
                        <Button
                            type="button"
                            className="h-10"
                            disabled={busy}
                            onClick={submitResult}
                        >
                            {busy ? 'Posting…' : 'Post'}
                        </Button>
                    </DialogFooter>
                </DialogContent>
            </Dialog>

            <Dialog
                open={reversing !== null}
                onOpenChange={(open) => {
                    if (!open && !reverseBusy) {
                        setReversing(null);
                    }
                }}
            >
                <DialogContent
                    className="gap-0 overflow-hidden p-0 sm:max-w-sm"
                    showCloseButton
                >
                    <DialogHeader className="-mx-0 rounded-t-xl border-b bg-muted/50 p-4 pr-12">
                        <DialogTitle className="text-lg font-semibold">
                            Bid Reverse
                        </DialogTitle>
                    </DialogHeader>

                    <div className="p-4">
                        <DialogDescription className="text-sm leading-relaxed text-muted-foreground">
                            {reversing
                                ? `Reverse ${reversing.market} result for ${reversing.game.game_name} on ${formatDisplayDate(filters.date)} across all active domains?`
                                : 'Reverse this result across all active domains?'}
                        </DialogDescription>
                    </div>

                    <DialogFooter className="mx-0 mb-0 gap-2 sm:justify-end">
                        <Button
                            type="button"
                            variant="outline"
                            className="h-10"
                            disabled={reverseBusy}
                            onClick={() => setReversing(null)}
                        >
                            Cancel
                        </Button>
                        <Button
                            type="button"
                            variant="destructive"
                            className="h-10"
                            disabled={reverseBusy}
                            onClick={submitBidReverse}
                        >
                            {reverseBusy ? 'Reversing…' : 'Bid Reverse'}
                        </Button>
                    </DialogFooter>
                </DialogContent>
            </Dialog>
            </>
        </TooltipProvider>
    );
}
