import {ChangeEvent} from "react";
import {Button, FormControl, FormGroup, FormLabel, FormText, Modal} from "react-bootstrap";
import {ModalState} from "../../utils/modalState";
import {observer} from "mobx-react";
import {action, computed, makeObservable, observable, reaction} from "mobx";
import {post} from "../../utils/request";
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
import {ComponentContext} from "../../utils/ComponentContext";

interface LoginModalProps {
    modalState: ModalState;
}

@observer
export class LoginModal extends ComponentContext<LoginModalProps> {
    @observable login = '';
    @observable loginError = '';
    @observable password = '';
    @observable passwordError = '';

    constructor(props: LoginModalProps) {
        super(props);
        makeObservable(this);
        reaction(() => this.login, this.validateLogin);
        reaction(() => this.password, this.validatePassword);
    }

    @action.bound
    validateLogin() {
        if (!this.login) {
            this.loginError = 'Имя пользователя не может быть пустым';
        } else if (this.login.length < 5) {
            this.loginError = 'Имя пользователя должно быть не менее 5 символов';
        } else if (this.login.length > 50) {
            this.loginError = 'Имя пользователя должно быть не более 50 символов';
        } else if (!/^[a-zA-Z0-9_]+$/.test(this.login)) {
            this.loginError = 'Имя пользователя должно содержать только латинские буквы, цифры и знак подчеркивания';
        } else {
            this.loginError = '';
        }
    }

    @action.bound
    validatePassword() {
        if (!this.password) {
            this.passwordError = 'Пароль не может быть пустым';
        } else if (this.password.length < 5) {
            this.passwordError = 'Пароль должен быть не менее 5 символов';
        } else if (this.password.length > 32) {
            this.passwordError = 'Пароль должен быть не более 32 символов';
        } else if (!/^[a-zA-Z0-9!@#$%^&*()_+]+$/.test(this.password)) {
            this.passwordError = 'Пароль должен содержать только латинские буквы, цифры и специальные символы';
        } else {
            this.passwordError = '';
        }
    }

    @computed
    get loginButtonDisabled() {
        return !this.login || !this.password || !!this.loginError || !!this.passwordError;
    }

    @action.bound
    onLoginInput(event: ChangeEvent<HTMLInputElement>) {
        this.login = event.target.value;
    }

    @action.bound
    onPasswordInput(event: ChangeEvent<HTMLInputElement>) {
        this.password = event.target.value;
    }

    @action.bound
    tryLogin() {
        if (this.loginButtonDisabled)
            return;

        this.thinkStore.think('loginModal');
        post('user/login', {
            username: this.login,
            password: this.password
        }).then(() => {
            this.userStore.updateCurrentUser((user) => {
                if (user.authenticated) {
                    this.routerStore.goTo('profile').then();
                    this.notificationStore.success('Вы успешно вошли в систему, ' + user.fullName, 'Успешный вход');
                } else {
                    this.routerStore.goTo('root').then();
                    this.notificationStore.error('Произошла ошибка при попытке входа в систему', 'Ошибка входа');
                }
            });
        }).finally(() => {
            this.props.modalState.close();
            this.thinkStore.completeAll('loginModal');
        });
    }

    render() {
        const open = this.props.modalState.isOpen;
        const thinking = this.thinkStore.isThinking('loginModal');

        return <Modal show={open} centered>
            <Modal.Header>
                <Modal.Title>Вход</Modal.Title>
            </Modal.Header>
            {
                thinking &&
                <Modal.Body>
                    <FontAwesomeIcon icon={'gear'} spin/>
                </Modal.Body>
            }
            {
                !thinking &&
                <>
                    <Modal.Body>
                        <FormGroup className={'mb-3'}>
                            <FormLabel>Имя пользователя</FormLabel>
                            <FormControl type="text" onChange={this.onLoginInput}/>
                            {
                                this.loginError &&
                                <FormText className={'text-danger'}>{this.loginError}</FormText>
                            }
                        </FormGroup>
                        <FormGroup className={'mb-3'}>
                            <FormLabel>Пароль</FormLabel>
                            <FormControl type="password" onChange={this.onPasswordInput}/>
                            {
                                this.passwordError &&
                                <FormText className={'text-danger'}>{this.passwordError}</FormText>
                            }
                        </FormGroup>
                    </Modal.Body>
                    <Modal.Footer>
                        <Button variant={'primary'} onClick={this.tryLogin}
                                disabled={this.loginButtonDisabled}>Войти</Button>
                        <Button variant={'secondary'} onClick={this.props.modalState.close}>Закрыть</Button>
                    </Modal.Footer>
                </>
            }
        </Modal>
    }
}