import * as React from 'react';
import {useContext, useEffect, useState} from 'react';
import {
    Alert,
    CardActions,
    CardContent, Chip,
    FormControl,
    Select,
    Stack,
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableRow,
    Tooltip,
    useMediaQuery
} from "@mui/material";
import Typography from "@mui/material/Typography";
import prefs from "../app/Prefs";
import {Paragraph} from "./styles";
import EditIcon from '@mui/icons-material/Edit';
import CloseIcon from "@mui/icons-material/Close";
import WarningIcon from '@mui/icons-material/Warning';
import IconButton from "@mui/material/IconButton";
import PlayArrowIcon from '@mui/icons-material/PlayArrow';
import Container from "@mui/material/Container";
import TextField from "@mui/material/TextField";
import MenuItem from "@mui/material/MenuItem";
import Card from "@mui/material/Card";
import Button from "@mui/material/Button";
import {useLiveQuery} from "dexie-react-hooks";
import theme from "./theme";
import Dialog from "@mui/material/Dialog";
import DialogTitle from "@mui/material/DialogTitle";
import DialogContent from "@mui/material/DialogContent";
import DialogActions from "@mui/material/DialogActions";
import userManager from "../app/UserManager";
import {playSound, shuffle, sounds, validTopic, validUrl} from "../app/utils";
import {useTranslation} from "react-i18next";
import session from "../app/Session";
import routes from "./routes";
import accountApi, {UnauthorizedError} from "../app/AccountApi";
import {Pref, PrefGroup} from "./Pref";
import LockIcon from "@mui/icons-material/Lock";
import {Check, Info, Public, PublicOff} from "@mui/icons-material";
import DialogContentText from "@mui/material/DialogContentText";
import ReserveTopicSelect from "./ReserveTopicSelect";
import {AccountContext} from "./App";
import {useOutletContext} from "react-router-dom";
import subscriptionManager from "../app/SubscriptionManager";

const Preferences = () => {
    return (
        <Container maxWidth="md" sx={{marginTop: 3, marginBottom: 3}}>
            <Stack spacing={3}>
                <Notifications/>
                <Reservations/>
                <Users/>
                <Appearance/>
            </Stack>
        </Container>
    );
};

const Notifications = () => {
    const { t } = useTranslation();
    return (
        <Card sx={{p: 3}} aria-label={t("prefs_notifications_title")}>
            <Typography variant="h5" sx={{marginBottom: 2}}>
                {t("prefs_notifications_title")}
            </Typography>
            <PrefGroup>
                <Sound/>
                <MinPriority/>
                <DeleteAfter/>
            </PrefGroup>
        </Card>
    );
};

const Sound = () => {
    const { t } = useTranslation();
    const labelId = "prefSound";
    const sound = useLiveQuery(async () => prefs.sound());
    const handleChange = async (ev) => {
        await prefs.setSound(ev.target.value);
        await maybeUpdateAccountSettings({
            notification: {
                sound: ev.target.value
            }
        });
    }
    if (!sound) {
        return null; // While loading
    }
    let description;
    if (sound === "none") {
        description = t("prefs_notifications_sound_description_none");
    } else {
        description = t("prefs_notifications_sound_description_some", { sound: sounds[sound].label });
    }
    return (
        <Pref labelId={labelId} title={t("prefs_notifications_sound_title")} description={description}>
            <div style={{ display: 'flex', width: '100%' }}>
                <FormControl fullWidth variant="standard" sx={{ margin: 1 }}>
                    <Select value={sound} onChange={handleChange} aria-labelledby={labelId}>
                        <MenuItem value={"none"}>{t("prefs_notifications_sound_no_sound")}</MenuItem>
                        {Object.entries(sounds).map(s => <MenuItem key={s[0]} value={s[0]}>{s[1].label}</MenuItem>)}
                    </Select>
                </FormControl>
                <IconButton onClick={() => playSound(sound)} disabled={sound === "none"} aria-label={t("prefs_notifications_sound_play")}>
                    <PlayArrowIcon />
                </IconButton>
            </div>
        </Pref>
    )
};

