import { ButtonEmpty, Tooltip } from '@planview/pv-uikit'
import React from 'react'
import { defineMessages, useIntl } from 'react-intl'
import { useGridContext, useGridSelector } from '../context/grid-context'
import { CollapseRows, ExpandRows } from '@planview/pv-icons'
import { sizePx } from '@planview/pv-utilities'
import styled from 'styled-components'

export type GridHeaderCellExpandProps = {
    tabIndex: number
    collapseOnly?: boolean
}

const messages = defineMessages({
    expandRows: {
        id: 'pvds.grid.header.expandRows',
        defaultMessage: 'Expand all rows',
        description:
            'In a tree based grid, this is the label and tooltip for the button in the header',
    },
    collapseRows: {
        id: 'pvds.grid.header.collapseRows',
        defaultMessage: 'Collapse all rows',
        description:
            'In a tree based grid, this is the label and tooltip for the button in the header',
    },
})

const ThinButtonEmpty = styled(ButtonEmpty)`
    width: ${sizePx.smallCompact};
    min-width: ${sizePx.smallCompact};

    & > div:first-child {
        position: relative;
        left: -5px;
    }
`

export const GridHeaderCellExpand: React.FC<GridHeaderCellExpandProps> = ({
    tabIndex,
    collapseOnly,
}) => {
    const intl = useIntl()
    const { selectors, api } = useGridContext()

    const treeIndentSize = useGridSelector(selectors.selectTreeIndentSize)
    const expandedState = useGridSelector((state) =>
        selectors.selectExpandedState(state)
    )
    const text =
        expandedState === 'all' || collapseOnly
            ? intl.formatMessage(messages.collapseRows)
            : intl.formatMessage(messages.expandRows)

    const handlePointerDown = React.useCallback<
        React.PointerEventHandler<HTMLButtonElement>
    >((e) => {
        e.stopPropagation()
    }, [])

    const disabled = collapseOnly && expandedState === 'none'

    const handleKeyDown = React.useCallback<
        React.KeyboardEventHandler<HTMLElement>
    >(
        (e) => {
            if (e.key === 'Enter' || e.key === ' ') {
                e.stopPropagation()
                if (disabled) {
                    e.preventDefault()
                }
            }
        },
        [disabled]
    )

    const handleClick = React.useCallback<
        React.MouseEventHandler<HTMLButtonElement>
    >(
        (e) => {
            e.stopPropagation()
            if (expandedState === 'all' || collapseOnly) {
                api.tree.collapseAll()
            } else {
                api.tree.expandAll()
            }
        },
        [api, expandedState, collapseOnly]
    )

    const ButtonComp =
        treeIndentSize === 'small' ? ThinButtonEmpty : ButtonEmpty

    return (
        <Tooltip onKeyDown={handleKeyDown} text={text}>
            <ButtonComp
                icon={
                    expandedState === 'all' || collapseOnly ? (
                        <CollapseRows />
                    ) : (
                        <ExpandRows />
                    )
                }
                disabled={disabled}
                aria-label={text}
                tabIndex={tabIndex}
                onPointerDown={handlePointerDown}
                onClick={handleClick}
            />
        </Tooltip>
    )
}
