import React from 'react'
import { Counter, PopoverView } from '@planview/pv-uikit'
import { useGridContext, useGridSelector } from '../context/grid-context'
import styled from 'styled-components'
import { GrabDotsVertical } from '@planview/pv-icons'
import {
    borderRadius,
    theme,
    cursor,
    iconSizes,
    shadow,
    spacing,
    spacingPx,
    text,
} from '@planview/pv-utilities'
import { GridCellDefault } from '../components'
import { EmptySubNavigationContext } from '../context/grid-sub-navigation-context'

const StyledGrabDots = styled(GrabDotsVertical)`
    position: absolute;
    left: -5px;
    top: 50%;
    margin-top: -8px;
`

const StyledPopover = styled(PopoverView)`
    margin: 0;
    position: absolute;
    min-width: 200px;
    z-index: 2;
`

const PopoverContent = styled.div`
    color: ${theme.textError};
`

const DragOverlayContainer = styled.div<{ $shadowSize: 'small' | 'regular' }>`
    ${borderRadius.small};
    background-color: ${theme.backgroundNeutral0};
    ${(props) => shadow[props.$shadowSize]};
    display: flex;
    ${text.regular};
    padding-left: ${spacingPx.small};
    width: 200px;
    align-items: center;
    ${cursor.grabbing};
`

export const GridDragOverlay = () => {
    const grid = useGridContext()

    const draggingActive = useGridSelector(grid.selectors.selectDragIsActive)
    const draggingRowIds = useGridSelector(grid.selectors.selectDraggingRowIds)
    const rowHeight = useGridSelector(grid.selectors.selectRowHeight)
    const errorMessage = useGridSelector(grid.selectors.selectDragMessage)

    const previewColumnId = useGridSelector(
        grid.selectors.selectPreviewColumnId
    )
    const columnAll = useGridSelector((state) =>
        previewColumnId
            ? grid.selectors.selectColumn(state, previewColumnId)
            : null
    )

    const { actualWidth: originalWidth, data: column } = columnAll || {
        actualWidth: 200,
        data: {},
    }

    const actualWidth = Math.min(originalWidth, 250)

    const count = draggingRowIds.size
    const multiple = count > 1

    const id = [...draggingRowIds][0]
    const rowData = useGridSelector((state) =>
        id ? grid.selectors.selectRow(state, id) : null
    )
    const rowMeta = useGridSelector((state) =>
        id ? grid.selectors.selectRowMeta(state, id) : undefined
    )

    if (!draggingActive || !previewColumnId) {
        return null
    }

    const value = column.cell?.value
        ? column.cell.value({
              columnId: previewColumnId,
              row: rowData,
              rowMeta: rowMeta as any,
          })
        : rowData?.[previewColumnId]

    const label = column.cell?.label
        ? column.cell?.label({
              columnId: previewColumnId,
              row: rowData,
              rowMeta: rowMeta as any,
              value,
          })
        : value == null
          ? ''
          : value.toString()

    return (
        <div
            style={{
                position: 'relative',
                width: actualWidth,
                height: rowHeight,
                overflow: 'visible',
            }}
            data-testid="pvds-grid-drag-overlay"
        >
            {multiple && (
                <Counter
                    count={count}
                    style={{
                        position: 'absolute',
                        zIndex: 3,
                        top: -5,
                        right: -8,
                    }}
                />
            )}
            <DragOverlayContainer
                $shadowSize={multiple ? 'small' : 'regular'}
                style={{
                    height: rowHeight,
                    zIndex: 2,
                    position: 'relative',
                    width: actualWidth,
                }}
            >
                <StyledGrabDots size={iconSizes.medium} />
                {column?.cell?.Renderer ? (
                    <EmptySubNavigationContext>
                        <column.cell.Renderer
                            {...{
                                rowId: id,
                                columnId: 'name',
                                value,
                                label,
                                tabIndex: -1,
                            }}
                        />
                    </EmptySubNavigationContext>
                ) : (
                    <GridCellDefault tabIndex={-1} label={label} />
                )}
            </DragOverlayContainer>
            {multiple && (
                <DragOverlayContainer
                    $shadowSize="regular"
                    style={{
                        height: rowHeight,
                        zIndex: 1,
                        position: 'absolute',
                        left: spacing.xsmall,
                        top: spacing.xsmall,
                        width: actualWidth,
                    }}
                />
            )}
            {errorMessage && (
                <StyledPopover
                    style={{
                        top:
                            rowHeight +
                            spacing.xsmall +
                            (multiple ? spacing.xsmall : 0),
                    }}
                    show
                    content={<PopoverContent>{errorMessage}</PopoverContent>}
                />
            )}
        </div>
    )
}