const MinPriority = () => {
    const { t } = useTranslation();
    const labelId = "prefMinPriority";
    const minPriority = useLiveQuery(async () => prefs.minPriority());
    const handleChange = async (ev) => {
        await prefs.setMinPriority(ev.target.value);
        await maybeUpdateAccountSettings({
            notification: {
                min_priority: ev.target.value
            }
        });
    }
    if (!minPriority) {
        return null; // While loading
    }
    const priorities = {
        1: t("priority_min"),
        2: t("priority_low"),
        3: t("priority_default"),
        4: t("priority_high"),
        5: t("priority_max")
    }
    let description;
    if (minPriority === 1) {
        description = t("prefs_notifications_min_priority_description_any");
    } else if (minPriority === 5) {
        description = t("prefs_notifications_min_priority_description_max");
    } else {
        description = t("prefs_notifications_min_priority_description_x_or_higher", {
            number: minPriority,
            name: priorities[minPriority]
        });
    }
    return (
        <Pref labelId={labelId} title={t("prefs_notifications_min_priority_title")} description={description}>
            <FormControl fullWidth variant="standard" sx={{ m: 1 }}>
                <Select value={minPriority} onChange={handleChange} aria-labelledby={labelId}>
                    <MenuItem value={1}>{t("prefs_notifications_min_priority_any")}</MenuItem>
                    <MenuItem value={2}>{t("prefs_notifications_min_priority_low_and_higher")}</MenuItem>
                    <MenuItem value={3}>{t("prefs_notifications_min_priority_default_and_higher")}</MenuItem>
                    <MenuItem value={4}>{t("prefs_notifications_min_priority_high_and_higher")}</MenuItem>
                    <MenuItem value={5}>{t("prefs_notifications_min_priority_max_only")}</MenuItem>
                </Select>
            </FormControl>
        </Pref>
    )
};

const DeleteAfter = () => {
    const { t } = useTranslation();
    const labelId = "prefDeleteAfter";
    const deleteAfter = useLiveQuery(async () => prefs.deleteAfter());
    const handleChange = async (ev) => {
        await prefs.setDeleteAfter(ev.target.value);
        await maybeUpdateAccountSettings({
            notification: {
                delete_after: ev.target.value
            }
        });
    }
    if (deleteAfter === null || deleteAfter === undefined) { // !deleteAfter will not work with "0"
        return null; // While loading
    }
    const description = (() => {
        switch (deleteAfter) {
            case 0: return t("prefs_notifications_delete_after_never_description");
            case 10800: return t("prefs_notifications_delete_after_three_hours_description");
            case 86400: return t("prefs_notifications_delete_after_one_day_description");
            case 604800: return t("prefs_notifications_delete_after_one_week_description");
            case 2592000: return t("prefs_notifications_delete_after_one_month_description");
        }
    })();
    return (
        <Pref labelId={labelId} title={t("prefs_notifications_delete_after_title")} description={description}>
            <FormControl fullWidth variant="standard" sx={{ m: 1 }}>
                <Select value={deleteAfter} onChange={handleChange} aria-labelledby={labelId}>
                    <MenuItem value={0}>{t("prefs_notifications_delete_after_never")}</MenuItem>
                    <MenuItem value={10800}>{t("prefs_notifications_delete_after_three_hours")}</MenuItem>
                    <MenuItem value={86400}>{t("prefs_notifications_delete_after_one_day")}</MenuItem>
                    <MenuItem value={604800}>{t("prefs_notifications_delete_after_one_week")}</MenuItem>
                    <MenuItem value={2592000}>{t("prefs_notifications_delete_after_one_month")}</MenuItem>
                </Select>
            </FormControl>
        </Pref>
    )
};

