import React, { FC, useEffect, useState } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { useParams, useHistory } from 'react-router-dom'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faUserPlus, faUserMinus, faUserClock, faBan } from '@fortawesome/free-solid-svg-icons'
import moment from 'moment'

import { handleApiError } from '../../api/errors'
import { fetchUser, subscribe, unsubscribe } from '../../actions/users'
import { fetchUserPosts } from '../../actions/posts'
import { setTheme } from '../../actions/theme'
import { getEntity } from '../../selectors/entities'
import { getAuthenticatedUser, getChecked } from '../../selectors/authentication'
import { getUserPosts } from '../../selectors/posts'
import { getThemeName } from '../../selectors/theme'

import { useDeepCompareEffect, useTheme, useSetting } from '../../hooks'
import { setTitle } from '../../utils'
import { AppState, EntityType, User, Post, AppThunkDispatch, LevelItem } from '../../types'

import Title from '../../components/title'
import Subtitle from '../../components/subtitle'
import Level from '../../components/level'
import PostList from '../../components/post-list'
import Section from '../../components/section'
import HorizontalRule from '../../components/horizontal-rule'
import Loading from '../../components/pages/loading'

interface Params {
    id: string
}

const ViewUser: FC = () => {
    const { id } = useParams<Params>()
    const theme = useTheme()
    const themeName = useSelector(getThemeName)
    const [selectedThemeName] = useState(themeName)
    const checked = useSelector(getChecked)
    const self = useSelector(getAuthenticatedUser)
    const user = useSelector<AppState, User | undefined>(state => getEntity<User>(state, EntityType.User, id))
    const posts = useSelector<AppState, Post[]>(state => getUserPosts(state, id))
    const dispatch = useDispatch<AppThunkDispatch>()
    const history = useHistory()
    const allowThemeChange = useSetting<boolean>('allowThemeChange', true)

    useEffect(() => {
        const init = async () => {
            try {
                await dispatch(fetchUser(id))
                await dispatch(fetchUserPosts(id))
            } catch (err) {
                handleApiError(err, dispatch, history)
            }
        }

        if (checked) init()
    }, [checked])

    useDeepCompareEffect(() => {
        if (user) {
            setTitle(user.name)
            if (allowThemeChange && user.theme) dispatch(setTheme(user.theme))
        }

        return () => {
            if (allowThemeChange && selectedThemeName) dispatch(setTheme(selectedThemeName))
        }
    }, [user])

    if (!user) return <Loading />

    const isSelf = self && self.id === user.id
    const isGroup = self && self.group && user.group && self.group.id === user.group.id
    const subscription = self && user.subscriptions ? user.subscriptions.find(subscription => subscription.from === self.id && subscription.to === user.id) : undefined
    const subscribed = subscription && !subscription.pending
    const subscriptionPending = subscription && subscription.pending

    const items: LevelItem[] = []
    items.push({
        label: 'Posts',
        content: user.posts,
    })
    items.push({
        label: 'Awards',
        content: user.awards,
    })
    items.push({
        label: 'Points',
        content: user.points,
    })
    items.push({
        label: 'Joined',
        content: moment(user.created).format('MMMM Do, YYYY'),
    })

    return (
        <div>
            <Section>
                {user.coverImageUrl &&
                    <div className="cover-image">
                        <img src={user.coverImageUrl} />
                    </div>
                }

                <div className="header">
                    {user.imageUrl &&
                        <div className="image">
                            <img src={user.imageUrl} style={{ width: 128 }} />
                        </div>
                    }
                    <div>
                        <Title>{user.name}</Title>
                        <p style={{ color: theme.text }}>{user.about}</p>
                    </div>
                </div>
                
                <Level items={items} />
                <HorizontalRule />

                <div className="buttons">
                    {subscribed &&
                        <button style={{ backgroundColor: theme.red, color: 'white' }} onClick={() => dispatch(unsubscribe(user.id))}>
                            <span className="button-icon">
                                <FontAwesomeIcon icon={faUserMinus} />
                            </span>
                            <span>Unsusbcribe</span>
                        </button>
                    }

                    {subscriptionPending &&
                        <button style={{ backgroundColor: theme.blue, color: 'white' }}>
                            <span className="button-icon">
                                <FontAwesomeIcon icon={faUserClock} />
                            </span>
                            <span>Pending</span>
                        </button>
                    }

                    {self && !isSelf && !subscribed && !subscriptionPending &&
                        <button style={{ backgroundColor: theme.green, color: 'white' }} onClick={() => dispatch(subscribe(user.id))}>
                            <span className="button-icon">
                                <FontAwesomeIcon icon={faUserPlus} />
                            </span>
                            <span>Subscribe</span>
                        </button>
                    }

                    {!isSelf &&
                        <button style={{ backgroundColor: theme.red, color: 'white' }}>
                            <span className="button-icon">
                                <FontAwesomeIcon icon={faBan} />
                            </span>
                            <span>Block</span>
                        </button>
                    }

                    {user.group && !isGroup &&
                        <button style={{ backgroundColor: theme.red, color: 'white' }}>
                            <span className="button-icon">
                                <FontAwesomeIcon icon={faBan} />
                            </span>
                            <span>Block Community: {user.group.name}</span>
                        </button>
                    }
                </div>
            </Section>

            <div style={{ padding: '0px 1rem' }}>
                <Subtitle>Posts</Subtitle>
            </div>

            <PostList posts={posts} />
        </div>
    )
}

export default ViewUser
