import React, { useEffect, useState } from 'react'
import PropTypes from 'prop-types'
import styles from './MissingRequirements.module.scss'
import ModalWrapper from '../Modal/ModalWrapper'
import installRequirement from '../../api/installRequirement'
import MainHeading from '../Titles/MainHeading'
import Button from '../Buttons/Button'
import ExternalLink from '../Buttons/ExternalLink'

const InstallRequirementInBackground = ({ requirement, completeCallback }) => {
  if (!requirement) {
    // If the user has chosen to skip this requirement (by unselecting it)
    // then we fire the complete callback and return a 'Skipped' mesage for the UI to display
    useEffect(() => {
      completeCallback()
    }, [])
    return 'Skipped'
  }
  const { loading, data, error } = installRequirement(requirement)

  useEffect(() => {
    if (!loading) {
      // If we have finished loading (i.e. installing the requirement)
      // we call our completeCallback but we don't care if we errored on this one
      // just continue onto the next.
      completeCallback(error)
    }
  }, [loading])

  return (
    <>
      {loading ? (
        <>
          <span className={`dashicons dashicons-update ${styles.installingIcon}`} />
          Installing...
        </>
      ) : null}
      {error ? (
        <>
          <span className='dashicons dashicons-no' />
          {data && data.error ? (
            <>
              {data.error.data && data.error.data.url
                ? <a href={data.error.data.url} target='_blank' rel='noopener noreferrer'>{data.error.message}</a> : data.error.message}
            </>
          ) : 'Error'}
        </>
      ) : null}
      {!loading && !error ? (
        <>
          <span className='dashicons dashicons-yes-alt' />
          Success!
        </>
      ) : null}
    </>
  )
}

const RequiredCSSPreview = ({ previewCss }) => {
  const [openRequiredCSSModal, setOpenRequiredCSSModal] = useState(false)
  return (
    <>
      {openRequiredCSSModal ? (
        <ModalWrapper isOpen onCloseCallback={() => setOpenRequiredCSSModal(false)}>
          <code className={styles.cssPreview}>
            <pre>
              {previewCss}
            </pre>
          </code>
        </ModalWrapper>) : null}{' '}
      <a
        href='#'
        onClick={(event) => {
          event.preventDefault()
          setOpenRequiredCSSModal(true)
          return false
        }}
      >
        Preview CSS
      </a>
    </>
  )
}