const Users = () => {
    const { t } = useTranslation();
    const [dialogKey, setDialogKey] = useState(0);
    const [dialogOpen, setDialogOpen] = useState(false);
    const users = useLiveQuery(() => userManager.all());
    const handleAddClick = () => {
        setDialogKey(prev => prev+1);
        setDialogOpen(true);
    };
    const handleDialogCancel = () => {
        setDialogOpen(false);
    };
    const handleDialogSubmit = async (user) => {
        setDialogOpen(false);
        try {
            await userManager.save(user);
            console.debug(`[Preferences] User ${user.username} for ${user.baseUrl} added`);
        } catch (e) {
            console.log(`[Preferences] Error adding user.`, e);
        }
    };
    return (
        <Card sx={{ padding: 1 }} aria-label={t("prefs_users_title")}>
            <CardContent sx={{ paddingBottom: 1 }}>
                <Typography variant="h5" sx={{marginBottom: 2}}>
                    {t("prefs_users_title")}
                </Typography>
                <Paragraph>
                    {t("prefs_users_description")}
                    {session.exists() && <>{" " + t("prefs_users_description_no_sync")}</>}
                </Paragraph>
                {users?.length > 0 && <UserTable users={users}/>}
            </CardContent>
            <CardActions>
                <Button onClick={handleAddClick}>{t("prefs_users_add_button")}</Button>
                <UserDialog
                    key={`userAddDialog${dialogKey}`}
                    open={dialogOpen}
                    user={null}
                    users={users}
                    onCancel={handleDialogCancel}
                    onSubmit={handleDialogSubmit}
                />
            </CardActions>
        </Card>
    );
};

const UserTable = (props) => {
    const { t } = useTranslation();
    const [dialogKey, setDialogKey] = useState(0);
    const [dialogOpen, setDialogOpen] = useState(false);
    const [dialogUser, setDialogUser] = useState(null);

    const handleEditClick = (user) => {
        setDialogKey(prev => prev+1);
        setDialogUser(user);
        setDialogOpen(true);
    };

    const handleDialogCancel = () => {
        setDialogOpen(false);
    };

    const handleDialogSubmit = async (user) => {
        setDialogOpen(false);
        try {
            await userManager.save(user);
            console.debug(`[Preferences] User ${user.username} for ${user.baseUrl} updated`);
        } catch (e) {
            console.log(`[Preferences] Error updating user.`, e);
        }
    };

    const handleDeleteClick = async (user) => {
        try {
            await userManager.delete(user.baseUrl);
            console.debug(`[Preferences] User ${user.username} for ${user.baseUrl} deleted`);
        } catch (e) {
            console.error(`[Preferences] Error deleting user for ${user.baseUrl}`, e);
        }
    };

    return (
        <Table size="small" aria-label={t("prefs_users_table")}>
            <TableHead>
                <TableRow>
                    <TableCell sx={{paddingLeft: 0}}>{t("prefs_users_table_user_header")}</TableCell>
                    <TableCell>{t("prefs_users_table_base_url_header")}</TableCell>
                    <TableCell/>
                </TableRow>
            </TableHead>
            <TableBody>
                {props.users?.map(user => (
                    <TableRow
                        key={user.baseUrl}
                        sx={{'&:last-child td, &:last-child th': {border: 0}}}
                    >
                        <TableCell component="th" scope="row" sx={{paddingLeft: 0}}
                                   aria-label={t("prefs_users_table_user_header")}>{user.username}</TableCell>
                        <TableCell aria-label={t("prefs_users_table_base_url_header")}>{user.baseUrl}</TableCell>
                        <TableCell align="right">
                            {(!session.exists() || user.baseUrl !== config.base_url) &&
                                <>
                                    <IconButton onClick={() => handleEditClick(user)} aria-label={t("prefs_users_edit_button")}>
                                        <EditIcon/>
                                    </IconButton>
                                    <IconButton onClick={() => handleDeleteClick(user)} aria-label={t("prefs_users_delete_button")}>
                                        <CloseIcon/>
                                    </IconButton>
                                </>
                            }
                            {session.exists() && user.baseUrl === config.base_url &&
                                <Tooltip title={t("prefs_users_table_cannot_delete_or_edit")}>
                                    <span>
                                        <IconButton disabled><EditIcon/></IconButton>
                                        <IconButton disabled><CloseIcon/></IconButton>
                                    </span>
                                </Tooltip>
                            }
                        </TableCell>
                    </TableRow>
                ))}
            </TableBody>
            <UserDialog
                key={`userEditDialog${dialogKey}`}
                open={dialogOpen}
                user={dialogUser}
                users={props.users}
                onCancel={handleDialogCancel}
                onSubmit={handleDialogSubmit}
            />
        </Table>
    );
};

