'use client';

import React, {useCallback, useEffect, useRef, useState} from "react";
import {Alert, Box, CircularProgress, Paper, Radio, RadioGroup, Stack, Typography} from "@mui/material";
import {AuthGuard} from "@/src/auth/AuthGuard";
import {Fixture, picksClient, PickSelection} from "@/lib/api/picks";
import {ApiError} from "@/lib/api/client";
import CheckCircleRoundedIcon from '@mui/icons-material/CheckCircleRounded';
import ScheduleRoundedIcon from '@mui/icons-material/ScheduleRounded';
import SyncRoundedIcon from '@mui/icons-material/SyncRounded';
import {useSearchParams} from "next/navigation";

const PicksPage: React.FC = () => {
    const searchParams = useSearchParams();
    const footerRef = useRef<HTMLDivElement | null>(null);
    const [fixtures, setFixtures] = useState<Fixture[]>([]);
    const [selectedPicks, setSelectedPicks] = useState<Record<number, PickSelection>>({});
    const [savedPicks, setSavedPicks] = useState<Record<number, PickSelection>>({});
    const [savingPickIds, setSavingPickIds] = useState<number[]>([]);
    const [isLoadingFixtures, setIsLoadingFixtures] = useState(true);
    const [isRefreshingFixtures, setIsRefreshingFixtures] = useState(false);
    const [error, setError] = useState('');
    const [footerHeight, setFooterHeight] = useState(0);

    const loadFixtures = useCallback(async (signal?: AbortSignal) => {
        setError('');
        setIsLoadingFixtures(true);

        try {
            const [fixturesResponse, picksResponse] = await Promise.all([
                picksClient.getFixtures(signal),
                picksClient.getPicks(signal),
            ]);

            setFixtures(fixturesResponse.fixtures);
            const nextSavedPicks = picksResponse.picks.reduce<Record<number, PickSelection>>((accumulator, pick) => {
                    accumulator[pick.match_id] = pick.selection;
                    return accumulator;
                }, {});

            setSelectedPicks(nextSavedPicks);
            setSavedPicks(nextSavedPicks);
        } catch (fetchError: unknown) {
            if (signal?.aborted) {
                return;
            }

            if (fetchError instanceof ApiError) {
                setError(fetchError.message);
            } else {
                setError('No fue posible cargar los fixtures.');
            }
        } finally {
            if (!signal?.aborted) {
                setIsLoadingFixtures(false);
            }
        }
    }, []);

    useEffect(() => {
        const controller = new AbortController();

        void loadFixtures(controller.signal);

        return () => {
            controller.abort();
        };
    }, [loadFixtures]);

    const handleRefreshFixtures = async () => {
        setIsRefreshingFixtures(true);

        try {
            await loadFixtures();
        } finally {
            setIsRefreshingFixtures(false);
        }
    };

    const getLocaleDate = (date: number): string => {
        return new Date(date * 1000).toLocaleString(undefined, {
            dateStyle: 'medium',
            timeStyle: 'short',
        })
    };

    const getStatusString = (status: string): string => {
        switch (status) {
            case "scheduled":
                return "Agendado"
            case "in_progress":
                return "En vivo"
            case "finished":
                return "Terminado"
            case "cancelled":
                return "Cancelado"
            default:
                return "Desconocido"
        }
    }

    const handlePickChange = async (fixtureId: number, pick: PickSelection) => {
        const previousPick = selectedPicks[fixtureId];

        setSelectedPicks((current) => ({
            ...current,
            [fixtureId]: pick,
        }));

        setSavingPickIds((current) => [...current, fixtureId]);
        setError('');

        try {
            await picksClient.savePick({
                match_id: fixtureId,
                selection: pick,
            });

            setSavedPicks((current) => ({
                ...current,
                [fixtureId]: pick,
            }));
        } catch (saveError: unknown) {
            setSelectedPicks((current) => {
                if (!previousPick) {
                    const remainingPicks = {...current};
                    delete remainingPicks[fixtureId];
                    return remainingPicks;
                }

                return {
                    ...current,
                    [fixtureId]: previousPick,
                };
            });

            if (saveError instanceof ApiError) {
                setError(saveError.message);
            } else {
                setError('No fue posible guardar tu selección.');
            }
        } finally {
            setSavingPickIds((current) => current.filter((currentFixtureId) => currentFixtureId !== fixtureId));
        }
    };

    const getPickStatus = (fixtureId: number) => {
        if (savingPickIds.includes(fixtureId)) {
            return {
                label: 'Registrando...',
                color: 'text.primary',
            } as const;
        }

        if (savedPicks[fixtureId]) {
            return {
                label: 'Registrado correctamente',
                color: 'primary.main',
            } as const;
        }

        return {
            label: 'No se ha registrado el resultado',
            color: 'error.main',
        } as const;
    };

    const savedCount = fixtures.filter((fixture) => Boolean(savedPicks[fixture.id])).length;
    const footerPreviewCountValue = Number(searchParams.get('footerPreview') ?? '0');
    const footerPreviewCount =
        Number.isFinite(footerPreviewCountValue) && footerPreviewCountValue > 0
            ? Math.floor(footerPreviewCountValue)
            : 0;
    const footerTotalCount = Math.max(fixtures.length, footerPreviewCount);
    const missingCount = Math.max(footerTotalCount - savedCount, 0);
    const footerItems = Array.from({length: footerTotalCount}, (_, index) => {
        const fixture = fixtures[index];

        if (fixture) {
            return {
                key: `fixture-${fixture.id}`,
                fixtureId: fixture.id,
            };
        }

        return {
            key: `preview-${index}`,
            fixtureId: null,
        };
    });
    const footerBottomPadding = footerTotalCount > 0 ? Math.max(footerHeight + 12, 190) : 0;

    useEffect(() => {
        if (footerTotalCount === 0) {
            setFooterHeight(0);
            return;
        }

        const footerElement = footerRef.current;

        if (!footerElement) {
            return;
        }

        const updateFooterHeight = () => {
            setFooterHeight(footerElement.getBoundingClientRect().height);
        };

        updateFooterHeight();

        const observer = new ResizeObserver(() => {
            updateFooterHeight();
        });

        observer.observe(footerElement);

        return () => {
            observer.disconnect();
        };
    }, [footerTotalCount, savedCount, missingCount, savingPickIds.length]);

    return (
        <AuthGuard>
            <Box
                sx={{
                    minHeight: '100vh',
                    backgroundColor: {
                        xs: 'white',
                        md: 'grey.100',
                    },
                    p: {xs: 0, sm: 4},
                }}
            >
                <Paper
                    elevation={0}
                    sx={{
                        maxWidth: 720,
                        mx: 'auto',
                        p: {xs: 3, sm: 4},
                        borderRadius: 4,
                        boxShadow: {
                            xs: 'none',
                            md: 4,
                        }
                    }}
                >
                    <Stack spacing={3}>
                        <Stack
                            direction={{xs: 'column', sm: 'row'}}
                            spacing={2}
                            alignItems={{xs: 'flex-start', sm: 'center'}}
                            justifyContent="space-between"
                        >
                            <Box>
                                <Typography variant="h4" fontWeight={700}>
                                    Partidos
                                </Typography>
                            </Box>
                        </Stack>

                        {error ? <Alert severity="error">{error}</Alert> : null}

                        {isLoadingFixtures ? (
                            <Box
                                sx={{
                                    py: 8,
                                    display: 'flex',
                                    justifyContent: 'center',
                                }}
                            >
                                <CircularProgress/>
                            </Box>
                        ) : fixtures.length === 0 ? (
                            <Typography color="text.secondary">
                                No hay partidos disponibles.
                            </Typography>
                        ) : (
                            <Stack spacing={2}>
                                {fixtures.map((fixture) => (
                                    <Paper
                                        key={fixture.id}
                                        variant="outlined"
                                        sx={{
                                            p: 2,
                                            borderRadius: 3,
                                        }}
                                    >
                                        <Box display={'flex'} flexDirection={'column'}>
                                            <Box sx={{
                                                display: 'grid',
                                                gap: 1.5,
                                                gridTemplateColumns: {
                                                    xs: '1fr',
                                                    sm: 'repeat(2, minmax(0, 1fr))',
                                                },
                                            }}>
                                                <Box component={'div'}>
                                                    <Typography
                                                        variant="subtitle1">{getLocaleDate(fixture.starts_at)}
                                                    </Typography>
                                                    <Typography
                                                        variant="subtitle2">{fixture.venue}
                                                    </Typography>
                                                </Box>
                                                <Box component={'div'} sx={{textAlign: {xs: 'left', sm: 'right'}}}>
                                                    <Typography
                                                        variant="subtitle1">{fixture.stage}
                                                    </Typography>
                                                    <Typography variant="subtitle2">
                                                        {getStatusString(fixture.status)}
                                                    </Typography>
                                                </Box>
                                            </Box>
                                            <RadioGroup
                                                name={`fixture-${fixture.id}`}
                                                value={selectedPicks[fixture.id] ?? ''}
                                                onChange={(event) => void handlePickChange(fixture.id, event.target.value as PickSelection)}
                                            >
                                                <Box
                                                    sx={{
                                                        mt: 2,
                                                        display: 'grid',
                                                        gap: 1.5,
                                                        gridTemplateColumns: {
                                                            xs: '1fr',
                                                            sm: 'repeat(3, minmax(0, 1fr))',
                                                        },
                                                    }}
                                                >
                                                    <Paper
                                                        component="label"
                                                        variant="outlined"
                                                        sx={{
                                                            px: 1.5,
                                                            py: 1,
                                                            position: 'relative',
                                                            display: 'flex',
                                                            alignItems: 'center',
                                                            justifyContent: 'center',
                                                            cursor: 'pointer',
                                                            borderWidth: 2,
                                                            borderColor: selectedPicks[fixture.id] === 'home' ? 'green' : 'divider',
                                                            backgroundColor: selectedPicks[fixture.id] === 'home' ? 'rgba(53,205,53,0.5)' : 'grey.50',
                                                            color: selectedPicks[fixture.id] === 'home' ? 'black' : 'text.primary',
                                                            transition: 'background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease',
                                                            opacity: savingPickIds.includes(fixture.id) ? 0.7 : 1,
                                                        }}
                                                    >
                                                        <Stack
                                                            direction="row"
                                                            spacing={1}
                                                            alignItems="center"
                                                            justifyContent="center"
                                                        >
                                                            <Radio
                                                                value={'home'}
                                                                checked={selectedPicks[fixture.id] === 'home'}
                                                                disabled={savingPickIds.includes(fixture.id)}
                                                                sx={{
                                                                    position: 'absolute',
                                                                    opacity: 0,
                                                                    width: 1,
                                                                    height: 1,
                                                                    m: 0,
                                                                    p: 0,
                                                                    overflow: 'hidden',
                                                                    '&.Mui-checked': {
                                                                        color: 'inherit',
                                                                    },
                                                                }}
                                                            />
                                                            <span className={`fi fi-${fixture.home_short_name}`}></span>
                                                            <Typography
                                                                variant="subtitle1"
                                                                fontWeight={600}
                                                                textAlign="center"
                                                                sx={{overflow: 'hidden', overflowWrap: 'break-word'}}
                                                            >
                                                                {fixture.home_team}
                                                            </Typography>
                                                        </Stack>
                                                    </Paper>
                                                    <Paper
                                                        component="label"
                                                        variant="outlined"
                                                        sx={{
                                                            px: 1.5,
                                                            py: 1,
                                                            position: 'relative',
                                                            display: 'flex',
                                                            alignItems: 'center',
                                                            justifyContent: 'center',
                                                            cursor: 'pointer',
                                                            borderWidth: 2,
                                                            borderColor: selectedPicks[fixture.id] === 'draw' ? '#e6b94b' : 'divider',
                                                            backgroundColor: selectedPicks[fixture.id] === 'draw' ? 'rgba(255,255,0,0.5)' : 'grey.50',
                                                            color: selectedPicks[fixture.id] === 'draw' ? 'black' : 'text.primary',
                                                            transition: 'background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease',
                                                            opacity: savingPickIds.includes(fixture.id) ? 0.7 : 1,
                                                        }}
                                                    >
                                                        <Stack
                                                            direction="row"
                                                            spacing={1}
                                                            alignItems="center"
                                                            justifyContent="center"
                                                        >
                                                            <Radio
                                                                value={'draw'}
                                                                checked={selectedPicks[fixture.id] === 'draw'}
                                                                disabled={savingPickIds.includes(fixture.id)}
                                                                sx={{
                                                                    position: 'absolute',
                                                                    opacity: 0,
                                                                    width: 1,
                                                                    height: 1,
                                                                    m: 0,
                                                                    p: 0,
                                                                    overflow: 'hidden',
                                                                    '&.Mui-checked': {
                                                                        color: 'inherit',
                                                                    },
                                                                }}
                                                            />
                                                            <Typography
                                                                variant="subtitle1"
                                                                fontWeight={600}
                                                                textAlign="center"
                                                                sx={{overflow: 'hidden', overflowWrap: 'break-word'}}
                                                            >
                                                                {'Empate'}
                                                            </Typography>
                                                        </Stack>
                                                    </Paper>
                                                    <Paper
                                                        component="label"
                                                        variant="outlined"
                                                        sx={{
                                                            px: 1.5,
                                                            py: 1,
                                                            position: 'relative',
                                                            display: 'flex',
                                                            alignItems: 'center',
                                                            justifyContent: 'center',
                                                            cursor: 'pointer',
                                                            borderWidth: 2,
                                                            borderColor: selectedPicks[fixture.id] === 'away' ? '#7a1800' : 'divider',
                                                            backgroundColor: selectedPicks[fixture.id] === 'away' ? 'rgba(255,0,0,0.25)' : 'grey.50',
                                                            color: selectedPicks[fixture.id] === 'away' ? 'black' : 'text.primary',
                                                            transition: 'background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease',
                                                            opacity: savingPickIds.includes(fixture.id) ? 0.7 : 1,
                                                        }}
                                                    >
                                                        <Stack
                                                            direction="row"
                                                            spacing={1}
                                                            alignItems="center"
                                                            justifyContent="center"
                                                        >
                                                            <Radio
                                                                value={'away'}
                                                                checked={selectedPicks[fixture.id] === 'away'}
                                                                disabled={savingPickIds.includes(fixture.id)}
                                                                sx={{
                                                                    position: 'absolute',
                                                                    opacity: 0,
                                                                    width: 1,
                                                                    height: 1,
                                                                    m: 0,
                                                                    p: 0,
                                                                    overflow: 'hidden',
                                                                    '&.Mui-checked': {
                                                                        color: 'inherit',
                                                                    },
                                                                }}
                                                            />
                                                            <span className={`fi fi-${fixture.away_short_name}`}></span>
                                                            <Typography
                                                                variant="subtitle1"
                                                                fontWeight={600}
                                                                textAlign="center"
                                                                sx={{overflow: 'hidden', overflowWrap: 'break-word'}}
                                                            >
                                                                {fixture.away_team}
                                                            </Typography>
                                                        </Stack>
                                                    </Paper>
                                                </Box>
                                            </RadioGroup>
                                            {(() => {
                                                const pickStatus = getPickStatus(fixture.id);

                                                return (
                                                    <Typography
                                                        variant="caption"
                                                        sx={{
                                                            mt: 1.5,
                                                            color: pickStatus.color,
                                                            fontWeight: 600,
                                                        }}
                                                    >
                                                        {pickStatus.label}
                                                    </Typography>
                                                );
                                            })()}
                                        </Box>
                                    </Paper>
                                ))}
                            </Stack>
                        )}
                    </Stack>
                </Paper>
                {footerTotalCount > 0 ? (
                    <Box
                        aria-hidden
                        sx={{
                            height: `calc(${footerBottomPadding}px + env(safe-area-inset-bottom, 0px))`,
                        }}
                    />
                ) : null}
                {!isLoadingFixtures && footerTotalCount > 0 ? (
                    <Box
                        ref={footerRef}
                        sx={{
                            position: 'fixed',
                            left: 0,
                            right: 0,
                            bottom: 0,
                            px: {xs: 1.5, sm: 3},
                            pb: {xs: 1.5, sm: 2.5},
                            zIndex: 1200,
                        }}
                    >
                        <Paper
                            elevation={10}
                            sx={{
                                maxWidth: 720,
                                mx: 'auto',
                                borderRadius: 4,
                                px: {xs: 2, sm: 3},
                                py: 1.75,
                                border: '1px solid',
                                borderColor: 'divider',
                                backgroundColor: 'rgba(255,255,255,0.96)',
                                backdropFilter: 'blur(10px)',
                            }}
                        >
                            <Stack spacing={1.5}>
                                <Stack
                                    direction="row"
                                    alignItems="center"
                                    justifyContent="space-between"
                                    spacing={2}
                                >
                                    <Box>
                                        <Typography variant="subtitle1" fontWeight={700}>
                                            {savedCount}/{footerTotalCount} resultados registrados
                                        </Typography>
                                        <Typography variant="body2" color="text.secondary">
                                            {missingCount} pendientes por registrar
                                        </Typography>
                                    </Box>
                                    <Stack direction="row" spacing={1.5} alignItems="center">
                                        <Stack direction="row" spacing={0.5} alignItems="center">
                                            <CheckCircleRoundedIcon sx={{fontSize: 18, color: 'primary.main'}}/>
                                            <Typography variant="body2" fontWeight={600} color="primary.main">
                                                {savedCount}
                                            </Typography>
                                        </Stack>
                                        <Stack direction="row" spacing={0.5} alignItems="center">
                                            <ScheduleRoundedIcon sx={{fontSize: 18, color: 'grey.500'}}/>
                                            <Typography variant="body2" fontWeight={600} color="text.secondary">
                                                {missingCount}
                                            </Typography>
                                        </Stack>
                                    </Stack>
                                </Stack>
                                {footerPreviewCount > fixtures.length ? (
                                    <Typography variant="caption" color="text.secondary">
                                        Vista previa del footer con {footerPreviewCount} partidos
                                    </Typography>
                                ) : null}
                                <Box
                                    sx={{
                                        display: 'grid',
                                        gridTemplateColumns: 'repeat(auto-fit, minmax(18px, 18px))',
                                        gap: 0.75,
                                        justifyContent: 'start',
                                    }}
                                >
                                    {footerItems.map((item) => {
                                        if (item.fixtureId && savingPickIds.includes(item.fixtureId)) {
                                            return (
                                                <SyncRoundedIcon
                                                    key={item.key}
                                                    sx={{
                                                        fontSize: 18,
                                                        color: 'text.secondary',
                                                        animation: 'spin 1s linear infinite',
                                                        '@keyframes spin': {
                                                            from: {transform: 'rotate(0deg)'},
                                                            to: {transform: 'rotate(-360deg)'},
                                                        },
                                                    }}
                                                />
                                            );
                                        }

                                        if (item.fixtureId && savedPicks[item.fixtureId]) {
                                            return (
                                                <CheckCircleRoundedIcon
                                                    key={item.key}
                                                    sx={{fontSize: 18, color: 'primary.main'}}
                                                />
                                            );
                                        }

                                        return (
                                            <ScheduleRoundedIcon
                                                key={item.key}
                                                sx={{fontSize: 18, color: 'grey.500'}}
                                            />
                                        );
                                    })}
                                </Box>
                            </Stack>
                        </Paper>
                    </Box>
                ) : null}
            </Box>
        </AuthGuard>
    )
}

export default PicksPage;
