import React, { FC, useEffect } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { Link, useHistory } from 'react-router-dom'
import { faCheckCircle, faIdCard, faLink, faAddressBook, faCodeBranch } from '@fortawesome/free-solid-svg-icons'

import { checkAppAvailability, createApp } from '../../actions/apps'
import { initForm, initField, setFieldNotification } from '../../actions/forms'
import { showNotification } from '../../actions/notifications'
import { getForm } from '../../selectors/forms'
import { getIsFetching } from '../../selectors/requests'
import { useTheme } from '../../hooks'
import { setTitle, valueFromForm } from '../../utils'
import { AppState, NotificationType, AppThunkDispatch, RequestKey } from '../../types'

import Title from '../../components/title'
import Section from '../../components/section'
import HorizontalRule from '../../components/horizontal-rule'
import PrimaryButton from '../../components/controls/primary-button'
import TextField from '../../components/controls/text-field'
import TextareaField from '../../components/controls/textarea-field'
import CheckboxField from '../../components/controls/checkbox-field'
import ImageField from '../../components/controls/image-field'
import CoverImageField from '../../components/controls/cover-image-field'
import IconImageField from '../../components/controls/icon-image-field'

const CreateApp: FC = () => {
    const theme = useTheme()
    const form = useSelector(getForm)
    const fetching = useSelector<AppState, boolean>(state => getIsFetching(state, RequestKey.CreateApp))
    const dispatch = useDispatch<AppThunkDispatch>()
    const history = useHistory()

    const checkAvailability = (value: string) => {
        if (value.length > 3) {
            dispatch(checkAppAvailability(value))
        }
    }

    const handleCreate = async () => {
        let invalid = false

        const name = valueFromForm<string>(form, 'name')
        const about = valueFromForm<string>(form, 'about')
        const websiteUrl = valueFromForm<string>(form, 'websiteUrl')
        const companyName = valueFromForm<string>(form, 'companyName')
        const version = valueFromForm<string>(form, 'version')
        const composerUrl = valueFromForm<string>(form, 'composerUrl')
        const rendererUrl = valueFromForm<string>(form, 'rendererUrl')
        const imageUrl = valueFromForm<string>(form, 'image')
        const coverImageUrl = valueFromForm<string>(form, 'coverImage')
        const iconImageUrl = valueFromForm<string>(form, 'iconImage')
        const agree = valueFromForm<boolean>(form, 'agree')

        if (!name || name === '') {
            dispatch(setFieldNotification('name', NotificationType.Error, 'This is required'))
            invalid = true
        }

        if (!version || version === '') {
            dispatch(setFieldNotification('version', NotificationType.Error, 'This is required'))
            invalid = true
        }

        if (!agree) {
            dispatch(setFieldNotification('agree', NotificationType.Error, 'You must agree to the terms and conditions to continue'))
            dispatch(showNotification(NotificationType.Error, 'You must agree to the terms and conditions to continue.'))
            invalid = true
        }

        if (invalid) return

        const id = await dispatch(createApp({
            name: name!,
            version: version!,
            about,
            websiteUrl,
            companyName,
            composerUrl,
            rendererUrl,
            imageUrl,
            coverImageUrl,
            iconImageUrl,
        }))

        dispatch(showNotification(NotificationType.Success, 'App created successfully!'))

        setTimeout(() => {
            history.push(`/a/${id}`)
        }, 1000)
    }

    useEffect(() => {
        setTitle('Create a new App')

        dispatch(initForm())
        dispatch(initField('name', ''))
        dispatch(initField('about', ''))
        dispatch(initField('websiteUrl', ''))
        dispatch(initField('companyName', ''))
        dispatch(initField('version', ''))
        dispatch(initField('composerUrl', ''))
        dispatch(initField('rendererUrl', ''))
        dispatch(initField('agree', false))
    }, [])
    
    return (
        <div>
            <Section>
                <Title>Create a new App</Title>
                <HorizontalRule />

                <TextField name="name" label="Name" icon={faIdCard} placeholder="App ID/Name" onBlur={e => checkAvailability(e.target.value)} />
                <TextareaField name="about" label="About" placeholder="Description of this app" />
                <TextField name="websiteUrl" label="Website" icon={faLink} placeholder="Website URL (optional)" />
                <TextField name="companyName" label="Company" icon={faAddressBook} placeholder="Your company or organization (optional)" />
                <TextField name="version" label="Version" icon={faCodeBranch} placeholder="Current Version of the app (ex: 0.0.1beta5)" />
                <HorizontalRule />

                <ImageField name="image" />
                <CoverImageField name="coverImage" />
                <IconImageField name="iconImage" />
                <HorizontalRule />

                <TextField name="composerUrl" label="Composer URL" icon={faLink} placeholder="URL for the composer web page" />
                <TextField name="rendererUrl" label="Renderer URL" icon={faLink} placeholder="URL for the renderer template" />

                <CheckboxField name="agree">
                    I agree to the Apps <Link style={{ color: theme.primary }} to="/terms/apps">terms and conditions</Link>.
                </CheckboxField>
                <br /><br />
                
                <PrimaryButton text="Create" icon={faCheckCircle} loading={fetching} onClick={() => handleCreate()} />
            </Section>
        </div>
    )
}

export default CreateApp