const UserDialog = (props) => {
    const { t } = useTranslation();
    const [baseUrl, setBaseUrl] = useState("");
    const [username, setUsername] = useState("");
    const [password, setPassword] = useState("");
    const fullScreen = useMediaQuery(theme.breakpoints.down('sm'));
    const editMode = props.user !== null;
    const addButtonEnabled = (() => {
        if (editMode) {
            return username.length > 0 && password.length > 0;
        }
        const baseUrlValid = validUrl(baseUrl);
        const baseUrlExists = props.users?.map(user => user.baseUrl).includes(baseUrl);
        return baseUrlValid
            && !baseUrlExists
            && username.length > 0
            && password.length > 0;
    })();
    const handleSubmit = async () => {
        props.onSubmit({
            baseUrl: baseUrl,
            username: username,
            password: password
        })
    };
    useEffect(() => {
        if (editMode) {
            setBaseUrl(props.user.baseUrl);
            setUsername(props.user.username);
            setPassword(props.user.password);
        }
    }, [editMode, props.user]);
    return (
        <Dialog open={props.open} onClose={props.onCancel} fullScreen={fullScreen}>
            <DialogTitle>{editMode ? t("prefs_users_dialog_title_edit") : t("prefs_users_dialog_title_add")}</DialogTitle>
            <DialogContent>
                {!editMode && <TextField
                    autoFocus
                    margin="dense"
                    id="baseUrl"
                    label={t("prefs_users_dialog_base_url_label")}
                    aria-label={t("prefs_users_dialog_base_url_label")}
                    value={baseUrl}
                    onChange={ev => setBaseUrl(ev.target.value)}
                    type="url"
                    fullWidth
                    variant="standard"
                />}
                <TextField
                    autoFocus={editMode}
                    margin="dense"
                    id="username"
                    label={t("prefs_users_dialog_username_label")}
                    aria-label={t("prefs_users_dialog_username_label")}
                    value={username}
                    onChange={ev => setUsername(ev.target.value)}
                    type="text"
                    fullWidth
                    variant="standard"
                />
                <TextField
                    margin="dense"
                    id="password"
                    label={t("prefs_users_dialog_password_label")}
                    aria-label={t("prefs_users_dialog_password_label")}
                    type="password"
                    value={password}
                    onChange={ev => setPassword(ev.target.value)}
                    fullWidth
                    variant="standard"
                />
            </DialogContent>
            <DialogActions>
                <Button onClick={props.onCancel}>{t("prefs_users_dialog_button_cancel")}</Button>
                <Button onClick={handleSubmit} disabled={!addButtonEnabled}>{editMode ? t("prefs_users_dialog_button_save") : t("prefs_users_dialog_button_add")}</Button>
            </DialogActions>
        </Dialog>
    );
};

const Appearance = () => {
    const { t } = useTranslation();
    return (
        <Card sx={{p: 3}} aria-label={t("prefs_appearance_title")}>
            <Typography variant="h5" sx={{marginBottom: 2}}>
                {t("prefs_appearance_title")}
            </Typography>
            <PrefGroup>
                <Language/>
            </PrefGroup>
        </Card>
    );
};

