import React from 'react';

import Button from '@mui/material/Button';
import TextField from '@mui/material/TextField';
import FormControlLabel from '@mui/material/FormControlLabel';
import Checkbox from '@mui/material/Checkbox';
import Link from '@mui/material/Link';
import Typography from '@mui/material/Typography';
import DialogTitle from '@mui/material/DialogTitle';
import Dialog from '@mui/material/Dialog';
import DialogActions from '@mui/material/DialogActions';
import DialogContent from '@mui/material/DialogContent';

import authManager from '../AuthManager'

function Copyright() {
    return (
        <Typography variant="body2" color="textSecondary" align="center">
            {'Copyright © 2016-'}{new Date().getFullYear()}{' Savoir-faire Linux Inc.'}
            <Link color="inherit" href="https://jami.net/">
                Jami.net
        </Link>{' '}
            {'.'}
        </Typography>
    );
}

class SignInPage extends React.Component {

    constructor(props) {
        console.log("SignInPage " + props.open)
        super(props)
        this.state = {
            submitted: false,
            loading: false,
        }
        this.handleSubmit = this.handleSubmit.bind(this);
        this.localLogin = this.localLogin.bind(this);
    }

    handleusername(text) {
        this.setState({ username: text.target.value })
    }

    handlePassword(text) {
        this.setState({ password: text.target.value })
    }

    localLogin() {
        this.setState({
            submitted: true,
            loading: true
        })
        authManager.authenticate('admin', 'admin')
        /*fetch('/api/localLogin?username=none&password=none', {
            header: { "Content-Type": "application/json" },
            method: "POST",
            credentials: 'same-origin'
            //body: JSON.stringify({ obj })
        })
            .then((res) => {
                if (res.status === '200') {
                    this.setState({
                        redirect: true
                    });
                } else if (res.status === '401') {
                    this.setState({
                        loading: false,
                        error: true,
                        open: true,
                        errorMessage: "Wrong credentials! Your are not allowed to connect"
                    })
                }
                //this.setState({ session: res });
            }).catch((e) => {
                this.setState({
                    loading: false,
                    error: true,
                    open: true,
                    errorMessage: e.toString()
                })
            })*/
    }

    handleSubmit(event) {
        event.preventDefault();
        let obj = {}
        obj.username = this.state.username;
        obj.password = this.state.password;

        this.setState({
            submitted: true,
            loading: true
        })

        fetch('/api/login?username=' + obj.username + '&password=' + obj.password,
            {
                header: {
                    "Content-Type": "application/json"
                },
                method: "POST",
                credentials: 'same-origin'
                //body: JSON.stringify({ obj })
            }
        ).then((res) => {
            if (res.status === '200') {
                this.setState({
                    redirect: true
                });
            } else if (res.status === '401') {
                this.setState({
                    loading: false,
                    error: true,
                    open: true,
                    errorMessage: "Wrong credentials! Your are not allowed to connect"
                })
            }
            //this.setState({ session: res });
        }).catch((e) => {
            this.setState({
                loading: false,
                error: true,
                open: true,
                errorMessage: e.toString()
            })
        })
    }

    render() {
        console.log("SignInPage render " + this.props.open)
        return (
            <Dialog open={this.props.open}>
                <DialogTitle>Se connecter</DialogTitle>
                <DialogContent>
                    <Button
                        type="submit"
                        fullWidth
                        variant="contained"
                        color="primary"
                        className=""/*{classes.submit}*/
                        onClick={() => { this.localLogin() }}
                    >
                        Compte local
                    </Button>

                    <TextField
                        variant="outlined"
                        margin="normal"
                        required
                        fullWidth
                        id="username"
                        label="LDAP Savoir-faire Linux"
                        name="username"
                        autoComplete="email"
                        autoFocus
                        onChange={(text) => { this.handleusername(text) }}
                    />
                    <TextField
                        variant="outlined"
                        margin="normal"
                        required
                        fullWidth
                        name="password"
                        label="Mot de passe"
                        type="password"
                        id="password"
                        autoComplete="current-password"
                        onChange={(text) => { this.handlePassword(text) }}
                    />
                    <FormControlLabel
                        control={<Checkbox value="remember" color="primary" />}
                        label="Se rapeller de moi"
                    />
                </DialogContent>

                <DialogActions>
                    <Button
                        type="submit"
                        size="medium"
                        onClick={this.handleSubmit}
                    >
                        Se connecter
                    </Button>
                </DialogActions>
            </Dialog>
        );
    }
}


export default SignInPage;