import React, {useState, useEffect, useCallback} from 'react'
import PropTypes from 'prop-types'
import inputNames from 'common-fe/constants/input-names'
import {validateInput} from 'common-fe/utils/validation'
import UserClient from 'common-fe/clients/user'
import {uuid} from 'common-fe/utils'

import {Flex} from 'react-uikit/layout'
import Banner from 'components/banner'
import Button from 'react-uikit/button'
import Form from 'react-uikit/form'
import Loader from 'react-uikit/loader'
import ModalForm from 'react-uikit/modal/form'
import TeamManagementRow from './partials/row'
import TextInput from 'react-uikit/input-text'

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

const defaultState = {[inputNames.EMAIL]: ''}

const TeamManagementModal = ({
    currentUser,
    getUser,
    isShowing,
    onDismiss,
    portfolio,
    updatePortfolioUsers,
    users,
}) => {
    // Fetching User Data ======================================================
    const [usersTracking, setUsersTracking] = useState(uuid())
    useEffect(() => {
        portfolio.userIds.forEach((id) => {
            if (!users[id]) {
                getUser({userId: id})
            }
        })
    }, [portfolio.id, portfolio.userIds.length, usersTracking])

    // User Lookup Form ========================================================
    const emailFieldId = 'team-management-modal-email-field'
    const [formData, setFormData] = useState(defaultState)
    const [formError, setFormError] = useState({})
    const onChange = ({name, value}) => {
        setFormData({[name]: value})
    }
    const validate = ({name, value, isRequired}) => {
        return validateInput({name, value, isRequired})
    }

    // Search ==================================================================
    const [searchUser, setSearchUser] = useState({})
    const [searchErrors, setSearchErrors] = useState([])
    const [searchIsLoading, setSearchLoading] = useState(false)
    const [hasSearched, setHasSearched] = useState(false)
    const lookUpUser = useCallback(({email}) => {
        setSearchErrors([])
        setSearchLoading(true)
        UserClient.searchUser({email})
            .then((result) => {
                setSearchLoading(false)
                setHasSearched(true)
                const user = result[0] || {}
                user.email = email
                setSearchUser(user)
            })
            .catch((error) => {
                setSearchLoading(false)
                setSearchErrors(error.errors)
            })
    }, [])
    const resetSearch = useCallback(() => {
        setSearchUser({})
        setHasSearched(false)
    }, [])

    // User Management =========================================================
    const addUser = useCallback(
        (idToAdd, userIds) => {
            const _userIds = userIds.filter(Boolean)
            updatePortfolioUsers({
                portfolioId: portfolio.id,
                userIds: [..._userIds, idToAdd],
            })
            resetSearch()
            setUsersTracking(uuid())
        },
        [portfolio.id]
    )

    const removeUser = useCallback(
        (idToRemove, userIds) => {
            updatePortfolioUsers({
                portfolioId: portfolio.id,
                userIds: userIds.filter((id) => id !== idToRemove),
            })
            setUsersTracking(uuid())
        },
        [portfolio.id]
    )

    const sortedUserIds = [
        currentUser.id,
        ...portfolio.userIds.filter((id) => id !== currentUser.id),
    ]
    const team = sortedUserIds.map((id) => users[id]).filter(Boolean)
    const hasSearchResults = !!searchUser.id

    const rootClasses = bem.classNames('c-team-management-modal')
    const hrClasses = bem.classNames('c-team-management-modal__hr')
    const formClasses = bem.classNames('c-team-management-modal__form')
    const bannerClasses = bem.classNames('c-team-management-modal__banner')
    const notFoundClasses = bem.classNames('c-team-management-modal__not-found')

    return (
        <ModalForm
            className={rootClasses}
            isShowing={isShowing}
            onDismiss={onDismiss}
            title="Team Management"
        >
            {team.map(({id, avatarUrl, firstName, lastName, email}) => (
                <React.Fragment key={id}>
                    <TeamManagementRow
                        addUser={addUser}
                        userIds={sortedUserIds}
                        avatarUrl={avatarUrl}
                        email={email}
                        firstName={firstName}
                        id={id}
                        currentUserId={currentUser.id}
                        lastName={lastName}
                        removeUser={removeUser}
                        toRemove
                    />
                    <hr className={hrClasses} />
                </React.Fragment>
            ))}

            <Form
                className={formClasses}
                data={formData}
                error={formError}
                name="team-management-look-up-by-email"
                onChange={onChange}
                onError={setFormError}
                onSubmit={lookUpUser}
                validate={validate}
                validateOnUpdate
            >
                <fieldset>
                    <div>
                        <label htmlFor={emailFieldId}>Add more members</label>
                        <Form.Field
                            id={emailFieldId}
                            render={TextInput}
                            type="email"
                            required
                            name={inputNames.EMAIL}
                            placeholder="ex. han@yolo.com"
                        />
                    </div>
                    <Form.SubmitTrigger
                        render={({submit}) => (
                            <Button
                                variant="primary"
                                text="Look Up"
                                onClick={submit}
                            />
                        )}
                    />
                </fieldset>
                <p>Look up registered users by their email.</p>
            </Form>
            {searchIsLoading && (
                <Flex align="center" justify="center">
                    <Loader size="small" />
                </Flex>
            )}
            {hasSearchResults && (
                <TeamManagementRow
                    addUser={addUser}
                    avatarUrl={searchUser.avatarUrl}
                    email={searchUser.email}
                    firstName={searchUser.firstName}
                    id={searchUser.id}
                    currentUserId={currentUser.id}
                    lastName={searchUser.lastName}
                    removeUser={removeUser}
                    toAdd
                    userIds={sortedUserIds}
                />
            )}
            {hasSearched && !hasSearchResults && (
                <div className={bannerClasses}>
                    <Banner warning>
                        <p className={notFoundClasses}>
                            <em>We couldn’t find a user with that email.</em> Do
                            they have an account on EquitySim? It only takes a
                            minute to create one{' '}
                            <a href="https://equitysim.com/registration/">
                                equitysim.com/registration
                            </a>
                            .
                        </p>
                    </Banner>
                </div>
            )}
            {searchErrors.length > 0 && (
                <div className={bannerClasses}>
                    <Banner error>{searchErrors[0].reason}</Banner>
                </div>
            )}
        </ModalForm>
    )
}

TeamManagementModal.propTypes = {
    currentUser: PropTypes.object,
    getUser: PropTypes.func,
    isShowing: PropTypes.bool,
    portfolio: PropTypes.object,
    updatePortfolioUsers: PropTypes.func,
    users: PropTypes.object,
    onDismiss: PropTypes.func,
}

export default TeamManagementModal