const Language = () => {
    const { t, i18n } = useTranslation();
    const labelId = "prefLanguage";
    const randomFlags = shuffle(["🇬🇧", "🇺🇸", "🇪🇸", "🇫🇷", "🇧🇬", "🇨🇿", "🇩🇪", "🇵🇱", "🇺🇦", "🇨🇳", "🇮🇹", "🇭🇺", "🇧🇷", "🇳🇱", "🇮🇩", "🇯🇵", "🇷🇺", "🇹🇷"]).slice(0, 3);
    const title = t("prefs_appearance_language_title") + " " + randomFlags.join(" ");
    const lang = i18n.language ?? "en";

    const handleChange = async (ev) => {
        await i18n.changeLanguage(ev.target.value);
        await maybeUpdateAccountSettings({
            language: ev.target.value
        });
    };

    // Remember: Flags are not languages. Don't put flags next to the language in the list.
    // Languages names from: https://www.omniglot.com/language/names.htm
    // Better: Sidebar in Wikipedia: https://en.wikipedia.org/wiki/Bokm%C3%A5l

    return (
        <Pref labelId={labelId} title={title}>
            <FormControl fullWidth variant="standard" sx={{ m: 1 }}>
                <Select value={lang} onChange={handleChange} aria-labelledby={labelId}>
                    <MenuItem value="en">English</MenuItem>
                    <MenuItem value="id">Bahasa Indonesia</MenuItem>
                    <MenuItem value="bg">Български</MenuItem>
                    <MenuItem value="cs">Čeština</MenuItem>
                    <MenuItem value="zh_Hans">中文</MenuItem>
                    <MenuItem value="de">Deutsch</MenuItem>
                    <MenuItem value="es">Español</MenuItem>
                    <MenuItem value="fr">Français</MenuItem>
                    <MenuItem value="it">Italiano</MenuItem>
                    <MenuItem value="hu">Magyar</MenuItem>
                    <MenuItem value="ko">한국어</MenuItem>
                    <MenuItem value="ja">日本語</MenuItem>
                    <MenuItem value="nl">Nederlands</MenuItem>
                    <MenuItem value="nb_NO">Norsk bokmål</MenuItem>
                    <MenuItem value="uk">Українська</MenuItem>
                    <MenuItem value="pt">Português</MenuItem>
                    <MenuItem value="pt_BR">Português (Brasil)</MenuItem>
                    <MenuItem value="pl">Polski</MenuItem>
                    <MenuItem value="ru">Русский</MenuItem>
                    <MenuItem value="tr">Türkçe</MenuItem>
                </Select>
            </FormControl>
        </Pref>
    )
};

const Reservations = () => {
    const { t } = useTranslation();
    const { account } = useContext(AccountContext);
    const [dialogKey, setDialogKey] = useState(0);
    const [dialogOpen, setDialogOpen] = useState(false);

    if (!config.enable_reservations || !session.exists() || !account || account.role === "admin") {
        return <></>;
    }
    const reservations = account.reservations || [];
    const limitReached = account.role === "user" && account.stats.reservations_remaining === 0;

    const handleAddClick = () => {
        setDialogKey(prev => prev+1);
        setDialogOpen(true);
    };

    const handleDialogCancel = () => {
        setDialogOpen(false);
    };

    const handleDialogSubmit = async (reservation) => {
        setDialogOpen(false);
        try {
            await accountApi.upsertReservation(reservation.topic, reservation.everyone);
            await accountApi.sync();
            console.debug(`[Preferences] Added topic reservation`, reservation);
        } catch (e) {
            console.log(`[Preferences] Error topic reservation.`, e);
        }
        // FIXME handle 401/403/409
    };

    return (
        <Card sx={{ padding: 1 }} aria-label={t("prefs_reservations_title")}>
            <CardContent sx={{ paddingBottom: 1 }}>
                <Typography variant="h5" sx={{marginBottom: 2}}>
                    {t("prefs_reservations_title")}
                </Typography>
                <Paragraph>
                    {t("prefs_reservations_description")}
                </Paragraph>
                {reservations.length > 0 && <ReservationsTable reservations={reservations}/>}
                {limitReached && <Alert severity="info">{t("prefs_reservations_limit_reached")}</Alert>}
            </CardContent>
            <CardActions>
                <Button onClick={handleAddClick} disabled={limitReached}>{t("prefs_reservations_add_button")}</Button>

                <ReservationsDialog
                    key={`reservationAddDialog${dialogKey}`}
                    open={dialogOpen}
                    reservation={null}
                    reservations={reservations}
                    onCancel={handleDialogCancel}
                    onSubmit={handleDialogSubmit}
                />
            </CardActions>
        </Card>
    );
};

