import { useEffect, useState } from 'react';
import { toast } from 'react-toastify';
import { GetServerSideProps, NextPage } from 'next';
import { useTranslation } from 'next-i18next';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
import { useRouter } from 'next/router';
import { LockOutlined } from '@ant-design/icons';
import { useMutation } from '@tanstack/react-query';
import { Button, Form, Input } from 'antd';
import PasswordHintContainer from '@/components/ui/input/password/PasswordHintContainer';
import { checkVerifyToken, verifyMember } from '@/services/auth';
import { AxiosErrorResponse, CheckVerifyTokenErrorResponse, Member, VerificationParams, VerifyTokenErrorResponse } from '@/types';
import { errorMessageFormatter } from '@/utils/errorFormatter';
import localeLinkGenerator from '@/utils/localeLinkGenerator';
import { passwordRegex } from '@/utils/regex';
import logo from '../../../../public/logo.png';
import Image from 'next/image';

interface TokenVerificationProps {
    member: Member;
    token: string;
}

const TokenVerification: NextPage<TokenVerificationProps> = ({ member, token }) => {
    const { t } = useTranslation(['auth', 'messages']);
    const [verifyForm] = Form.useForm<
        VerificationParams & {
            email: string;
        }
    >();
    const [password, setPassword] = useState<string>('');
    const router = useRouter();

    useEffect(() => {
        verifyForm.setFieldsValue({
            email: member.email,
        });
    }, []);

    // Mutations
    const verifyTokenMutation = useMutation({
        mutationFn: async (formValues: VerificationParams) => {
            const res = await verifyMember(member.id, token, formValues);
            return res.data;
        },
        onSuccess: () => {
            router.push('/dashboard');
        },
        onError: (error: VerifyTokenErrorResponse) => {
            if (error.response?.data.verificationExpired) {
                router.push(`/?unverified=true&email=${member.email}&verificationExpired=true`);
            }
        },
    });

    // Handlers
    const handlePasswordChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        setPassword(e.target.value);
    };

    const onVerifyHandler = async () => {
        verifyForm.validateFields().then((values) => {
            toast.promise(verifyTokenMutation.mutateAsync(values), {
                pending: t('messages:verifying-account'),
                success: t('messages:account-verified'),
                error: {
                    render({ data }) {
                        return t(errorMessageFormatter(data as AxiosErrorResponse));
                    },
                },
            });
        });
    };

    return (
        <div className="flex items-center justify-center h-screen">
            <div className="w-full max-w-[500px] px-5">
                <div className="relative mb-8 w-full text-center md:px-10">
                    <Image src={logo} priority={true} alt="Logo" style={{ width: '200px', height: 'auto' }}></Image>
                </div>
                <div>
                    <Form form={verifyForm} layout="vertical" size="large" name="verify_form">
                        <Form.Item name="email" label={t('email')} className="mb-5" labelCol={{ flex: '35px' }}>
                            <Input disabled />
                        </Form.Item>
                        <Form.Item
                            name="password"
                            label={t('password')}
                            rules={[
                                { required: true },
                                {
                                    pattern: passwordRegex,
                                    message: '',
                                },
                            ]}
                            className="mb-5"
                            labelCol={{ flex: '35px' }}
                        >
                            <Input.Password classNames={{ prefix: '!me-2' }} prefix={<LockOutlined />} onChange={handlePasswordChange} />
                        </Form.Item>
                        <Form.Item
                            name="confirmPassword"
                            label={t('confirm-password')}
                            dependencies={['password']}
                            rules={[
                                { required: true },
                                ({ getFieldValue }) => ({
                                    validator(_, value) {
                                        if (!value || getFieldValue('password') === value) {
                                            return Promise.resolve();
                                        }
                                        return Promise.reject(new Error(t('password-not-match')));
                                    },
                                }),
                            ]}
                            className="mb-5"
                            labelCol={{ flex: '35px' }}
                        >
                            <Input.Password classNames={{ prefix: '!me-2' }} prefix={<LockOutlined />} />
                        </Form.Item>
                        <PasswordHintContainer password={password} />
                        <Button
                            type="primary"
                            htmlType="submit"
                            block
                            className="mt-3"
                            loading={verifyTokenMutation.isLoading}
                            onClick={onVerifyHandler}
                        >
                            {t('verify-account')}
                        </Button>
                    </Form>
                </div>
            </div>
        </div>
    );
};

export default TokenVerification;

export const getServerSideProps: GetServerSideProps = async ({ params, locale }) => {
    try {
        const checkTokenResponse = await checkVerifyToken(params!.memberId as string, params!.token as string);

        return {
            props: {
                member: {
                    id: checkTokenResponse.data.id,
                    email: checkTokenResponse.data.email,
                },
                token: params!.token,
                ...(await serverSideTranslations(locale as string, ['auth', 'messages', 'api-messages'])),
            },
        };
    } catch (error: unknown) {
        const checkTokenError = error as CheckVerifyTokenErrorResponse;

        const verificationExpired = checkTokenError?.response?.data.verificationExpired;
        const email = checkTokenError?.response?.data.email;

        if (verificationExpired) {
            return {
                redirect: {
                    destination: localeLinkGenerator(locale, `/?unverified=true&email=${email}&verificationExpired=true`),
                    permanent: false,
                },
            };
        }

        return {
            redirect: {
                destination: '/404',
                permanent: false,
            },
        };
    }
};
