import { ChevronDown } from '@planview/pv-icons'
import { ButtonEmpty } from '@planview/pv-uikit'
import { motion } from '@planview/pv-utilities'
import React from 'react'
import { defineMessages, useIntl } from 'react-intl'
import styled from 'styled-components'
import { calculateIndent } from '../utils/indent'
import type { GridTreeIndentSize } from '../types'

export type GridCellTreeProps = {
    children: React.ReactNode
    level: number
    expandable: boolean
    expanded: boolean
    tabIndex: number
    onContentClick: React.MouseEventHandler<HTMLDivElement>
    onExpandClick: React.MouseEventHandler<HTMLButtonElement>
    requireDoubleClick?: boolean
    treeIndentSize: GridTreeIndentSize
}

const GridCellTreeContainer = styled.div`
    width: 100%;
    height: 100%;
    display: flex;
    contain: layout;
    align-items: center;
`

const GridCellTreeContentContainer = styled.div`
    flex: 1 1 auto;
    isolation: isolate;
    position: relative;
    height: 100%;
`

const AnimatedChevron = styled(ChevronDown)<{ $open: boolean }>`
    ${(props) => motion.rotateCounterClockwise(!props.$open)}
`

const messages = defineMessages({
    expandRow: {
        id: 'pvds.grid.row.expandRow',
        defaultMessage: 'Expand row',
        description:
            'In a tree based grid, this is the label and tooltip for the button on the row',
    },
    collapseRow: {
        id: 'pvds.grid.row.collapseRow',
        defaultMessage: 'Collapse row',
        description:
            'In a tree based grid, this is the label and tooltip for the button on the row',
    },
})

export const GridCellTree: React.FC<GridCellTreeProps> = ({
    children,
    level,
    expandable,
    expanded,
    tabIndex,
    onExpandClick,
    onContentClick,
    requireDoubleClick,
    treeIndentSize,
}) => {
    const intl = useIntl()
    const handleChevronClick = React.useCallback<
        React.MouseEventHandler<HTMLButtonElement>
    >(
        (e) => {
            e.stopPropagation()
            onExpandClick(e)
        },
        [onExpandClick]
    )

    let message = ''

    if (expandable) {
        message = expanded
            ? intl.formatMessage(messages.collapseRow)
            : intl.formatMessage(messages.expandRow)
    }

    return (
        <GridCellTreeContainer
            style={{
                paddingLeft: calculateIndent(
                    level,
                    treeIndentSize,
                    !expandable
                ),
            }}
        >
            {expandable && (
                <ButtonEmpty
                    tabIndex={tabIndex}
                    icon={<AnimatedChevron $open={expanded} />}
                    onClick={handleChevronClick}
                    aria-label={message}
                    size={
                        treeIndentSize === 'small' ? 'small-compact' : 'small'
                    }
                />
            )}
            <GridCellTreeContentContainer
                onClick={requireDoubleClick ? undefined : onContentClick}
                onDoubleClick={requireDoubleClick ? onContentClick : undefined}
            >
                {children}
            </GridCellTreeContentContainer>
        </GridCellTreeContainer>
    )
}