const ReservationsTable = (props) => {
    const { t } = useTranslation();
    const [dialogKey, setDialogKey] = useState(0);
    const [dialogOpen, setDialogOpen] = useState(false);
    const [dialogReservation, setDialogReservation] = useState(null);
    const { subscriptions } = useOutletContext();
    const localSubscriptions = (subscriptions?.length > 0)
        ? Object.assign(...subscriptions.filter(s => s.baseUrl === config.base_url).map(s => ({[s.topic]: s})))
        : [];

    const handleEditClick = (reservation) => {
        setDialogKey(prev => prev+1);
        setDialogReservation(reservation);
        setDialogOpen(true);
    };

    const handleDialogCancel = () => {
        setDialogOpen(false);
    };

    const handleDialogSubmit = async (reservation) => {
        setDialogOpen(false);
        try {
            await accountApi.upsertReservation(reservation.topic, reservation.everyone);
            await accountApi.sync();
            console.debug(`[Preferences] Added topic reservation`, reservation);
        } catch (e) {
            console.log(`[Preferences] Error topic reservation.`, e);
        }
        // FIXME handle 401/403/409
    };

    const handleDeleteClick = async (reservation) => {
        try {
            await accountApi.deleteReservation(reservation.topic);
            await accountApi.sync();
            console.debug(`[Preferences] Deleted topic reservation`, reservation);
        } catch (e) {
            console.log(`[Preferences] Error topic reservation.`, e);
        }
        // FIXME handle 401/403
    };

    return (
        <Table size="small" aria-label={t("prefs_reservations_table")}>
            <TableHead>
                <TableRow>
                    <TableCell sx={{paddingLeft: 0}}>{t("prefs_reservations_table_topic_header")}</TableCell>
                    <TableCell>{t("prefs_reservations_table_access_header")}</TableCell>
                    <TableCell/>
                </TableRow>
            </TableHead>
            <TableBody>
                {props.reservations.map(reservation => (
                    <TableRow
                        key={reservation.topic}
                        sx={{'&:last-child td, &:last-child th': {border: 0}}}
                    >
                        <TableCell component="th" scope="row" sx={{paddingLeft: 0}} aria-label={t("prefs_reservations_table_topic_header")}>
                            {reservation.topic}
                        </TableCell>
                        <TableCell aria-label={t("prefs_reservations_table_access_header")}>
                            {reservation.everyone === "read-write" &&
                                <>
                                    <Public fontSize="small" sx={{color: "grey", verticalAlign: "bottom", mr: 0.5}}/>
                                    {t("prefs_reservations_table_everyone_read_write")}
                                </>
                            }
                            {reservation.everyone === "read-only" &&
                                <>
                                    <PublicOff fontSize="small" sx={{color: "grey", verticalAlign: "bottom", mr: 0.5}}/>
                                    {t("prefs_reservations_table_everyone_read_only")}
                                </>
                            }
                            {reservation.everyone === "write-only" &&
                                <>
                                    <PublicOff fontSize="small" sx={{color: "grey", verticalAlign: "bottom", mr: 0.5}}/>
                                    {t("prefs_reservations_table_everyone_write_only")}
                                </>
                            }
                            {reservation.everyone === "deny-all" &&
                                <>
                                    <LockIcon fontSize="small" sx={{color: "grey", verticalAlign: "bottom", mr: 0.5}}/>
                                    {t("prefs_reservations_table_everyone_deny_all")}
                                </>
                            }
                        </TableCell>
                        <TableCell align="right">
                            {!localSubscriptions[reservation.topic] &&
                                <Chip icon={<Info/>} label="Not subscribed" color="primary" variant="outlined"/>
                            }
                            <IconButton onClick={() => handleEditClick(reservation)} aria-label={t("prefs_reservations_edit_button")}>
                                <EditIcon/>
                            </IconButton>
                            <IconButton onClick={() => handleDeleteClick(reservation)} aria-label={t("prefs_reservations_delete_button")}>
                                <CloseIcon/>
                            </IconButton>
                        </TableCell>
                    </TableRow>
                ))}
            </TableBody>
            <ReservationsDialog
                key={`reservationEditDialog${dialogKey}`}
                open={dialogOpen}
                reservation={dialogReservation}
                reservations={props.reservations}
                onCancel={handleDialogCancel}
                onSubmit={handleDialogSubmit}
            />
        </Table>
    );
};

