// Dependencies
import { validateEmail, validateTld, getSearchParam } from '@freesewing/utils'

// Hooks
import React, { useState, useContext, useEffect } from 'react'
import { useAccount } from '@freesewing/react/hooks/useAccount'
import { useBackend } from '@freesewing/react/hooks/useBackend'

// Context
import { LoadingStatusContext } from '@freesewing/react/context/LoadingStatus'
import { ModalContext } from '@freesewing/react/context/Modal'

// Components
import { Link } from '@freesewing/react/components/Link'
import {
  LeftIcon,
  RightIcon,
  HelpIcon,
  GoogleIcon,
  GitHubIcon,
  KeyIcon,
  EmailIcon,
  DownIcon,
} from '@freesewing/react/components/Icon'
import { ModalWrapper } from '@freesewing/react/components/Modal'
import { EmailInput } from '@freesewing/react/components/Input'
import { IconButton } from '@freesewing/react/components/Button'
import { Spinner } from '@freesewing/react/components/Spinner'
import { Consent } from '@freesewing/react/components/Account'

export const SignUp = ({ embed = false }) => {
  // State
  const [email, setEmail] = useState('')
  const [emailValid, setEmailValid] = useState(false)
  const [result, setResult] = useState(false)
  const [showAll, setShowAll] = useState(false)

  // Hooks
  const backend = useBackend()

  // Context
  const { setModal } = useContext(ModalContext)
  const { setLoadingStatus } = useContext(LoadingStatusContext)

  const updateEmail = (value) => {
    setEmail(value)
    const valid = (validateEmail(value) && validateTld(value)) || false
    setEmailValid(valid === true ? true : false)
  }

  const signupHandler = async (evt) => {
    evt.preventDefault()
    if (!emailValid) {
      setLoadingStatus([true, 'Please provide a valid email address', true, false])
      return
    }
    const [status, body] = await backend.signUp({ email })
    if (status === 201 && body.result === 'created') setResult('success')
    else {
      setModal(
        <ModalWrapper bg="tw:base-100 tw:lg:bg-base-300">
          <div className="tw:bg-base-100 tw:rounded-lg tw:p-4 tw:lg:px-8 tw:max-w-xl tw:lg:shadow-lg">
            <h3>An error occured while trying to process your request</h3>
            <p className="tw:text-lg">
              Unfortunately, we cannot recover from this error, we need a human being to look into
              this.
            </p>
            <p className="tw:text-lg">
              Feel free to try again, or reach out to support so we can assist you.
            </p>
            <div className="tw:flex tw:flex-row tw:gap-4 tw:items-center tw:justify-center tw:p-8 tw:flex-wrap">
              <IconButton onClick={() => setResult(false)}>
                <LeftIcon />
                Back
              </IconButton>
              <IconButton href="/support" className="tw:daisy-btn-outline">
                <HelpIcon />
                Contact support
              </IconButton>
            </div>
          </div>
        </ModalWrapper>
      )
    }
  }

  const initOauth = async (provider) => {
    setLoadingStatus([true, 'Contacting the backend'])
    const [status, body] = await backend.oauthInit(provider.toLowerCase())
    if (status === 200 && body.result === 'success') {
      setLoadingStatus([true, `Contacting ${provider}`])
      window.location.href = body.authUrl
    }
  }
  const Heading = embed
    ? ({ children }) => <h2 className="tw:text-inherit">{children}</h2>
    : ({ children }) => <h1 className="tw:text-inherit">{children}</h1>

  return (
    <div className="tw:w-full">
      <Heading className="tw:text-inherit">
        {result ? (
          result === 'success' ? (
            <span>Now check your inbox</span>
          ) : (
            <span>An error occured while trying to process your request</span>
          )
        ) : (
          <span>Create a FreeSewing account</span>
        )}
      </Heading>

      {result ? (
        result === 'success' ? (
          <>
            <p className="tw:text-inherit tw:text-lg">
              Go check your inbox for an email from <b>FreeSewing.org</b>
            </p>
            <p className="tw:text-inherit tw:text-lg">
              Click your personal signup link in that email to create your FreeSewing account.
            </p>
            <div className="tw:grid tw:grid-cols-1 tw:md:grid-cols-2 tw:gap-2">
              <IconButton onClick={() => setResult(false)}>
                <LeftIcon />
                Back
              </IconButton>
              <IconButton href="/support" className="tw:daisy-btn-outline">
                <HelpIcon />
                Contact support
              </IconButton>
            </div>
          </>
        ) : (
          <>
            robot here
            <p className="tw:text-inherit tw:text-lg">
              Unfortunately, we cannot recover from this error, we need a human being to look into
              this.
            </p>
            <p className="tw:text-inherit tw:text-lg">
              Feel free to try again, or reach out to support so we can assist you.
            </p>
            <div className="tw:flex tw:flex-row tw:gap-4 tw:items-center tw:justify-center tw:p-8">
              <button className="tw:daisy-btn tw:daisy-btn-ghost" onClick={() => setResult(false)}>
                Back
              </button>
              <Link href="/support" className="tw:daisy-btn tw:daisy-btn-ghost">
                Contact support
              </Link>
            </div>
          </>
        )
      ) : (
        <>
          <p className="tw:text-inherit">To receive a sign-up link, enter your email address</p>
          <form onSubmit={signupHandler}>
            <EmailInput
              id="signup-email"
              label="Email address"
              current={email}
              original={''}
              valid={() => emailValid}
              placeholder="Email address"
              update={updateEmail}
            />
            <IconButton
              onClick={signupHandler}
              btnProps={{ type: 'submit' }}
              className="tw:lg:w-full tw:grow tw:mt-2"
            >
              <EmailIcon />
              Email me a sign-up link
            </IconButton>
          </form>
          {showAll ? (
            <>
              <div className="tw:grid tw:grid-cols-1 tw:md:grid-cols-2 tw:gap-1 tw:items-center tw:mt-1">
                {['Google', 'GitHub'].map((provider) => (
                  <IconButton
                    key={provider}
                    id={provider}
                    color="secondary"
                    onClick={() => initOauth(provider)}
                  >
                    {provider === 'Google' ? <GoogleIcon stroke={0} /> : <GitHubIcon />}
                    <span>Sign up with {provider}</span>
                  </IconButton>
                ))}
              </div>
              <IconButton color="neutral" href="/signin" className="tw:daisy-btn-lg tw:mt-1">
                <span className="tw:hidden tw:md:block">
                  <KeyIcon className="tw:h-10 tw:w-10" />
                </span>
                Sign in here
              </IconButton>
              <div className="tw:flex tw:flex-row tw:justify-center tw:mt-2">
                <IconButton color="ghost" onClick={() => setShowAll(false)}>
                  <DownIcon className="tw:w-6 tw:h-6 tw:rotate-180" />
                  Fewer options
                  <DownIcon className="tw:w-6 tw:h-6 tw:rotate-180" />
                </IconButton>
              </div>
            </>
          ) : (
            <div className="tw:flex tw:flex-row tw:justify-center tw:mt-2">
              <IconButton color="ghost" onClick={() => setShowAll(true)}>
                <DownIcon />
                More options
                <DownIcon />
              </IconButton>
            </div>
          )}
        </>
      )}
    </div>
  )
}

export const SignUpConfirmation = ({ onSuccess = false }) => {
  // State
  const [id, setId] = useState()
  const [check, setCheck] = useState()

  // Effects
  useEffect(() => {
    const newId = getSearchParam('id')
    const newCheck = getSearchParam('check')
    if (newId !== id) setId(newId)
    if (newCheck !== check) setCheck(newCheck)
  }, [id, check])

  // If we do not (yet) have the data, show a loader
  if (!id || !check)
    return (
      <>
        <h1>One moment pleae</h1>
        <Spinner className="tw:w-8 tw:h-8 tw:m-auto tw:animate-spin" />
      </>
    )

  return (
    <>
      <h1>One more thing</h1>
      <Consent signUp={id} />
    </>
  )
}