import type { PointerEvent as ReactPointerEvent, ReactNode } from 'react'
import { useMemo, useRef, useState } from 'react'
import {
    Sheet,
    SheetContent,
    SheetDescription,
    SheetHeader,
    SheetTitle,
} from '../../../../../../packages/ui-shadcn/components/ui/sheet'
import { cn } from '../../../../../../packages/ui-shadcn/lib/utils'

type ResizableDrawerProps = {
    open: boolean
    onOpenChange: (open: boolean) => void
    title?: string
    description?: string
    children?: ReactNode
    side?: 'right' | 'left' | 'top' | 'bottom'
    className?: string
    defaultWidth?: number
    minWidth?: number
    maxWidth?: number
    resizable?: boolean
}

export function ResizableDrawer({
    open,
    onOpenChange,
    title,
    description,
    children,
    side = 'right',
    className,
    defaultWidth = 560,
    minWidth = 420,
    maxWidth = 980,
    resizable = true,
}: ResizableDrawerProps) {
    const [width, setWidth] = useState(defaultWidth)
    const [isResizing, setIsResizing] = useState(false)
    const pointerIdRef = useRef<number | null>(null)

    const handleOpenChange = (nextOpen: boolean) => {
        if (!nextOpen) {
            setIsResizing(false)
            pointerIdRef.current = null
        }

        onOpenChange(nextOpen)
    }

    const computedMaxWidth = useMemo(() => {
        if (typeof window === 'undefined') {
            return maxWidth
        }

        return Math.min(maxWidth, Math.floor(window.innerWidth * 0.92))
    }, [maxWidth])

    const effectiveMinWidth = Math.min(minWidth, computedMaxWidth)

    const handleResizeStart = (event: ReactPointerEvent<HTMLButtonElement>) => {
        if (!resizable || (side !== 'right' && side !== 'left')) {
            return
        }

        if (typeof window === 'undefined') {
            return
        }

        if (window.innerWidth < 768) {
            return
        }

        event.preventDefault()
        event.stopPropagation()
        pointerIdRef.current = event.pointerId
        setIsResizing(true)

        const onPointerMove = (moveEvent: PointerEvent) => {
            if (pointerIdRef.current !== null && moveEvent.pointerId !== pointerIdRef.current) {
                return
            }

            const nextRaw = side === 'right' ? window.innerWidth - moveEvent.clientX : moveEvent.clientX
            const nextWidth = Math.max(effectiveMinWidth, Math.min(computedMaxWidth, nextRaw))
            setWidth(nextWidth)
        }

        const onPointerUp = (upEvent: PointerEvent) => {
            if (pointerIdRef.current !== null && upEvent.pointerId !== pointerIdRef.current) {
                return
            }

            setIsResizing(false)
            pointerIdRef.current = null
            document.body.style.userSelect = ''
            window.removeEventListener('pointermove', onPointerMove)
            window.removeEventListener('pointerup', onPointerUp)
        }

        document.body.style.userSelect = 'none'
        window.addEventListener('pointermove', onPointerMove)
        window.addEventListener('pointerup', onPointerUp)
    }

    const isHorizontalDrawer = side === 'right' || side === 'left'

    return (
        <Sheet open={open} onOpenChange={handleOpenChange}>
            <SheetContent
                side={side}
                className={cn(
                    'gap-0 border-border bg-white p-0 shadow-2xl',
                    isHorizontalDrawer && 'w-[92vw] max-w-none sm:w-auto sm:max-w-none',
                    className
                )}
                style={
                    isHorizontalDrawer
                        ? { width: `${Math.max(effectiveMinWidth, Math.min(width, computedMaxWidth))}px` }
                        : undefined
                }
            >
                {resizable && isHorizontalDrawer && (
                    <button
                        type="button"
                        aria-label="Resize drawer"
                        onPointerDown={handleResizeStart}
                        className={cn(
                            'absolute top-0 z-20 h-full w-2 cursor-col-resize border-l border-border/70 bg-transparent transition-colors hover:bg-primary/20',
                            side === 'right' ? 'left-0' : 'right-0',
                            isResizing && 'bg-primary/30'
                        )}
                    />
                )}
                {(title || description) && (
                    <SheetHeader className="border-b border-border/80 bg-white px-6 pb-4 pt-5">
                        {title && <SheetTitle className="text-2xl tracking-tight">{title}</SheetTitle>}
                        {description && (
                            <SheetDescription className="text-sm">{description}</SheetDescription>
                        )}
                    </SheetHeader>
                )}
                <div className="min-h-0 flex-1 overflow-y-auto bg-white px-5 py-5 sm:px-6">{children}</div>
            </SheetContent>
        </Sheet>
    )
}