const ReservationsDialog = (props) => {
    const { t } = useTranslation();
    const [topic, setTopic] = useState("");
    const [everyone, setEveryone] = useState("deny-all");
    const fullScreen = useMediaQuery(theme.breakpoints.down('sm'));
    const editMode = props.reservation !== null;
    const addButtonEnabled = (() => {
        if (editMode) {
            return true;
        } else if (!validTopic(topic)) {
            return false;
        }
        return props.reservations
            .filter(r => r.topic === topic)
            .length === 0;
    })();
    const handleSubmit = async () => {
        props.onSubmit({
            topic: (editMode) ? props.reservation.topic : topic,
            everyone: everyone
        })
    };
    useEffect(() => {
        if (editMode) {
            setTopic(props.reservation.topic);
            setEveryone(props.reservation.everyone);
        }
    }, [editMode, props.reservation]);
    return (
        <Dialog open={props.open} onClose={props.onCancel} maxWidth="sm" fullWidth fullScreen={fullScreen}>
            <DialogTitle>{editMode ? t("prefs_reservations_dialog_title_edit") : t("prefs_reservations_dialog_title_add")}</DialogTitle>
            <DialogContent>
                <DialogContentText>
                    {t("prefs_reservations_dialog_description")}
                </DialogContentText>
                {!editMode && <TextField
                    autoFocus
                    margin="dense"
                    id="topic"
                    label={t("prefs_reservations_dialog_topic_label")}
                    aria-label={t("prefs_reservations_dialog_topic_label")}
                    value={topic}
                    onChange={ev => setTopic(ev.target.value)}
                    type="url"
                    fullWidth
                    variant="standard"
                />}
                <ReserveTopicSelect
                    value={everyone}
                    onChange={setEveryone}
                    sx={{mt: 1}}
                />
            </DialogContent>
            <DialogActions>
                <Button onClick={props.onCancel}>{t("prefs_users_dialog_button_cancel")}</Button>
                <Button onClick={handleSubmit} disabled={!addButtonEnabled}>{editMode ? t("prefs_users_dialog_button_save") : t("prefs_users_dialog_button_add")}</Button>
            </DialogActions>
        </Dialog>
    );
};

const maybeUpdateAccountSettings = async (payload) => {
    if (!session.exists()) {
        return;
    }
    try {
        await accountApi.updateSettings(payload);
    } catch (e) {
        console.log(`[Preferences] Error updating account settings`, e);
        if ((e instanceof UnauthorizedError)) {
            session.resetAndRedirect(routes.login);
        }
    }
};

export default Preferences;