import * as React from "react";

import List from "@material-ui/core/List";
import ListItem from "@material-ui/core/ListItem";
import ListItemText from "@material-ui/core/ListItemText";
import Typography from "@material-ui/core/Typography";
import Paper from "@material-ui/core/Paper";
import Grid from "@material-ui/core/Grid";
import Card from "@material-ui/core/Card";
import CardContent from "@material-ui/core/CardContent";
import CircularProgress from "@material-ui/core/CircularProgress";

import { withRouter } from "react-router-dom";

import { IVocab } from "../models/vocab";

interface IProps {
    id: string;
    levelVocab: (id: string) => Promise<IVocab[]>;
    updateDoneLevels: (id: string) => void;

    history: any;

    loading: boolean;
    setLoading: (state: boolean) => void;
    vocab: IVocab[];
    setVocab: (vocab: IVocab[]) => void;
    setLookedAt: (ids: number[]) => void;
    setCurrentVocab: (vocab: IVocab) => void;
    drawerButtonState: (state: boolean) => void;
    currentVocab: IVocab;
    lookedAt: number[];
};

const LevelPageWithRouter = withRouter(
    class LevelPage extends React.Component<IProps> {
        private uid = 0;
        // To prevent React from redrawing the vocabulary list and prematurely
        // cancelling the animation
        private uids: { [key: string]: string } = {};

        componentDidMount() {
            // Hide the drawer
            this.props.drawerButtonState(false);

            // Fetch the vocabulary
            this.props.setLoading(true);

            // TODO: Error handling
            this.props.levelVocab(this.props.id).then(vocab => {
                this.props.setVocab(vocab);
                this.props.setCurrentVocab(vocab[0]);
                this.props.setLookedAt([vocab[0].id]);
                this.props.setLoading(false);
            });


        }

        genUID = (vocab: IVocab): string => {
            const { grundform } = vocab.latin;
            if (grundform in this.uids) {
                return this.uids[grundform];
            } else {
                this.uids[grundform] = "LEVELPAGE" + this.uid++;
                return this.uids[grundform];
            }
        }

        renderVocabListItem = (vocab: IVocab): any => {
            // Check if the vocab was already looked at
            const lookedAt = this.props.lookedAt.find((el) => el === vocab.id);

            return <ListItem button key={this.genUID(vocab)} onClick={() => {
                // Prevent the user from using too much memory by always clicking on the elements
                // Show the clicked at vocab word

                this.props.setCurrentVocab(vocab);
                this.props.setLookedAt(lookedAt ? (
                    this.props.lookedAt
                ) : this.props.lookedAt.concat(vocab.id));
            }}>
                <ListItemText>
                    {`${vocab.latin.grundform} ${lookedAt ? "✔" : ""}`}
                </ListItemText>
            </ListItem>;
        }

        toReview = () => {
            const { vocab, lookedAt, id } = this.props;

            // Only go to the review if all vocabulary item have been looked at
            if (vocab.length === lookedAt.length) {
                this.props.updateDoneLevels(id);
                this.props.setLoading(true);
                this.props.history.push(`/review/level/${id}`);
            }
        }

        render() {
            if (this.props.loading) {
                return <div>
                    <Grid
                        container
                        spacing={0}
                        direction="column"
                        alignItems="center"
                        justify="center"
                        style={{ minHeight: '100vh' }}>
                        <Grid item xs={12}>
                            <Paper className="paper">
                                <Grid container direction="column" spacing={8}>
                                    <CircularProgress />
                                </Grid>
                            </Paper>
                        </Grid>
                    </Grid>

                </div>;
            }

            const { currentVocab } = this.props;
            return <div>
                <Grid container direction="row">
                    <Grid item xs={3}>
                        <List>
                            {this.props.vocab
                                .map(this.renderVocabListItem)}
                            <ListItem button onClick={this.toReview}>
                                <ListItemText>
                                    Zur Übung
                            </ListItemText>
                            </ListItem>
                        </List>
                    </Grid>
                    <Grid item lg={7} xs={9}>
                        <Grid container direction="column">
                            <Grid item style={{ margin: 12 }}>
                                <Card>
                                    <CardContent>
                                        <Typography gutterBottom variant="headline" component="h2">
                                            {currentVocab.latin.grundform}
                                        </Typography>
                                        <Typography gutterBottom variant="headline" component="h3">
                                            {currentVocab.german.join(", ")}
                                        </Typography>
                                        {
                                            currentVocab.hint ? (
                                                <div style={{
                                                    border: "dashed",
                                                    borderColor: "red",
                                                    padding: 12,
                                                }}>
                                                    <Typography variant="subheading" component="p">
                                                        <b>Tipp:</b>
                                                    </Typography>
                                                    <Typography variant="body2">
                                                        {currentVocab.hint}
                                                    </Typography>
                                                </div>
                                            ) : undefined
                                        }
                                        {
                                            currentVocab.mnemonic ? (
                                                <div style={{
                                                    border: "dashed",
                                                    borderColor: "#f1c40f",
                                                    marginTop: 12,
                                                    padding: 12,
                                                }}>
                                                    <Typography variant="subheading" component="p">
                                                        <b>Eselsbrücke:</b>
                                                    </Typography>
                                                    <Typography variant="body2">
                                                        {currentVocab.mnemonic}
                                                    </Typography>
                                                </div>
                                            ) : undefined
                                        }
                                    </CardContent>
                                    {/*TODO: Maybe "next" and "prev" buttons?*/}
                                </Card>
                            </Grid>
                        </Grid>
                    </Grid>
                </Grid>
            </div>;
        }
    }
);
export default LevelPageWithRouter;
