import React, { useEffect, useState } from 'react';
import GlobalStyles from '@mui/joy/GlobalStyles';
import Avatar from '@mui/joy/Avatar';
import Box from '@mui/joy/Box';
import Button from '@mui/joy/Button';
import Card from '@mui/joy/Card';
import ListItemDecorator from '@mui/joy/ListItemDecorator';
import { ListDivider, ListSubheader } from "@mui/joy";
import Divider from '@mui/joy/Divider';
import Badge from "@mui/joy/Badge";
import DnsIcon from '@mui/icons-material/Dns';
import AutoAwesomeIcon from '@mui/icons-material/AutoAwesome';
import IconButton from '@mui/joy/IconButton';
import Input from '@mui/joy/Input';
import LinearProgress from '@mui/joy/LinearProgress';
import List from '@mui/joy/List';
import ListItem from '@mui/joy/ListItem';
import ListItemButton, { listItemButtonClasses } from '@mui/joy/ListItemButton';
import ListItemContent from '@mui/joy/ListItemContent';
import Typography from '@mui/joy/Typography';
import Sheet from '@mui/joy/Sheet';
import SearchRoundedIcon from '@mui/icons-material/SearchRounded';
import HomeRoundedIcon from '@mui/icons-material/HomeRounded';
import SettingsRoundedIcon from '@mui/icons-material/SettingsRounded';
import LogoutRoundedIcon from '@mui/icons-material/LogoutRounded';
import FeedRoundedIcon from '@mui/icons-material/FeedRounded';
import EmojiObjectsTwoToneIcon from '@mui/icons-material/EmojiObjectsTwoTone';
import CampaignRoundedIcon from '@mui/icons-material/CampaignRounded';
import InfoRoundedIcon from '@mui/icons-material/InfoRounded';
import GradeIcon from '@mui/icons-material/Grade';
import { Link, useNavigate } from 'react-router-dom';
import { closeSidebar } from "../../utils/uiUtils";
import { useLocation } from "react-router-dom";
import SellIcon from '@mui/icons-material/Sell';
import NamedEntityChip from "../news/chips/NamedEntityChip";
import namedEntitySlice from "../../store/namedEntitySlice";
import { useAppDispatch, useAppSelector } from "../../store/hooks";
import { NamedEntity } from "../../model/NamedEntity";
import { EnvUtils } from "../../utils/env.utils";
import { serverUrl } from "../../utils/request";
import dayjs from "dayjs";

function Toggler({
    defaultExpanded = false,
    renderToggle,
    children,
}: {
    defaultExpanded?: boolean;
    children: React.ReactNode;
    renderToggle: (params: {
        open: boolean;
        setOpen: React.Dispatch<React.SetStateAction<boolean>>;
    }) => React.ReactNode;
}) {
    const [open, setOpen] = React.useState(defaultExpanded);
    return (
        <React.Fragment>
            {renderToggle({ open, setOpen })}
            <Box
                sx={{
                    display: 'grid',
                    gridTemplateRows: open ? '1fr' : '0fr',
                    transition: '0.2s ease',
                    '& > *': {
                        overflow: 'hidden',
                    },
                }}
            >
                {children}
            </Box>
        </React.Fragment>
    );
}

type ColorType = "primary" | "warning" | "success" | "neutral" | "danger" | undefined;
type ServiceStatus = {
    color: ColorType;
    status: string;
    lastUpdated: string;
};

