import * as React from "react";

import Grid from "@material-ui/core/Grid";
import Typography from "@material-ui/core/Typography";
import Paper from "@material-ui/core/Paper";
import CircularProgress from "@material-ui/core/CircularProgress";
import Button from "@material-ui/core/Button";
import TextField from "@material-ui/core/TextField";
import Dialog from "@material-ui/core/Dialog";
import DialogTitle from "@material-ui/core/DialogTitle";
import DialogContent from "@material-ui/core/DialogContent";
import DialogActions from "@material-ui/core/DialogActions";

import SearchIcon from "@material-ui/icons/Search";

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

import VocabularyData from "../components/VocabularyData";

interface IProps {
    getVocab: () => Promise<IVocab[]>;

    searchOpen: boolean;
    searchTerm: string;
    loading: boolean;
    vocab: IVocab[];

    setLoading: (state: boolean) => void;
    setVocab: (vocab: IVocab[]) => void;
    setSearchOpen: (state: boolean) => void;
    setSearchTerm: (term: string) => void;
}

export default class VocabPage extends React.Component<IProps> {
    // Internal counter for dynmic children
    private uid = 0;
    // Mapping Vocab ID -> React Key
    private uids: { [id: number]: string } = {};

    // @vid: The vocabulary ID of the child
    genUID = (vid: number) => {
        if (!(vid in this.uids)) {
            this.uids[vid] = `VOCABPAGE-${this.uid++}`;
        }

        return this.uids[vid];
    }

    componentDidMount() {
        this.props.setLoading(true);
        // TODO: Errorhandling
        this.props.getVocab().then(vocab => {
            this.props.setVocab(vocab);
            this.props.setLoading(false);
        });
    }

    componentWillUnmount() {
        // Reset the search term
        this.props.setSearchTerm("");
    }

    openSearch = () => {
        this.props.setSearchOpen(true);
    }
    closeSearch = () => {
        this.props.setSearchOpen(false);
    }

    vocabToCard = (voc: IVocab) => {
        // Do we need to apply a search filter?
        const { searchTerm } = this.props;
        if (searchTerm !== "") {
            // Just ignore the vocabulary item if it does
            // not match the "query"
            const lower = voc.latin.grundform.toLowerCase();
            if (!lower.startsWith(searchTerm.toLowerCase())) {
                return;
            }
        }

        const vocabTypeToStr = {
            [VocabType.NOMEN]: "Nomen",
            [VocabType.VERB]: "Verb",
            [VocabType.ADJEKTIV]: "Adjektiv",
            [VocabType.ADVERB]: "Adverb",
        };

        return <Paper key={this.genUID(voc.id)} style={{ marginBottom: 12, padding: 12 }}>
            <Typography gutterBottom variant="headline" component="h2">
                {`${voc.latin.grundform} (${vocabTypeToStr[voc.type]})`}
            </Typography>
            <VocabularyData vocab={voc} />
        </Paper>;
    }

    applySearchFilter = (e: any) => {
        // Not sure how much this does
        e.preventDefault();
        this.closeSearch();
    }

    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>;
        }

        // Trigger a search when the user presses the return key
        const onEnter = (event: any) => {
            if (event.key === "Enter") {
                this.applySearchFilter(event);
            }
        };

        const { vocab } = this.props;
        return <div className="content">
            {vocab.map(this.vocabToCard)}
            <div className="vocab-bottom-spacer" />

            <Dialog
                open={this.props.searchOpen}
                onClose={this.closeSearch}>
                <DialogTitle>
                    Suche
                </DialogTitle>
                <DialogContent>
                    <TextField
                        helperText="Suche nach Vokabeln"
                        onKeyPress={onEnter}
                        value={this.props.searchTerm}
                        onChange={(event) => this.props.setSearchTerm(event.target.value)}
                        inputProps={{
                            autoFocus: "autofocus",
                        }} />
                </DialogContent>
                <DialogActions>
                    <Button onClick={this.applySearchFilter} color="primary">
                        Suchen
                    </Button>
                </DialogActions>
            </Dialog>

            <Button
                className="vocab-search-fab"
                variant="fab"
                color="primary"
                onClick={this.openSearch}>
                <SearchIcon />
            </Button>
        </div>;
    }
};
