import React, { FC, useEffect } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { Link, useParams, useHistory } from 'react-router-dom'
import { faPlusSquare, faMinusSquare } from '@fortawesome/free-solid-svg-icons'
import moment from 'moment'

import { handleApiError } from '../../api/errors'
import { fetchApp, installApp, uninstallApp } from '../../actions/apps'
import { fetchInstallations } from '../../actions/composer'
import { getAuthenticatedUserId } from '../../selectors/authentication'
import { getInstallations } from '../../selectors/composer'
import { getEntity } from '../../selectors/entities'
import { getIsFetching } from '../../selectors/requests'

import { useTheme } from '../../hooks'
import { setTitle } from '../../utils'
import { AppState, AppThunkDispatch, EntityType, App, RequestKey, LevelItem } from '../../types'

import Title from '../../components/title'
import Section from '../../components/section'
import HorizontalRule from '../../components/horizontal-rule'
import Button from '../../components/controls/button'
import Level from '../../components/level'
import Loading from '../../components/pages/loading'

interface Params {
    id: string
}

const ViewApp: FC = () => {
    const { id } = useParams<Params>()
    const theme = useTheme()
    const app = useSelector<AppState, App | undefined>(state => getEntity<App>(state, EntityType.App, id))
    const installations = useSelector(getInstallations)
    const selfId = useSelector(getAuthenticatedUserId)
    const fetching = useSelector<AppState, boolean>(state => getIsFetching(state, RequestKey.InstallApp) || getIsFetching(state, RequestKey.UninstallApp))
    const dispatch = useDispatch<AppThunkDispatch>()
    const history = useHistory()

    useEffect(() => {
        try {
            dispatch(fetchApp(id))
            dispatch(fetchInstallations())
        } catch (err) {
            handleApiError(err, dispatch, history)
        }
    }, [])

    useEffect(() => {
        if (app) setTitle(app.name)
    }, [app])

    if (!app) return <Loading />

    const isCreator = app.user.id === selfId
    const installed = !!installations.find(i => i.app.id === app.id)

    const renderButton = () => {
        if (installed) {
            const handleClick = async () => {
                await dispatch(uninstallApp(id))
                await dispatch(fetchApp(id))
            }

            return (
                <Button text="Uninstall" icon={faMinusSquare} loading={fetching} onClick={() => handleClick()} color="#fff" backgroundColor={theme.red} />
            )
        } else {
            const handleClick = async () => {
                await dispatch(installApp(id))
                await dispatch(fetchApp(id))
            }

            return (
                <Button text="Install" icon={faPlusSquare} loading={fetching} onClick={() => handleClick()} color={theme.primaryAlternate} backgroundColor={theme.primary} />
            )
        }
    }

    const items: LevelItem[] = []
    items.push({
        label: 'Users',
        content: app.users,
    })
    items.push({
        label: 'Rating',
        content: app.rating.toString(),
    })
    
    if (app.companyName) {
        items.push({
            label: 'Company',
            content: app.companyName,
        })
    }

    items.push({
        label: 'Updated',
        content: moment(app.updated).format('MMMM Do, YYYY'),
    })

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

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

                <div style={{ textAlign: 'center', padding: '1rem' }}>
                    {renderButton()}
                </div>

                <HorizontalRule />

                <div className="buttons">
                    {isCreator && <Link style={{ color: theme.secondary }} to={`/a/${id}/edit`}>View/Edit App</Link>}
                </div>
            </Section>
        </div>
    )
}

export default ViewApp
