import generateQueryString from '@/lib/generateQueryString';
import { gray100 } from '@/styles/colors';
import { useMutation } from '@tanstack/react-query';
import { useRouter } from 'next/router';
import { ParsedUrlQuery } from 'querystring';
import { useEffect, useState } from 'react';
import Modal, { ModalProps } from '../Modal';
import { getRecaptchaToken } from './helper';
import { AuthButton, AuthSeparatorLine, CancelButton, Header, ModalBodyParagraph, Notice } from './styles';

const SERVER_URL = process.env.NEXT_PUBLIC_SERVER_URL;

type VerifyEmailModalProps = Omit<ModalProps, 'children'> & {
  verifyEmailCode: string;
};

const resendVerification = async (email: string, query: ParsedUrlQuery) => {
  const token = await getRecaptchaToken('resend_verification_email');
  const response = await fetch(`${SERVER_URL}/auth/email/resend-verification${generateQueryString(query)}`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ email, token }),
    credentials: 'include',
  });
  if (response.status === 429) {
    throw new Error('Too many attempts. Please try again later.');
  } else if (response.status !== 200) {
    throw new Error('Something went wrong. Please try again later.');
  }
};

const verifyEmail = async (values: { email: string; code: string }, query = {}) => {
  const { email, code } = values;
  const response = await fetch(`${SERVER_URL}/auth/email/verify${generateQueryString(query)}`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ email, code }),
    credentials: 'include',
  });
  if (response.status === 200) {
    const body = await response.json();
    const { redirected, url } = body;
    if (redirected && url) {
      window.location.href = url;
    }
  } else {
    throw new Error('Something went wrong. Please try again later.');
  }
};

export const UserNotVerifiedNotice = (props: { email: string }) => {
  const router = useRouter();
  const { email } = props;

  const { mutate, isLoading, isError, isSuccess, error } = useMutation(() => resendVerification(email, router.query));

  return (
    <div style={{ display: 'flex', flexDirection: 'column' }}>
      <ModalBodyParagraph>You can't log in unless you are verified.</ModalBodyParagraph>
      <ModalBodyParagraph>Check your email for the verification link.</ModalBodyParagraph>
      <ModalBodyParagraph>Don't have the email? Check your spam folder, or send a new one.</ModalBodyParagraph>
      <AuthButton
        onClick={() => mutate()}
        disabled={isLoading || isSuccess || isError}
        style={{ marginTop: 0, marginBottom: '0.5rem' }}
      >
        {isLoading ? (
          <>Loading...</>
        ) : isSuccess ? (
          <>
            Sent Verification Email <span style={{ fontSize: '1.5rem' }}>✅</span>
          </>
        ) : (
          <>
            Resend Verification Email
            <img src="/images/icons/Email.svg" height={24} width={24} alt="Email Icon" />
          </>
        )}
      </AuthButton>
      {isSuccess && (
        <Notice className="flash">
          Check your email for the verification link
          <br />
          If you don't see it, check your spam folder.
        </Notice>
      )}
      {isError && (
        <Notice className="flash">
          {(error as Error).message ? (error as Error).message : 'Something went wrong. Please try again later.'}
        </Notice>
      )}
    </div>
  );
};

const VerifyEmailModal = (props: VerifyEmailModalProps) => {
  const [email, setEmail] = useState('');
  const [valid, setValid] = useState(false);
  const router = useRouter();

  const { verifyEmailCode, onClose } = props;

  const resendVerificationMutation = useMutation({
    mutationFn: (email: string) => resendVerification(email, router.query),
  });
  const verifyEmailMutation = useMutation({
    mutationFn: (data: { email: string; code: string }) => verifyEmail(data, router.query),
    onError: () => setValid(false),
  });

  useEffect(() => {
    if (!verifyEmailCode) return;
    // Base64 decode the verifyEmailCode
    try {
      // This would have been generated by the /auth/email/forgot endpoint
      const { c, e } = JSON.parse(atob(verifyEmailCode as string));
      if (!c || !e) throw new Error('Invalid verification link');
      setEmail(e);
      setValid(true);
      verifyEmailMutation.mutate({ email: e, code: c });
    } catch (err) {
      setValid(false);
    }
  }, [verifyEmailCode]);

  return (
    <Modal
      style={{
        borderRadius: 4,
        backgroundColor: 'white',
        color: gray100,
      }}
      hideCloseButton
      {...props}
    >
      {verifyEmailMutation.isSuccess && (
        <div style={{ display: 'flex', flexDirection: 'column' }}>
          <Header>Verified!</Header>
          <ModalBodyParagraph>Logging you in...</ModalBodyParagraph>
        </div>
      )}
      {valid && !verifyEmailMutation.isSuccess && (
        <div style={{ display: 'flex', flexDirection: 'column' }}>
          <Header>Email Verification</Header>
          <ModalBodyParagraph>Verifying: {email}</ModalBodyParagraph>
        </div>
      )}
      {!valid && (
        <div style={{ display: 'flex', flexDirection: 'column' }}>
          <Header>Email Verification</Header>
          <ModalBodyParagraph style={{ margin: '20px 0' }}>⚠️ Invalid or expired verification link</ModalBodyParagraph>
          <AuthButton
            disabled={
              resendVerificationMutation.isLoading ||
              resendVerificationMutation.isSuccess ||
              resendVerificationMutation.isError
            }
            onClick={() => {
              resendVerificationMutation.mutate(email);
            }}
          >
            {resendVerificationMutation.isLoading ? (
              <>Loading...</>
            ) : resendVerificationMutation.isSuccess ? (
              <>
                Sent Verification Email <span style={{ fontSize: '1.5rem' }}>✅</span>
              </>
            ) : (
              <>
                Resend Verification Email
                <img src="/images/icons/Email.svg" height={24} width={24} alt="Email Icon" />
              </>
            )}
          </AuthButton>

          {resendVerificationMutation.isSuccess && (
            <Notice className="flash">
              Check your email for a verification link.
              <br />
              If you don't see it, check your spam folder.
            </Notice>
          )}
          {resendVerificationMutation.isError && (
            <Notice className="flash">
              {(resendVerificationMutation.error as Error).message
                ? (resendVerificationMutation.error as Error).message
                : 'Something went wrong. Please try again later.'}
            </Notice>
          )}

          <AuthSeparatorLine />
          <div style={{ display: 'flex', flexDirection: 'row', justifyContent: 'center' }}>
            <CancelButton onClick={onClose}>Cancel</CancelButton>
          </div>
        </div>
      )}
    </Modal>
  );
};

export default VerifyEmailModal;
