/* eslint-disable react/display-name */
import React, {useEffect, useRef, useState, useMemo} from 'react'
import PropTypes from 'prop-types'
import orderStatuses from 'common-fe/constants/order-statuses'
import requestStatuses from 'common-fe/constants/request-statuses'

import Accordion from 'react-uikit/accordion'
import Icon from 'react-uikit/icon'
import {withPagination} from 'react-uikit/table'
import ActivityDetails from './partials/activity-details'
import ActivityItem from './partials/activity-item'

import styles from './styles.scss'
import BEMModule from 'utils/bem'

const bem = new BEMModule(styles)
const Table = withPagination(Accordion)

const errorText = `We couldn't retrieve the activity history for this portfolio right now, please try again later.`

const ActivityTemplate = ({
    openedItem = [],
    onItemClose,
    onItemOpen,
    orders,
    policy,
    portfolio,
    securities,
    onPageChange,
}) => {
    // Create an array of blank values to render loading state rows if orders request is unresolved
    const orderList =
        orders?.status === requestStatuses.RESOLVED
            ? orders?.docs
            : Array(10).fill('')

    const data = useMemo(
        () =>
            orderList.map((order) => {
                const orderWithUser = order ? order : {}
                if (orderWithUser.firebaseId) {
                    orderWithUser.user = orders?.users[orderWithUser.firebaseId]
                }
                return orderWithUser
            }),
        [orderList.length, orders?.status]
    )
    const accordionTable = useRef(null)
    const [tablePages, setTablePages] = useState(1)
    const [hasResolved, setHasResolved] = useState(false)

    const handlePageChange = (pageIndex) => {
        if (pageIndex === orders?.page) {
            return
        }

        accordionTable?.current?.outerTableRef?.current?.closeAll?.()
        onPageChange?.(
            {
                include: 'all',
                portfolioId: portfolio.id,
                page: pageIndex,
                status: orderStatuses.PROCESSED.value,
            },
            {alertOnError: false, overrideLoader: true}
        )
    }

    useEffect(() => {
        // Open the first activity table row if viewing table for the first time
        if (
            orders?.requestCount === 1 &&
            orders?.status === requestStatuses.RESOLVED
        ) {
            accordionTable?.current?.outerTableRef?.current?.onOpen(1)
        }

        if (!hasResolved && orders?.status === requestStatuses.RESOLVED) {
            setHasResolved(true)
        }
    }, [orders?.status])

    useEffect(() => {
        // Update the order pages count if necessary - stops flickering between page changes
        if (
            orders?.status === requestStatuses.RESOLVED &&
            orders?.pages !== tablePages
        ) {
            setTablePages(orders.pages)
        }
    }, [orders?.pages])

    const classes = bem.classNames('c-activity-template')
    const headingClasses = bem.classNames('c-activity-template__heading')
    const footerClasses = bem.classNames('c-activity-template__footer')
    const paginationClasses = bem.classNames('c-activity-template__pagination')
    const errorWrapperClasses = bem.classNames(
        'c-activity-template__error-wrapper'
    )
    const warningClasses = bem.classNames('c-activity-template__warning')

    const {isOwner} = policy.forPortfolio(portfolio)
    const authenticatedVotingText = isOwner
        ? `Check out other users' portfolios to Upvote`
        : `Agree with their thinking? Upvote!`
    const votingText = policy.isAuthenticated ? (
        authenticatedVotingText
    ) : (
        <span>
            <a href="https://equitysim.com">Sign in</a> to Upvote
        </span>
    )

    if (orders?.status === requestStatuses.REJECTED) {
        return (
            <div className={errorWrapperClasses}>
                <Icon className={warningClasses} name="warning" />
                <span style={{lineHeight: '1.5', maxWidth: '36rem'}}>
                    {errorText}
                </span>
            </div>
        )
    }

    return (
        <Table
            className={classes}
            currentPage={orders?.page || 1}
            initialOpenItems={openedItem}
            pageCount={tablePages}
            paginationClassName={paginationClasses}
            ref={accordionTable}
            onItemClose={onItemClose}
            onItemOpen={onItemOpen}
            onPageChange={handlePageChange}
        >
            <div className={headingClasses}>{hasResolved && votingText}</div>

            {data.map(({id, securityId, status, ...rest}, index) => {
                const security = securities?.[securityId]

                return (
                    <Accordion.Item
                        {...rest}
                        disabled={orders?.status !== requestStatuses.RESOLVED}
                        key={id || index}
                        headerTemplate={ActivityItem}
                        security={security}
                        status={orders?.status}
                    >
                        <ActivityDetails security={security} {...rest} />
                    </Accordion.Item>
                )
            })}

            <div className={footerClasses} />
        </Table>
    )
}

ActivityTemplate.propTypes = {
    openedItem: PropTypes.array,
    orders: PropTypes.object,
    policy: PropTypes.object,
    portfolio: PropTypes.object,
    securities: PropTypes.object,
    onItemClose: PropTypes.func,
    onItemOpen: PropTypes.func,
    onPageChange: PropTypes.func,
}

export default ActivityTemplate
