import PageForm from "./Form";
import Pages from "./List";
import Prompt from "./Prompt";
import * as React from 'react';
import {Alert, AlertTitle, Button, Divider} from "@mui/material";
import {EncryptStorage} from "storage-encryption";
import {
    Switch,
    Route,
    Link,
    Redirect,
    withRouter,
    useHistory
} from "react-router-dom";
import {IList} from "../../interfaces/IList";
import {isAllLoadedLocally} from "../../utils";
import CalendarHeatmap from "../calendar/CalendarHeatmap";
import {CalendarHeatmapValuesProp} from "../calendar/CalendarHeatmapValuesProp";

const app = document.getElementById('app');
const word = "shikiryu"; // FIXME should be in db and ≠ between users

const sessionPassphrase = sessionStorage.getItem("key") as string;
let pages: IList[] = [];
let getPageContentUrl,
    postUrl,
    removeUrl,
    checkword,
    startDate,
    csrf = "";

if (app) {
    getPageContentUrl   = "" + app.getAttribute('data-url');
    pages               = JSON.parse("" + app.getAttribute('data-list')) as IList[];
    postUrl             = "" + app.getAttribute('data-post');
    startDate             = "" + app.getAttribute('data-start');
    removeUrl           = "" + app.getAttribute('data-remove');
    csrf                = "" + app.getAttribute('data-csrf');
    checkword           = "" + app.getAttribute('data-checkword');
}

function App() {
    const [listPages, setListPages]     = React.useState<IList[]>(pages);
    const [passphrase, setPassphrase]   = React.useState<string>(sessionPassphrase);
    const history = useHistory();
    const [user, setUser] = React.useState(checkPassphrase());
    const [error, isError] = React.useState(!checkPassphrase());
    const [allLoaded, setAllLoaded] = React.useState<boolean>(isAllLoadedLocally(pages));

    const loadPages = React.useRef(() => {return ;});

    const signin = cb => {
        const isAuthenticated = checkPassphrase();
        setUser(isAuthenticated);
        if (isAuthenticated) {
            isError(false);
            cb();
        } else {
            isError(true);
        }
    };

    const signout = cb => {
        sessionStorage.removeItem("key");
        setUser(false);
        cb();
    };

    function checkPassphrase() {
        if (checkword === "" || checkword === null || checkword === "null") {
            console.error("checkword is empty !");
            return false;
        }
        localStorage.setItem("checkword", checkword);

        const key = ""+sessionStorage.getItem("key");
        if (key === "" || key === null || key === "null") {
            console.error("key is empty 🤔 !");
            return false;
        }
        const encryptStorage = new EncryptStorage(key);
        const decrypted_word = encryptStorage.decrypt("checkword");

        return decrypted_word === word;
    }

    const Error = function() {
        if (error) {
            return (
                <Alert severity="error">
                    <AlertTitle>Erreur</AlertTitle>
                    La phrase de passe ne correspond pas.
                </Alert>
            );
        }
        return (<div></div>);
    }

    const LoadButton = function() {
        return allLoaded ? (<></>) : (
            <Button variant="outlined" size="small" sx={{align: "right"}} onClick={() => loadPages.current()}>
                Charger les pages localement
            </Button>
        );
    }

    const AuthButton = function() {
        const history = useHistory();

        return user ? (
            <p>
                Bienvenue !{" "}
                <Button variant="outlined" size="small" sx={{align: "right"}} onClick={() => {
                    signout(() => history.push("/diary/public"));
                }}>
                    Fermer mon carnet à clef
                </Button>
            </p>
        ) : (
            <p>
                Votre carnet est fermé.{" "}
                <Link to="/diary/public/pages">Voir vos pages</Link>
            </p>
        );
    }

    function updatePassphrase(newPassphrase) {
        setPassphrase(newPassphrase);
        if (checkPassphrase()) {
            isError(false);
            setUser(true);
            signin(() => {
                history.push({ pathname: "/diary/public/pages" });
            })
        } else {
            isError(true);
        }
    }

    function PrivateRoute({ children, ...rest }) {
        return (
            <Route
                {...rest}
                render={({ location }) =>
                    user ? (
                        children
                    ) : (
                        <Redirect
                            to={{
                                pathname: "/diary/public/pass",
                                state: { from: location }
                            }}
                        />
                    )
                }
            />
        );
    }

    function PromptPage() {
        return (<Prompt open={true} setOpen={updatePassphrase}/>);
    }

    function getCalendarValuesFromPagesList(pages: IList[]): CalendarHeatmapValuesProp[] {
        return pages.map(page => {
            const [date, ] = page.date.split(" ");
            const splittedDate = date.split("/").map(part => { return parseInt(part, 10);});
            return {
                id: page.id,
                date: new Date(splittedDate[2] as number, splittedDate[1] - 1, splittedDate[0] as number),
                event: page.id
            };
        });
    }

    function ListPage() {
        return (
            <div className="col-md-12">
                <CalendarHeatmap
                    values={getCalendarValuesFromPagesList(listPages)}
                    startDate={startDate}
                    endDate={new Date()}
                    showMonthLabels={true}
                    showWeekdayLabels={true}
                    showOutOfRangeDays={true}
                    horizontal={true}
                    gutterSize={4}
                    onClick={(value) => alert(value)}
                    tooltipDataAttrs={{}}
                />
                <Pages
                    pages={listPages}
                    url={getPageContentUrl}
                    passphrase={passphrase}
                    csrf={csrf}
                    removeUrl={removeUrl}
                    loadPages={loadPages}
                    setAllLoaded={setAllLoaded}
                />
                <Divider/>
                <PageForm setListPages={setListPages} csrf={csrf} url={postUrl} passphrase={passphrase}/>
            </div>
        );
    }

    return (
        <div>
            <AuthButton />
            <LoadButton />
            <Error/>
            <Divider sx={{height: "20px", mb: "20px", mt:"10px"}}/>
            <Switch>
                <Route path="/diary/public/pass">
                    <PromptPage />
                </Route>
                <PrivateRoute path="/diary/public/pages">
                    <ListPage />
                </PrivateRoute>
            </Switch>
        </div>
    );
}

export default withRouter(App);
