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;