import { useState, useEffect, useRef } from 'react';
import { useMediaQuery } from 'react-responsive';
import useResize from '../hooks/resizeHook';

import { Player, Metrics } from '../types';

import { Card, Typography } from '@mui/material';
import CardContent from '@mui/material/CardContent';
import CircularProgress from '@mui/material/CircularProgress';
import Box from '@mui/material/Box';
import { Button } from '@mui/material';
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp';
import ClickAwayListener from '@mui/material/ClickAwayListener';
import Grow from '@mui/material/Grow';
import Paper from '@mui/material/Paper';
import Popper from '@mui/material/Popper';
import MenuItem from '@mui/material/MenuItem';
import MenuList from '@mui/material/MenuList';
import Table from '@mui/material/Table';
import TableBody from '@mui/material/TableBody';
import TableCell from '@mui/material/TableCell';
import TableContainer from '@mui/material/TableContainer';
import TableHead from '@mui/material/TableHead';
import TableRow from '@mui/material/TableRow';
export default function MetricsCard({
    metrics,
    loadingMetrics,
    isPitcher
}: {
    metrics: Metrics[],
    loadingMetrics: boolean,
    isPitcher: boolean
}) {
    const isMobile = useMediaQuery({ maxWidth: 600 });
    useResize();

    const [selectedOpponentId, setSelectedOpponentId] = useState<string>("");
    const [selectedOpponentName, setSelectedOpponentName] = useState("");
    const [opponents, setOpponents] = useState<Player[]>([]);
    const [openOpponentsMenu, setOpenOpponentsMenu] = useState(false);
    const anchorRef = useRef<HTMLButtonElement>(null);
    const [loadingOpponents, setLoadingOpponents] = useState(true);

    const cardTitlePrefix = isPitcher ? "Pitcher vs. Batter" : "Batter vs. Pitcher"

    const opponentIds: number[] = [];
    metrics.forEach((metric) => {
        const oppId = isPitcher ? metric.batterid : metric.pitcherid;
        if (!opponentIds.includes(oppId)) opponentIds.push(oppId);
    });

    async function fetchOpponents() {
        try {
            const opponentsData: Player[] = [];
            await Promise.all(opponentIds.map(async (playerid) => {
                if (!playerid) return;
                const response = await fetch(`${process.env.NEXT_PUBLIC_BASE_API_URL}/playername/${playerid}`);
                const data = await response.json();
                if (data.length > 0) {
                    opponentsData.push(data[0]);
                }
            })).then(() => {
                if (opponentsData.length > 0) {
                    setOpponents(opponentsData);
                    setLoadingOpponents(false);
                }
            });
        } catch (error: any) {
            console.error('Error fetching opponents: ', error);
        }
    }

    useEffect(() => {
        // eslint-disable-next-line react-hooks/set-state-in-effect
        fetchOpponents();
    }, [metrics]);

    const handleOpponentsMenuToggle = () => {
        setOpenOpponentsMenu((oppsMenuPrevOpen) => !oppsMenuPrevOpen);
    };

    const handleOppsMenuClose = (event: Event | React.SyntheticEvent) => {
        if (
            anchorRef.current &&
            anchorRef.current.contains(event.target as HTMLElement)
        ) {
            return;
        }

        setOpenOpponentsMenu(false);
    };

    function handleListKeyDown(event: React.KeyboardEvent) {
        if (event.key === 'Tab') {
            event.preventDefault();
            setOpenOpponentsMenu(false);
        } else if (event.key === 'Escape') {
            setOpenOpponentsMenu(false);
        }
    }

    // return focus to the button when we transitioned from !open -> open
    const oppsMenuPrevOpen = useRef(openOpponentsMenu);
    useEffect(() => {
        if (oppsMenuPrevOpen.current === true && openOpponentsMenu === false) {
            anchorRef.current!.focus();
        }

        oppsMenuPrevOpen.current = openOpponentsMenu;
    }, [openOpponentsMenu]);

    function setCurrentOpponent(event: React.MouseEvent | React.KeyboardEvent) {
        const ev = event?.nativeEvent?.target as HTMLDivElement;
        setSelectedOpponentId(ev.dataset.oppId ? ev.dataset.oppId : "");
        setSelectedOpponentName(ev.outerText);
        handleOppsMenuClose(event);
    }
    function renderTeamsMenuItems() {
        return opponents.map((opp, index) => {
            return (
                <MenuItem data-opp-id={opp.playerid} onClick={setCurrentOpponent} key={index}>
                    {opp.firstname} {opp.lastname}
                </MenuItem >
            )
        });
    }

    function metricsTable() {
        const metricsForOpponent = metrics.filter((metric) => {
            if (selectedOpponentId.length == 0) return;
            return isPitcher ? metric.batterid === parseInt(selectedOpponentId) : metric.pitcherid === parseInt(selectedOpponentId);
        });

        return (
            <TableContainer component={Paper}>
                <Table sx={{ minWidth: 650 }} aria-label="Player Statistics Table">
                    <TableHead>
                        <TableRow>
                            <TableCell><b>Pitch No.</b></TableCell>
                            <TableCell><b>Pitch Type</b></TableCell>
                            <TableCell><b>Pitch Result</b></TableCell>
                            <TableCell><b>Pitch Velocity</b></TableCell>
                            <TableCell><b>Pitch X,Y</b></TableCell>
                            <TableCell><b>Hit Velocity</b></TableCell>
                            <TableCell><b>Hit Angle</b></TableCell>
                        </TableRow>
                    </TableHead>
                    <TableBody>
                        {metricsForOpponent.map((m: Metrics, index: number) => {
                            return (
                                <TableRow
                                    key={index}
                                    sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
                                >
                                    <TableCell align="center">{index + 1}</TableCell>
                                    <TableCell>{m.pitch_type}</TableCell>
                                    <TableCell>{m.pitch_result}</TableCell>
                                    <TableCell align="center">{m.pitch_velocity}</TableCell>
                                    <TableCell>{m.platex}, {m.platey}</TableCell>
                                    <TableCell align="center">{m.hit_velocity ? m.hit_velocity : '-'}</TableCell>
                                    <TableCell align="center">{m.hit_vertical_angle ? m.hit_vertical_angle : '-'}</TableCell>
                                </TableRow>
                            )
                        })}
                    </TableBody>
                </Table>
            </TableContainer>
        );
    }

    function metricsNotFound() {
        return (
            <div className="flex content-center">
                <Card sx={{ maxWidth: 345 }}>
                    <CardContent className="bg-red-100">
                        <Typography>
                            <b>ERROR:</b> Metrics not found for this player.
                        </Typography>
                    </CardContent>
                </Card>
            </div>
        );
    }

    function opponentSelectionWidget() {
        return (
            <>
                <Button
                    ref={anchorRef}
                    id="opponents-menu-button"
                    aria-controls={openOpponentsMenu ? 'opponents-menu-button' : undefined}
                    aria-expanded={openOpponentsMenu ? 'true' : undefined}
                    aria-haspopup="true"
                    onClick={handleOpponentsMenuToggle}
                    sx={{ fontSize: 18 }}
                >
                    Opponents {openOpponentsMenu ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />}
                </Button>
                <span style={{ height: 150, overflow: 'auto' }}>
                    <Popper
                        open={openOpponentsMenu}
                        anchorEl={anchorRef.current}
                        role={undefined}
                        placement="bottom-start"
                        transition
                        disablePortal
                    >
                        {({ TransitionProps, placement }) => (
                            <Grow
                                {...TransitionProps}
                                style={{
                                    transformOrigin:
                                        placement === 'bottom-start' ? 'left top' : 'left bottom',
                                }}
                            >
                                <Paper>
                                    <ClickAwayListener onClickAway={handleOpponentsMenuToggle}>
                                        <MenuList
                                            autoFocusItem={openOpponentsMenu}
                                            id="composition-menu"
                                            aria-labelledby="composition-button"
                                            onKeyDown={handleListKeyDown}
                                            style={{ maxHeight: 200, overflow: 'scroll' }}
                                        >
                                            {renderTeamsMenuItems()}
                                        </MenuList>
                                    </ClickAwayListener>
                                </Paper>
                            </Grow>
                        )}
                    </Popper>
                </span>
                {isMobile ?
                    <div style={{ paddingLeft: 8 }}>Selected Opponent: {selectedOpponentName}</div>
                    :
                    <span>Selected Opponent: {selectedOpponentName}</span>
                }
            </>
        );
    }
    
    return (
        <Card sx={{ minHeight: 300, marginBottom: 10 }}>
            <CardContent>
                <Typography gutterBottom variant="h5" component="div" className="flex justify-center text-center">{cardTitlePrefix} Metrics</Typography>
                { loadingMetrics ?
                    <Box sx={{ display: 'flex' }}>
                        <CircularProgress />
                    </Box>
                    :
                    <>{metrics.length > 0 ?
                        <div className="flex flex-col">
                            <div>
                                { loadingOpponents ?
                                     <Box sx={{ display: 'flex' }}>
                                        <CircularProgress />
                                    </Box>
                                    :
                                    <div>
                                            {opponentSelectionWidget()}
                                    </div>
                                }
                            </div>
                            {metricsTable()}
                        </div>
                        :
                        <>
                            {metricsNotFound()}
                        </>
                        }
                    </>
                }
            </CardContent>
        </Card>
    )
}