const MissingRequirements = ({ plugins, theme, settings, requiredCss, templateKitId, completeCallback }) => {
  const [openRequirementsModal, setOpenRequirementsModal] = useState(false)
  const [installingIndex, setInstallingIndex] = useState(null)
  const [requirementsToInstall, setRequirementsToInstall] = useState({})

  const installNextRequirement = () => {
    setInstallingIndex(oldStep => oldStep + 1)
  }

  const missingRequirements = []
  /**
  plugins is an array of objects that looks like this:

  plugins = [
    {
      author: "Elementor.com"
      file: "elementor/elementor.php"
      name: "Elementor"
      slug: "elementor"
      status: "activated"
      url: ""
      version: "2.9.6"
    }
  ]
  */
  plugins.forEach(plugin => {
    if (plugin.status !== 'activated') {
      missingRequirements.push({
        plugin
      })
    }
  })

  /**
  settings is an array of objects that looks like this:

  settings = [
    {
      name: "Elementor default color schemes"
      setting_name: "elementor_disable_color_schemes"
    }
  ]
  */
  settings.forEach(setting => {
    missingRequirements.push({
      setting
    })
  })

  /**
  required css is an array of objects that looks like this:

  required_css = [
    {
      name: "Global CSS"
      description: "This is the global CSS for this template kit, this can be edited from the WordPress Customizer."
      file: "css/customizer.css"
    }
  ]
  */
  requiredCss.forEach(requiredCss => {
    missingRequirements.push({
      requiredCss: { ...requiredCss, templateKitId }
    })
  })

  const missingCount = missingRequirements.length

  // If we don't have any missing requirements then we can skip rendering anything for this banner
  if (missingCount === 0) {
    return null
  }

  const isRequirementSelectedForInstall = (index) => {
    return typeof requirementsToInstall[index] === 'undefined' || requirementsToInstall[index]
  }

  // We have some missing requirements, display a banner with a button that opens a modal:
  return (
    <>
      {openRequirementsModal ? (
        <ModalWrapper isOpen onCloseCallback={completeCallback}>
          <div>
            <MainHeading title='Missing Requirements' />
            <p className={styles.notice}>Please install and activate these missing requirements for this Template Kit to work correctly. We recommend checking with your web developer before applying these changes.</p>
            <ul className={styles.requirements}>
              {missingRequirements.map((requirement, index) => {
                return (
                  <li key={`requirement${index}`} className={styles.requirement}>
                    <div className={styles.checkbox}>
                      <input
                        type='checkbox' id={`requirement${index}`} name='installRequirement[]' value='1' disabled={installingIndex !== null} checked={isRequirementSelectedForInstall(index)} onChange={(e) => {
                          const isChecked = !!e.target.checked
                          setRequirementsToInstall(oldRequirements => ({ ...oldRequirements, [index]: isChecked }))
                        }}
                      />
                    </div>
                    <div className={styles.text}>
                      <label htmlFor={`requirement${index}`}>
                        {requirement.theme ? `Theme: ${requirement.theme.name}` : null}
                        {requirement.plugin ? `Plugin: ${requirement.plugin.name}` : null}
                        {requirement.setting ? `Setting: ${requirement.setting.name}` : null}
                        {requirement.requiredCss ? (
                          <>
                            {requirement.requiredCss.name}: {requirement.requiredCss.description}
                            <RequiredCSSPreview previewCss={requirement.requiredCss.css_preview} />
                          </>
                        ) : null}
                      </label>
                    </div>
                    <div className={styles.status}>
                      {installingIndex === index || installingIndex > index ? (
                        <InstallRequirementInBackground key={`installRequirement${index}`} requirement={isRequirementSelectedForInstall(index) ? requirement : null} completeCallback={installNextRequirement} />
                      ) : null}
                    </div>
                  </li>
                )
              })}
              {theme && theme.name ? (
                <li className={styles.requirement}>
                  <div className={styles.checkbox}>
                    <span className='dashicons dashicons-warning' />
                  </div>
                  <div className={styles.text}>
                  FYI: This Template Kit has only been tested with the "{theme.name}" WordPress theme. <br />
                    If the imported templates don’t look correct please read <ExternalLink href='https://help.market.envato.com/hc/en-us/sections/360007560992-Template-Kits' text='this article' />.
                  </div>
                </li>
              ) : null}
            </ul>
            <div className={styles.footer}>
              {installingIndex === null ? (
                <Button
                  type='primary' icon='plus' label='Install Above Selected Requirements' onClick={() => {
                    setInstallingIndex(0)
                  }}
                />
              ) : (
                <>
                  {installingIndex >= missingCount ? (
                    <>
                      <p className={styles.notice}>Once the above is completed you can close this window.</p>
                      <Button
                        type='primary' icon='plus' label='Close' onClick={completeCallback}
                      />
                    </>
                  ) : (
                    <p className={styles.notice}>
                    Installing...
                    </p>
                  )}
                </>
              )}
            </div>
          </div>
        </ModalWrapper>
      ) : null}
      <div className={styles.wrapper}>
        <div className={styles.textWrapper}>
          <strong>Attention!</strong> There are {missingCount} requirements that need installing for this Template Kit to work correctly.
        </div>
        <div className={styles.buttonWrapper}>
          <Button type='attention' label='Install Requirements' icon='info' onClick={() => { setOpenRequirementsModal(true) }} />
        </div>
      </div>
    </>
  )
}

MissingRequirements.propTypes = {
  plugins: PropTypes.arrayOf(PropTypes.shape({
    author: PropTypes.string,
    file: PropTypes.string,
    name: PropTypes.string,
    slug: PropTypes.string,
    status: PropTypes.string,
    url: PropTypes.string,
    version: PropTypes.string
  })),
  settings: PropTypes.arrayOf(PropTypes.shape({
    name: PropTypes.string,
    setting_name: PropTypes.string
  })),
  RequiredCss: PropTypes.arrayOf(PropTypes.shape({
    name: PropTypes.string,
    description: PropTypes.string,
    file: PropTypes.string
  })),
  templateKitId: PropTypes.number.isRequired,
  completeCallback: PropTypes.func.isRequired
}

MissingRequirements.defaultProps = {
  plugins: [],
  settings: [],
  requiredCss: []
}

export default MissingRequirements
