import React, { useState, useEffect } from 'react';
import Container from 'components/Container';
import Card from 'react-bootstrap/Card';
import Form from 'react-bootstrap/Form';
import Button from 'react-bootstrap/Button';
import constants from 'utils/strings/constants';
import styled from 'styled-components';
import { LS_KEYS, getData, setData } from 'utils/storage/localStorage';
import { useRouter } from 'next/router';
import { Formik, FormikHelpers } from 'formik';
import * as Yup from 'yup';
import {
    verifyOtt,
    getOtt,
    logoutUser,
    clearFiles,
    isTokenValid,
} from 'services/userService';
import { setIsFirstLogin } from 'utils/storage';
import SubmitButton from 'components/SubmitButton';
import { clearKeys } from 'utils/storage/sessionStorage';

const Image = styled.img`
    width: 350px;
    margin-bottom: 20px;
    max-width: 100%;
`;

interface formValues {
    ott: string;
}

export default function Verify() {
    const [email, setEmail] = useState('');
    const [loading, setLoading] = useState(false);
    const [resend, setResend] = useState(0);
    const router = useRouter();

    useEffect(() => {
        const main = async () => {
            router.prefetch('/credentials');
            router.prefetch('/generate');
            const user = getData(LS_KEYS.USER);
            if (!user?.email) {
                router.push('/');
            } else if (user.token) {
                if (await isTokenValid()) {
                    router.push('/credentials');
                } else {
                    logoutUser();
                }
            } else {
                setEmail(user.email);
            }
        };
        main();
    }, []);

    const onSubmit = async (
        { ott }: formValues,
        { setFieldError }: FormikHelpers<formValues>
    ) => {
        try {
            setLoading(true);
            const resp = await verifyOtt(email, ott);
            setData(LS_KEYS.USER, {
                ...getData(LS_KEYS.USER),
                email,
                token: resp.data.token,
                id: resp.data.id,
            });
            const { subscription, keyAttributes } = resp.data;
            keyAttributes && setData(LS_KEYS.KEY_ATTRIBUTES, keyAttributes);
            subscription && setData(LS_KEYS.SUBSCRIPTION, subscription);
            clearFiles();
            setIsFirstLogin(true);
            if (resp.data.keyAttributes?.encryptedKey) {
                clearKeys();
                router.push('/credentials');
            } else {
                router.push('/generate');
            }
        } catch (e) {
            if (e?.status === 401) {
                setFieldError('ott', constants.INVALID_CODE);
            } else {
                setFieldError('ott', `${constants.UNKNOWN_ERROR} ${e.message}`);
            }
        }
        setLoading(false);
    };

    const resendEmail = async () => {
        setResend(1);
        const resp = await getOtt(email);
        setResend(2);
        setTimeout(() => setResend(0), 3000);
    };

    if (!email) {
        return null;
    }

    return (
        <Container>
            <Card style={{ minWidth: '300px' }} className="text-center">
                <Card.Body>
                    <Card.Title
                        style={{ fontWeight: 'bold', marginBottom: '24px' }}
                    >
                        {constants.VERIFY_EMAIL}
                    </Card.Title>
                    {constants.EMAIL_SENT({ email })}
                    {constants.CHECK_INBOX}
                    <br />
                    <br />
                    <Formik<formValues>
                        initialValues={{ ott: '' }}
                        validationSchema={Yup.object().shape({
                            ott: Yup.string().required(constants.REQUIRED),
                        })}
                        validateOnChange={false}
                        validateOnBlur={false}
                        onSubmit={onSubmit}
                    >
                        {({
                            values,
                            touched,
                            errors,
                            handleChange,
                            handleSubmit,
                        }) => (
                            <Form noValidate onSubmit={handleSubmit}>
                                <Form.Group>
                                    <Form.Control
                                        className="text-center"
                                        type="text"
                                        value={values.ott}
                                        onChange={handleChange('ott')}
                                        isInvalid={Boolean(
                                            touched.ott && errors.ott
                                        )}
                                        placeholder={constants.ENTER_OTT}
                                        disabled={loading}
                                        autoFocus={true}
                                    />
                                    <Form.Control.Feedback type="invalid">
                                        {errors.ott}
                                    </Form.Control.Feedback>
                                </Form.Group>
                                <SubmitButton
                                    buttonText={constants.VERIFY}
                                    loading={loading}
                                />
                                <div style={{ marginTop: '24px' }}>
                                    {resend === 0 && (
                                        <a href="#" onClick={resendEmail}>
                                            {constants.RESEND_MAIL}
                                        </a>
                                    )}
                                    {resend === 1 && (
                                        <span>{constants.SENDING}</span>
                                    )}
                                    {resend === 2 && (
                                        <span>{constants.SENT}</span>
                                    )}
                                    <div style={{ marginTop: '8px' }}>
                                        <a href="#" onClick={logoutUser}>
                                            {constants.CHANGE_EMAIL}
                                        </a>
                                    </div>
                                </div>
                            </Form>
                        )}
                    </Formik>
                </Card.Body>
            </Card>
        </Container>
    );
}
