import React, { useState, useEffect, useCallback, FC } from 'react'
import apiFetch from '@wordpress/api-fetch'
import { Credentials, CredentialsResponse } from './model/models'
import passwordImage from '../../assets/img/illustration-password.png'
import activatedImage from '../../assets/img/happy.svg'
import almostActivatedImage from '../../assets/img/not-so-happy.svg'
import {
  Button,
  ButtonGroup,
  Notice,
  Card,
  CardBody,
} from '@wordpress/components'
import './styles.scss'
import { useI18n } from '@wordpress/react-i18n'
import { arrowRight } from '@wordpress/icons'
import FeedbackForm from './components/FeedbackForm'
import ToggleRemoteLog from './ToggleRemoteLog'
import ToggleDarkMode from './ToggleDarkMode'
// @ts-expect-error 7016
import { getAdminLink } from '@woocommerce/settings'
import { useEnableWpCompatOverlaySlot } from '@wordpress/ui'

type CredentialsState = {
  apiKey: string
  webShopId: string
}

type ErrorsState = {
  credentialsError?: string
  webShopIdError?: string
  noAccessToWebshopError?: string
}

export declare interface SettingsProps {
  onTaskComplete?: () => void
}

const Settings: FC<SettingsProps> = ({ onTaskComplete }) => {
  const [credentials, setCredentials] = useState<CredentialsState>({
    apiKey: '',
    webShopId: '',
  })
  const [isLoading, setIsLoading] = useState(false)
  const [isSaving, setIsSaving] = useState(false)
  const [formActive, setFormActive] = useState(false)
  const [errors, setErrors] = useState<ErrorsState>({})
  const [missingCredentials, setMissingCredentials] = useState(false)
  const [failedCredentials, setFailedCredentials] = useState(false)
  const [keyPresent, setKeyPresent] = useState<boolean>(false)
  const [clipboardRequested, setClipboardRequested] = useState<boolean>(false)
  const [clipboardSupported, setClipboardSupported] = useState<boolean>(false)
  useEnableWpCompatOverlaySlot()

  const { __ } = useI18n()

  // @ts-expect-error 2339
  const blockCheckoutActive = window.shopDetails?.checkoutBlockActive
  // @ts-expect-error 2339
  const shopAddressConfigured = window.shopDetails?.shopAddressConfigured

  const toggleFormActive = useCallback(() => {
    setFormActive(!formActive)
    if (!formActive) {
      setCredentials(prev => ({
        ...prev,
        apiKey: '',
      }))
      setErrors({})
    } else {
      setFailedCredentials(false)
    }
  }, [formActive])

  useEffect(() => {
    const fetchCredentials = async () => {
      setIsLoading(true)
      const response: Credentials = await apiFetch({
        path: '/posten-bring-checkout/credentials',
      })
      if (response) {
        const credentialsMissing = !(response.webshop_id && response.apikey)
        setMissingCredentials(credentialsMissing)
        setCredentials({
          apiKey: credentialsMissing ? '' : response.apikey,
          webShopId: credentialsMissing ? '' : response.webshop_id,
        })

        if (!credentialsMissing && onTaskComplete) {
          onTaskComplete()
        }
      } else {
        setMissingCredentials(true)
      }
      setIsLoading(false)
    }
    fetchCredentials()
  }, [])

  const storeCredentials = async (
    e: React.FormEvent | undefined,
    creds: CredentialsState | undefined
  ) => {
    e && e.preventDefault && e.preventDefault()
    setErrors({})
    setFailedCredentials(false)
    setIsSaving(true)

    const response: CredentialsResponse = await apiFetch({
      path: 'posten-bring-checkout/credentials',
      method: 'POST',
      data: {
        apikey: creds ? creds.apiKey : credentials.apiKey,
        webshop_id: creds ? creds.webShopId : credentials.webShopId,
      },
    })

    if (
      !(
        response.validCredentials &&
        response.validWebshopId &&
        response.accessToWebshop
      )
    ) {
      setErrors({
        credentialsError: response.validCredentials
          ? undefined
          : __('Invalid API Key', 'posten-bring-checkout'),
        noAccessToWebshopError: response.accessToWebshop
          ? undefined
          : __(
              'Provided API Key has no access to this webshop',
              'posten-bring-checkout'
            ),
      })
      setFailedCredentials(true)
      setIsSaving(false)
    } else {
      setClipboardRequested(false)
      setKeyPresent(false)
      setIsSaving(false)
      setMissingCredentials(false)
      setFormActive(false)

      onTaskComplete && onTaskComplete()
    }
  }

  const fillOutForm = useCallback(async () => {
    setClipboardRequested(true)
    try {
      const clipboardText = await navigator.clipboard.readText()
      const [webShopId, apiKey] = clipboardText.split(':')
      setClipboardSupported(true)
      const uuidRegex =
        /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
      const base64Regex = /^[A-Za-z0-9+/]+={0,2}$/

      if (uuidRegex.test(webShopId) && base64Regex.test(apiKey)) {
        const creds = {
          apiKey: apiKey.trim(),
          webShopId: webShopId.trim(),
        }

        setCredentials(creds)
        setKeyPresent(true)
        await storeCredentials(undefined, creds) // Save credentials
      } else {
        setKeyPresent(false)
      }
    } catch (err: any) {
      if (err.name === 'NotAllowedError') {
        setClipboardSupported(false)
      } else if (err.name === 'NotFoundError') {
        setClipboardSupported(false)
      }
      setKeyPresent(false)
    }
  }, [])
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { value } = e.target

    const [webShopId, apiKey] = value.split(':')

    if (webShopId && apiKey) {
      setCredentials({
        webShopId: webShopId.trim(),
        apiKey: apiKey.trim(),
      })
    }
    // Clear any previous errors
    setErrors({})
  }

  const ErrorNotice = () => (
    <div className="mtm">
      <Notice status="error" politeness="assertive" isDismissible={false}>
        <strong>
          {__('⚠️ A problem has occurred', 'posten-bring-checkout')}
        </strong>
        <p>
          {__(
            'Please look carefully through the values you entered.',
            'posten-bring-checkout'
          )}
        </p>
      </Notice>
    </div>
  )

  const MissingAddressNotice = () => (
    <div className="mbl mrm">
      <Notice status="warning" politeness="assertive" isDismissible={false}>
        <strong>{__('Missing address', 'posten-bring-checkout')}</strong>
        <p>
          {__(
            'No webshop title or address has been configured. Posten Bring Checkout requires a complete address to be able to present shipping options.',
            'posten-bring-checkout'
          )}
        </p>
        <ButtonGroup>
          <Button
            variant="secondary"
            iconPosition="right"
            icon={arrowRight}
            href={getAdminLink('admin.php?page=wc-settings')}
            className="mbs"
          >
            {__('Configure address', 'posten-bring-checkout')}
          </Button>
          <Button
            variant="secondary"
            iconPosition="right"
            icon={arrowRight}
            href={getAdminLink('options-general.php')}
          >
            {__('Configure title', 'posten-bring-checkout')}
          </Button>
        </ButtonGroup>
      </Notice>
    </div>
  )

  return (
    <div id="posten-bring-checkout-settings">
      <h1>{__('Settings', 'posten-bring-checkout')}</h1>
      <hr />
      {isLoading ? (
        <div>{__('Fetching settings…', 'posten-bring-checkout')}</div>
      ) : (
        <>
          <div className="flex flex-dir-row gaxl mts">
            {missingCredentials && (
              <div style={{ width: '300px' }}>
                <div>
                  <h4>{__('Mybring key', 'posten-bring-checkout')}</h4>
                  <p>
                    {__(
                      'Register your webshop in Mybring. You will get your API key there.',
                      'posten-bring-checkout'
                    )}
                  </p>
                  {(missingCredentials || formActive) && (
                    <img src={passwordImage} alt="" width={290} />
                  )}
                </div>
              </div>
            )}
            <div>
              <Card
                style={{
                  width: '600px',
                  borderRadius: '10px',
                  paddingBottom: '10px',
                }}
              >
                <CardBody>
                  {(missingCredentials || formActive) && (
                    <form onSubmit={storeCredentials}>
                      <div
                        style={{
                          display: 'flex',
                          flexDirection: 'column',
                          rowGap: '1.0rem',
                        }}
                      >
                        <div>
                          {clipboardRequested === false && (
                            <>
                              <h3>
                                {__('Activate plugin', 'posten-bring-checkout')}
                              </h3>
                              <p>
                                {__('Go to', 'posten-bring-checkout')}{' '}
                                <a
                                  href="https://www.mybring.com/checkout"
                                  target="_blank"
                                  rel="noreferrer"
                                >
                                  {__(
                                    'Mybrings checkout area',
                                    'posten-bring-checkout'
                                  )}
                                </a>{' '}
                                {__(
                                  'navigate to your shop configuration and get your key. Come back here when you have copied the key.',
                                  'posten-bring-checkout'
                                )}
                              </p>
                            </>
                          )}

                          {clipboardRequested === true &&
                            keyPresent === false &&
                            clipboardSupported === true && (
                              <>
                                <h3>
                                  {__(
                                    'Activate plugin',
                                    'posten-bring-checkout'
                                  )}
                                </h3>
                                <p>
                                  {__(
                                    'Could not find key!',
                                    'posten-bring-checkout'
                                  )}{' '}
                                  <br /> {__('Go to', 'posten-bring-checkout')}{' '}
                                  <a
                                    href="https://www.mybring.com/checkout"
                                    target="_blank"
                                    rel="noreferrer"
                                  >
                                    {__(
                                      'Mybrings checkout area',
                                      'posten-bring-checkout'
                                    )}
                                  </a>{' '}
                                  {__(
                                    'and click Copy key again.',
                                    'posten-bring-checkout'
                                  )}{' '}
                                </p>
                              </>
                            )}

                          {clipboardRequested === true &&
                            clipboardSupported === false && (
                              <>
                                <h3>
                                  {__(
                                    'Activate plugin',
                                    'posten-bring-checkout'
                                  )}
                                </h3>
                                <p>
                                  {__(
                                    'Paste your key here:',
                                    'posten-bring-checkout'
                                  )}
                                </p>
                              </>
                            )}

                          {clipboardRequested === true &&
                            keyPresent === true && (
                              <p>
                                {__('Activating…', 'posten-bring-checkout')}
                              </p>
                            )}

                          <div>
                            {clipboardRequested && !clipboardSupported && (
                              <label htmlFor="webShopId">
                                {__('Key', 'posten-bring-checkout')}
                              </label>
                            )}
                            <input
                              id="webShopId"
                              type={
                                clipboardRequested && !clipboardSupported
                                  ? 'text'
                                  : 'hidden'
                              }
                              className={`${
                                errors.webShopIdError ||
                                errors.noAccessToWebshopError
                                  ? 'input-error'
                                  : ''
                              }`}
                              aria-invalid={
                                !!errors.webShopIdError ||
                                !!errors.noAccessToWebshopError
                              }
                              aria-errormessage={
                                errors.webShopIdError ||
                                errors.noAccessToWebshopError
                              }
                              onChange={handleChange}
                              disabled={isSaving}
                            />
                            {(errors.webShopIdError ||
                              errors.noAccessToWebshopError) && (
                              <span className={'input-error-description'}>
                                ⚠️{' '}
                                {errors.webShopIdError ||
                                  errors.noAccessToWebshopError}
                              </span>
                            )}
                          </div>
                        </div>
                        <div>
                          <ButtonGroup>
                            {!keyPresent && credentials.apiKey === '' && (
                              <Button
                                onClick={(
                                  e: React.MouseEvent<HTMLButtonElement>
                                ) => {
                                  e.preventDefault()
                                  fillOutForm()
                                }}
                                variant="primary"
                                isBusy={isSaving}
                              >
                                {__('Use key', 'posten-bring-checkout')} 🔑
                              </Button>
                            )}
                            {credentials.apiKey !== '' &&
                              credentials.webShopId !== '' && (
                                <Button
                                  variant="primary"
                                  type="submit"
                                  isBusy={isSaving}
                                >
                                  {__('Save', 'posten-bring-checkout')}
                                </Button>
                              )}
                            {formActive && (
                              <Button
                                onClick={(
                                  e: React.MouseEvent<HTMLButtonElement>
                                ) => {
                                  e.preventDefault()
                                  toggleFormActive()
                                }}
                                variant="secondary"
                                className="mls"
                                isBusy={isSaving}
                              >
                                {__('Cancel', 'posten-bring-checkout')}
                              </Button>
                            )}
                          </ButtonGroup>
                        </div>
                      </div>
                    </form>
                  )}
                  {credentials.webShopId !== '' &&
                    !missingCredentials &&
                    !formActive && (
                      <div>
                        <div className="flex justify-csb">
                          <div>
                            <div className="mtl">
                              {shopAddressConfigured && (
                                <h2>
                                  {__(
                                    'Posten Bring Checkout is active!',
                                    'posten-bring-checkout'
                                  )}
                                </h2>
                              )}
                              {!shopAddressConfigured && (
                                <h2>
                                  {__(
                                    'Posten Bring Checkout is almost ready for usage…',
                                    'posten-bring-checkout'
                                  )}
                                </h2>
                              )}
                              {!missingCredentials &&
                                !shopAddressConfigured && (
                                  <MissingAddressNotice />
                                )}
                            </div>
                            <div
                              style={{
                                marginTop: !shopAddressConfigured
                                  ? '30px'
                                  : '120px',
                              }}
                            >
                              <Button
                                variant="link"
                                onClick={(
                                  e: React.MouseEvent<HTMLButtonElement>
                                ) => {
                                  e.preventDefault()
                                  toggleFormActive()
                                }}
                              >
                                {__(
                                  'Modify Mybring key',
                                  'posten-bring-checkout'
                                )}
                              </Button>
                            </div>
                          </div>
                          <div className="flex flex-dir-col align-ic justify-cc">
                            <img
                              src={
                                !shopAddressConfigured
                                  ? almostActivatedImage
                                  : activatedImage
                              }
                              alt=""
                              width={250}
                            />
                          </div>
                        </div>
                      </div>
                    )}
                </CardBody>
              </Card>
              {failedCredentials && <ErrorNotice />}
              <br />
              {!missingCredentials && !blockCheckoutActive && (
                <ToggleDarkMode />
              )}
              {credentials.webShopId !== '' &&
                !missingCredentials &&
                !formActive &&
                shopAddressConfigured && <ToggleRemoteLog />}
            </div>
          </div>
          {credentials.webShopId !== '' && !missingCredentials && (
            <FeedbackForm className="mtxl" />
          )}
        </>
      )}
    </div>
  )
}

export default Settings
