import React from 'react'
import PropTypes from 'prop-types'
import inputNames from 'common-fe/constants/input-names'
import FormError from 'common-fe/utils/form-error'
import {sparsifyObj} from 'common-fe/utils'
import {validateInput} from 'common-fe/utils/validation'

import Form from 'react-uikit/form'
import Button from 'react-uikit/button'
import SuggestionsInput from 'react-uikit/input-suggestions'
import SchoolSearchItem from 'react-uikit/list-item/templates/search-school'
import SchoolSearchErrorItem from 'react-uikit/list-item/templates/search-school-error'

import BEMModule from 'utils/bem'
import styles from './styles.scss'
const bem = new BEMModule(styles)

class SchoolSettingsForm extends React.Component {
    static formName = 'school-settings'

    static defaultState = {
        data: {
            [inputNames.SCHOOL_ID]: {label: '', value: ''},
        },
    }

    get initialState() {
        const {
            school: {name = '', id = ''},
        } = this.props

        return {
            data: {
                ...SchoolSettingsForm.defaultState.data,
                [inputNames.SCHOOL_ID]:
                    name && id
                        ? {label: name, value: id}
                        : SchoolSettingsForm.defaultState.data[
                              inputNames.SCHOOL_ID
                          ],
            },
            error: {...SchoolSettingsForm.defaultState.error},
        }
    }

    get suggestionTemplate() {
        if (
            this.props.schoolSuggestions.isEmpty ||
            this.props.schoolSuggestions.isError ||
            this.props.schoolSuggestions.isLoading
        ) {
            return SchoolSearchErrorItem
        }

        return SchoolSearchItem
    }

    get schools() {
        return this.props.schoolSuggestions.results.list
    }

    change = ({name, value}) => {
        const {data} = this.props

        this.props.onChange && this.props.onChange({...data, [name]: value})
    }

    updateSchool = (data) => {
        const {user, updateProfessor, onError, onSubmit} = this.props

        if (!updateProfessor) {
            return
        }

        const payload = {
            userId: user.id,
            payload: sparsifyObj({
                [inputNames.SCHOOL_ID]: data[inputNames.SCHOOL_ID].value,
            }),
        }

        updateProfessor(payload)
            .then((payload) => onSubmit && onSubmit(payload))
            .catch((err) => {
                if (!err.inlineErrors || !err.inlineErrors.length || !onError) {
                    return
                }

                const error = new FormError(
                    Object.keys(SchoolSettingsForm.defaultState.data),
                    err.inlineErrors
                )

                onError && onError(error)
            })
    }

    validate = ({name, value, isRequired}) =>
        validateInput({name, value: value.value, isRequired})

    onQueryChange = (query) => {
        query &&
            query.length > 0 &&
            this.props.updateSchoolSearch &&
            this.props.updateSchoolSearch({query})
    }

    render() {
        const {data, error, onCancel, onError} = this.props

        const classNames = bem.classNames('c-school-settings-form')
        const buttonClassNames = bem.classNames(
            'c-school-settings-form__button'
        )
        const labelClassNames = bem.classNames('c-school-settings-form__label')
        const submitClassNames = bem.classNames(
            'c-school-settings-form__submit'
        )

        return (
            <Form
                className={classNames}
                data={data}
                error={error}
                name={SchoolSettingsForm.formName}
                validate={this.validate}
                onChange={this.change}
                onError={onError}
                onSubmit={this.updateSchool}
            >
                <label
                    className={labelClassNames}
                    htmlFor={inputNames.SCHOOL_ID}
                >
                    Institution
                </label>

                <Form.Field
                    name={inputNames.SCHOOL_ID}
                    placeholder="Institution"
                    render={SuggestionsInput}
                    required
                    size="small"
                    suggestionItemTemplate={this.suggestionTemplate}
                    suggestions={this.schools}
                    onQueryChange={this.onQueryChange}
                />

                <div className={submitClassNames}>
                    <Button
                        className={buttonClassNames}
                        isOutline
                        variant="neutral"
                        size="small"
                        text="cancel"
                        onClick={onCancel}
                    />

                    <Form.SubmitTrigger
                        render={({submit}) => (
                            <Button
                                className={buttonClassNames}
                                variant="primary"
                                size="small"
                                text="save"
                                onClick={submit}
                            />
                        )}
                    />
                </div>
            </Form>
        )
    }
}

SchoolSettingsForm.defaultProps = {
    data: {...SchoolSettingsForm.defaultState.data},
    error: {...SchoolSettingsForm.defaultState.error},
}

SchoolSettingsForm.propTypes = {
    data: PropTypes.object,
    error: PropTypes.object,
    school: PropTypes.object,
    schoolSuggestions: PropTypes.object,
    updateProfessor: PropTypes.func,
    updateSchoolSearch: PropTypes.func,
    user: PropTypes.shape({
        id: PropTypes.string,
        schoolId: PropTypes.string,
    }),
    valid: PropTypes.object,
    onCancel: PropTypes.func,
    onChange: PropTypes.func,
    onError: PropTypes.func,
    onSubmit: PropTypes.func,
}

export default SchoolSettingsForm