function Sidebar() {
    const initialBackendStatus: ServiceStatus = {
        color: 'neutral',
        status: 'Loading...',
        lastUpdated: dayjs().format('HH:mm:ss'),
    };

    const initialAiServiceStatus: ServiceStatus = {
        color: 'neutral',
        status: 'Loading...',
        lastUpdated: dayjs().format('HH:mm:ss'),
    };

    const navigation = useNavigate();
    const location = useLocation();
    const [selectedItem, setSelectedItem] = useState('' as string);
    const [backendStatus, setBackendStatus] = useState(initialBackendStatus as ServiceStatus);
    const [aiServiceStatus, setAiServiceStatus] = useState(initialAiServiceStatus as ServiceStatus);
    const [namedEntityHistoryState, setNamedEntityHistoryState] = useState([] as NamedEntity[]);

    const namedEntityHistory = useAppSelector((state) => state.namedEntity.history);

    // update the selected item in the sidebar when the location changes
    useEffect(() => {
        setSelectedItem(location.pathname);
    }, [location]);

    useEffect(() => {
        setNamedEntityHistoryState(namedEntityHistory);
    }, [namedEntityHistory]);

    useEffect(() => {
        const interval = setInterval(() => {
            const lastUpdated = dayjs().format('HH:mm:ss');
            fetch(`${serverUrl()}/status`)
                .then((response) => response.json())
                .then((data) => {
                    data = data.serviceStatus;
                    let statusBackend = { color: "neutral", status: "Unknown", lastUpdated } as ServiceStatus;
                    if (data.backend_status === 'UP') {
                        statusBackend = { color: "success", status: "Running", lastUpdated } as ServiceStatus;
                    } else if (data.backend_status === 'DOWN') {
                        statusBackend = { color: "danger", status: "Down", lastUpdated } as ServiceStatus;
                    }

                    setBackendStatus(statusBackend);

                    let statusAiService = { color: "neutral", status: "Unknown", lastUpdated } as ServiceStatus;
                    if (data.ai_service_status === 'UP' || data.ai_service_status === 'READY') {
                        statusAiService = { color: "success", status: data.ai_service_status, lastUpdated } as ServiceStatus;
                    } else if (data.ai_service_status === "CONNECTING") {
                        statusAiService = { color: "warning", status: "Connecting", lastUpdated } as ServiceStatus;
                    } else if (data.ai_service_status === 'DOWN' || data.ai_service_status === 'INVALID_STATE'
                        || data.ai_service_status === 'SHUTDOWN' || data.ai_service_status === 'TRANSIENT_FAILURE'
                    ) {
                        statusAiService = { color: "danger", status: "Down", lastUpdated } as ServiceStatus;
                    }

                    setAiServiceStatus(statusAiService);
                })
                .catch((error) => {
                    const errorStatus = { color: "danger", status: "Failed", lastUpdated } as ServiceStatus;
                    setBackendStatus(errorStatus);
                    setAiServiceStatus(errorStatus);
                });
        }, 5000);
        return () => clearInterval(interval);
    }, []);

    const env = process.env.NODE_ENV;
    const containerName = EnvUtils.get().containerName || 'Localhost';

    return (
        <Sheet
            className="Sidebar"
            sx={{
                position: { xs: 'fixed', md: 'sticky' },
                transform: {
                    xs: 'translateX(calc(100% * (var(--SideNavigation-slideIn, 0) - 1)))',
                    md: 'none',
                },
                transition: 'transform 0.4s, width 0.4s',
                zIndex: 10000,
                height: '100dvh',
                width: 'var(--Sidebar-width)',
                top: 0,
                p: 2,
                flexShrink: 0,
                display: 'flex',
                flexDirection: 'column',
                gap: 2,
                borderRight: '1px solid',
                borderColor: 'divider',
            }}
        >
            <GlobalStyles
                styles={(theme) => ({
                    ':root': {
                        '--Sidebar-width': '220px',
                        [theme.breakpoints.up('lg')]: {
                            '--Sidebar-width': '240px',
                        },
                    },
                })}
            />
            <Box
                className="Sidebar-overlay"
                sx={{
                    position: 'fixed',
                    zIndex: 9998,
                    top: 0,
                    left: 0,
                    width: '100vw',
                    height: '100vh',
                    opacity: 'var(--SideNavigation-slideIn)',
                    backgroundColor: 'var(--joy-palette-background-backdrop)',
                    transition: 'opacity 0.4s',
                    transform: {
                        xs: 'translateX(calc(100% * (var(--SideNavigation-slideIn, 0) - 1) + var(--SideNavigation-slideIn, 0) * var(--Sidebar-width, 0px)))',
                        lg: 'translateX(-100%)',
                    },
                }}
                onClick={() => closeSidebar()}
            />
            <Box sx={{ display: 'flex', gap: 1, alignItems: 'center' }}>
                <IconButton variant="soft" color="success" size="md">
                    <EmojiObjectsTwoToneIcon />
                </IconButton>
                <Typography level="title-lg" onClick={() => navigation('/')}>
                    MarketMinds
                </Typography>
            </Box>
            <Input size="sm" startDecorator={<SearchRoundedIcon />} placeholder="Search" />
            <Box
                sx={{
                    minHeight: 0,
                    overflow: 'hidden auto',
                    flexGrow: 1,
                    display: 'flex',
                    flexDirection: 'column',
                    [`& .${listItemButtonClasses.root}`]: {
                        gap: 1.5,
                    },
                }}
            >
                <List
                    size="sm"
                    sx={{
                        gap: 1,
                        '--List-nestedInsetStart': '30px',
                        '--ListItem-radius': (theme) => theme.vars.radius.sm,
                    }}
                >
                    <ListItem>
                        <ListItemButton
                            role="menuitem"
                            component={Link}
                            to="/"
                            selected={selectedItem === '/'}
                        >
                            <HomeRoundedIcon />
                            <ListItemContent>
                                <Typography level="title-sm">Home</Typography>
                            </ListItemContent>
                        </ListItemButton>
                    </ListItem>

                    <ListItem>
                        <ListItemButton
                            role="menuitem"
                            component={Link}
                            to="/latest"
                            selected={selectedItem === '/latest'}
                        >
                            <FeedRoundedIcon />
                            <ListItemContent>
                                <Typography level="title-sm">Latest News</Typography>
                            </ListItemContent>
                        </ListItemButton>
                    </ListItem>

                    <ListItem>
                        <ListItemButton
                            role="menuitem"
                            component={Link}
                            to="/tags"
                            selected={selectedItem === '/tags'}
                        >
                            <SellIcon />
                            <ListItemContent>
                                <Typography level="title-sm">Tags</Typography>
                            </ListItemContent>
                        </ListItemButton>
                    </ListItem>

                    <ListItem>
                        <ListItemButton
                            role="menuitem"
                            component={Link}
                            to="/news-channels"
                            selected={selectedItem === '/news-channels'}
                        >
                            <GradeIcon />
                            <ListItemContent>
                                <Typography level="title-sm">News Channels</Typography>
                            </ListItemContent>
                        </ListItemButton>
                    </ListItem>

                    <ListItem>
                        <ListItemButton
                            role="menuitem"
                            component={Link}
                            to="/about"
                            selected={selectedItem === '/about'}
                        >
                            <InfoRoundedIcon />
                            <ListItemContent>
                                <Typography level="title-sm">About</Typography>
                            </ListItemContent>
                        </ListItemButton>
                    </ListItem>
                </List>

                {namedEntityHistoryState.length > 0 &&
                    <Sheet
                        variant="outlined"
                        sx={{
                            maxHeight: 250,
                            height: 250,
                            overflow: 'auto',
                            borderRadius: 'sm',
                        }}
                    >
                        <List>
                            <ListItem nested>
                                <ListSubheader>Last 10 Tags Viewed</ListSubheader>
                                <List>
                                    {namedEntityHistoryState.filter(n => n.name).map((namedEntity) => (
                                        <ListItem key={namedEntity.name}>
                                            <NamedEntityChip namedEntity={namedEntity} />
                                        </ListItem>
                                    ))}
                                </List>
                            </ListItem>
                        </List>
                    </Sheet>}

                <List
                    size="sm"
                    sx={{
                        mt: 2,
                        flexGrow: 0,
                        '--ListItem-radius': (theme) => theme.vars.radius.sm,
                        '--List-gap': '8px',
                        mb: 2,
                    }}
                >
                    <ListItem>
                        <ListItemButton
                            role="menuitem"
                            component={Link}
                            to="/configure-feeds"
                            selected={selectedItem === '/configure-feeds'}
                        >
                            <CampaignRoundedIcon />
                            <ListItemContent>
                                <Typography level="title-sm">Configure Feeds</Typography>
                            </ListItemContent>
                        </ListItemButton>
                    </ListItem>

                    <ListItem>
                        <ListItemButton
                            role="menuitem"
                            component={Link}
                            to="/settings"
                            selected={selectedItem === '/settings'}
                        >
                            <SettingsRoundedIcon />
                            <ListItemContent>
                                <Typography level="title-sm">Settings</Typography>
                            </ListItemContent>
                        </ListItemButton>
                    </ListItem>
                </List>
            </Box>
            <Divider />
            <Box sx={{ display: 'flex', gap: 1, alignItems: 'center' }}>
                <Box sx={{ minWidth: 0, flex: 1 }}>
                    <Typography level="title-sm">Status</Typography>
                    <Typography level="body-xs">Last Updated: {backendStatus.lastUpdated}</Typography>
                    <Typography level="body-xs">Environment: {env}</Typography>
                    <Typography level="body-xs">Container: {containerName}</Typography>

                    <Box sx={{ mt: 2, display: 'flex', gap: 2, alignItems: 'center' }}>
                        <Badge badgeInset="-10%" color={backendStatus.color}>
                            <DnsIcon fontSize="medium" />
                        </Badge>
                        <Typography level="body-xs">Backend: {backendStatus.status}</Typography>
                    </Box>

                    <Box sx={{ mt: 2, display: 'flex', gap: 2, alignItems: 'center' }}>
                        <Badge badgeInset="-10%" color={aiServiceStatus.color}>
                            <AutoAwesomeIcon fontSize="medium" />
                        </Badge>
                        <Typography level="body-xs">AI Services: {aiServiceStatus.status}</Typography>
                    </Box>
                </Box>
            </Box>
        </Sheet>
    );
}

export default Sidebar;