import React from 'react'
import type { GridRowId } from '../../types'
import { useGridContext, useGridSelector } from '../../context/grid-context'
import { theme } from '@planview/pv-utilities'
import styled from 'styled-components'
import { calculateIndent } from '../../utils/indent'

const DraggingBox = styled.div<{ $error: boolean }>`
    box-sizing: border-box;
    pointer-events: none;
    background-color: transparent;
    position: absolute;
    left: 0;
    right: 0;
    display: block;
    z-index: 2;
    border: solid 2px
        ${(props) => (props.$error ? theme.borderError : theme.borderActive)};
`

export type GridDragBoxIndicatorProps = {
    overId: null | GridRowId
    width: number
}

export const GridDragBoxIndicator: React.FC<GridDragBoxIndicatorProps> = ({
    overId,
    width,
}) => {
    const grid = useGridContext()

    const isDropAllowed = useGridSelector(grid.selectors.selectDropIsAllowed)
    const message = useGridSelector(grid.selectors.selectDragMessage)
    const rowIds = useGridSelector(grid.selectors.selectRowIds)
    const rowHeight = useGridSelector(grid.selectors.selectRowHeight)
    const treeIndentSize = useGridSelector(grid.selectors.selectTreeIndentSize)
    const isTreeGrid = useGridSelector(grid.selectors.selectIsTreeGrid)
    const previewLeftOffset = useGridSelector(
        grid.selectors.selectPreviewLeftOffset
    )

    const startIndex = overId == null ? 0 : rowIds.indexOf(overId)
    const level = useGridSelector((state) =>
        overId == null ? -1 : grid.selectors.selectRowLevel(state, overId)
    )
    const endIndex = useGridSelector((state) => {
        if (level === -1 && overId) {
            return startIndex
        }

        let internalEndIndex = startIndex
        for (let index = startIndex + 1; index < rowIds.length; index++) {
            const nextLevel = grid.selectors.selectRowLevel(
                state,
                rowIds[index]
            )
            if (nextLevel > level) {
                internalEndIndex++
            } else {
                break
            }
        }
        return internalEndIndex
    })

    const headerHeight = useGridSelector(grid.selectors.selectHeaderHeight)
    const offset = startIndex * rowHeight - 1

    const leftOffset = isTreeGrid
        ? calculateIndent(level, treeIndentSize, true)
        : 0

    if (!isDropAllowed && !message) {
        return null
    }

    return (
        <DraggingBox
            data-testid="pvds-grid-drop-indicator"
            $error={isDropAllowed === false}
            style={{
                top: Math.max(headerHeight + offset, headerHeight),
                left: previewLeftOffset + leftOffset,
                width: `calc(max(100%,${width}px) - ${
                    previewLeftOffset + leftOffset
                }px)`,
                height: rowHeight * (endIndex - startIndex + 1),
            }}
        />
    )
}
