import { memo, useCallback, useEffect, useMemo, useRef, useState, type CSSProperties, type MouseEvent as ReactMouseEvent, type MutableRefObject, type PointerEvent as ReactPointerEvent } from 'react'
import { getAssetUrlsByImport } from '@tldraw/assets/imports.vite'
import { ArrowsIn, ArrowsOut } from '@phosphor-icons/react'
import { Dialog as DialogPrimitive } from 'radix-ui'
import {
  Box,
  Tldraw,
  createTLStore,
  defaultUserPreferences,
  loadSnapshot,
  useDialogs,
  useTldrawUser,
  useValue,
  type Editor,
  type TLEventInfo,
  type TLUiDialog,
  type TLStoreSnapshot,
  type TLUserPreferences,
} from 'tldraw'
import 'tldraw/tldraw.css'
import { useDocumentThemeMode } from '../hooks/useDocumentThemeMode'
import { resolveEffectiveLocale, translate, type AppLocale } from '../lib/i18n'
import type { ResolvedThemeMode } from '../lib/themeMode'
import {
  isWhiteboardPlatformPermissionRejection,
  retainWhiteboardPlatformPermissionGuard,
} from '../utils/whiteboardPlatformPermissionRejection'
import { Button } from './ui/button'
import { ActionTooltip } from './ui/action-tooltip'
import { installTldrawTextMeasurementGuard } from './tldrawTextMeasurementGuard'

const EMPTY_TLDRAW_TRANSLATION_URL = 'data:application/json;base64,e30K'
const TOLARIA_TLDRAW_USER_ID = 'tolaria-whiteboard'
const WHITEBOARD_FULLSCREEN_BODY_CLASS = 'tldraw-whiteboard-fullscreen-open'

function resolveTldrawAssetUrl(assetUrl: string | undefined): string {
  return assetUrl ?? EMPTY_TLDRAW_TRANSLATION_URL
}

const tldrawAssetUrls = getAssetUrlsByImport(resolveTldrawAssetUrl)

interface TldrawWhiteboardProps {
  boardId: string
  height: string
  snapshot: string
  width: string
  onSnapshotChange: (snapshot: string) => void
  onSizeChange: (size: TldrawWhiteboardSize) => void
}

interface TldrawWhiteboardSize {
  height: string
  width: string
}

interface PixelSize {
  height: number
  width: number | null
}

interface ResizeStart {
  height: number
  pointerX: number
  pointerY: number
  width: number
}

type ResizeMode = 'height' | 'width' | 'both'

const DEFAULT_HEIGHT = 520
const MIN_HEIGHT = 260
const MIN_WIDTH = 360
const TLDRAW_UI_ICON_SELECTOR = '.tlui-icon'
const WEBKIT_MASK_PROPERTY = '-webkit-mask'

function parsePixelValue(value: string, fallback: number): number {
  const parsed = Number.parseInt(value, 10)
  return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback
}

function normalizeSize({ height, width }: TldrawWhiteboardSize): PixelSize {
  return {
    height: parsePixelValue(height, DEFAULT_HEIGHT),
    width: width ? parsePixelValue(width, MIN_WIDTH) : null,
  }
}

function sizeToProps({ height, width }: PixelSize): TldrawWhiteboardSize {
  return {
    height: String(Math.max(MIN_HEIGHT, Math.round(height))),
    width: width === null ? '' : String(Math.max(MIN_WIDTH, Math.round(width))),
  }
}

function cssSize({ height, width }: PixelSize): CSSProperties {
  return {
    '--tldraw-whiteboard-height': `${Math.max(MIN_HEIGHT, height)}px`,
    '--tldraw-whiteboard-width': width === null ? '100%' : `${Math.max(MIN_WIDTH, width)}px`,
  } as CSSProperties
}

function tldrawUserPreferences(themeMode: ResolvedThemeMode): TLUserPreferences {
  return {
    ...defaultUserPreferences,
    id: TOLARIA_TLDRAW_USER_ID,
    colorScheme: themeMode,
  }
}

function ignoreTldrawUserPreferencesUpdate(preferences: TLUserPreferences) {
  void preferences
}

function readDocumentLocale(): AppLocale {
  if (typeof document === 'undefined') return 'en'
  return resolveEffectiveLocale(document.documentElement.lang)
}

function useDocumentLocale(): AppLocale {
  const [locale, setLocale] = useState(readDocumentLocale)

  useEffect(() => {
    if (typeof document === 'undefined') return

    const syncLocale = () => setLocale(readDocumentLocale())
    const observer = new MutationObserver(syncLocale)
    observer.observe(document.documentElement, { attributeFilter: ['lang'], attributes: true })
    syncLocale()

    return () => observer.disconnect()
  }, [])

  return locale
}

interface WhiteboardRuntimeGuardOptions {
  onPlatformPermissionDenied: () => void
}

function installTldrawPlatformPermissionGuard({ onPlatformPermissionDenied }: WhiteboardRuntimeGuardOptions): () => void {
  const releaseWhiteboardPermissionGuard = retainWhiteboardPlatformPermissionGuard()
  const handleUnhandledRejection = (event: PromiseRejectionEvent) => {
    if (!isWhiteboardPlatformPermissionRejection(event.reason)) return
    event.preventDefault()
    onPlatformPermissionDenied()
  }

  // Sentry installs its global rejection handler during app startup, before tldraw mounts.
  window.addEventListener('unhandledrejection', handleUnhandledRejection, true)
  return () => {
    window.removeEventListener('unhandledrejection', handleUnhandledRejection, true)
    releaseWhiteboardPermissionGuard()
  }
}

function parseSnapshot(source: string): TLStoreSnapshot | null {
  if (!source.trim()) return null

  try {
    return JSON.parse(source) as TLStoreSnapshot
  } catch {
    return null
  }
}

function createBoardStore(boardId: string) {
  void boardId
  return createTLStore({ onMount: installTldrawTextMeasurementGuard })
}

function serializeSnapshot(snapshot: TLStoreSnapshot): string {
  return `${JSON.stringify(snapshot, null, 2)}\n`
}

function getDocumentSnapshot(store: ReturnType<typeof createTLStore>): TLStoreSnapshot {
  return store.getStoreSnapshot()
}

function documentZoom(): number {
  const inlineZoom = document.documentElement.style.getPropertyValue('zoom')
  const computedZoom = getComputedStyle(document.documentElement).zoom
  const zoom = inlineZoom || computedZoom
  const parsed = Number.parseFloat(zoom)
  if (!Number.isFinite(parsed) || parsed <= 0) return 1
  return zoom.endsWith('%') ? parsed / 100 : parsed
}

function viewportBounds(screenBounds: Box | HTMLElement): Box | HTMLElement {
  if (screenBounds instanceof Box) return screenBounds

  const zoom = documentZoom()
  if (zoom === 1) return screenBounds

  const rect = screenBounds.getBoundingClientRect()
  return new Box(
    (rect.left || rect.x) / zoom,
    (rect.top || rect.y) / zoom,
    Math.max(rect.width / zoom, 1),
    Math.max(rect.height / zoom, 1),
  )
}

function zoomAdjustedPoint<T extends { x: number; y: number; z?: number }>(point: T, zoom: number): T {
  return {
    ...point,
    x: point.x / zoom,
    y: point.y / zoom,
  }
}

function zoomAdjustedEvent(info: TLEventInfo): TLEventInfo {
  const zoom = documentZoom()
  if (zoom === 1) return info

  switch (info.type) {
    case 'click':
    case 'pinch':
    case 'pointer':
    case 'wheel':
      return {
        ...info,
        point: zoomAdjustedPoint(info.point, zoom),
      } as TLEventInfo
    default:
      return info
  }
}

function installZoomAwareViewport(editor: Editor): () => void {
  const updateViewportScreenBounds = editor.updateViewportScreenBounds.bind(editor)
  const updateViewport: Editor['updateViewportScreenBounds'] = (screenBounds, center) =>
    updateViewportScreenBounds(viewportBounds(screenBounds), center)
  const dispatch = editor.dispatch.bind(editor)
  const animationFrameIds: number[] = []
  const timeoutIds: number[] = []

  editor.updateViewportScreenBounds = updateViewport
  editor.dispatch = (info: TLEventInfo) => dispatch(zoomAdjustedEvent(info))

  const updateCurrentCanvas = () => {
    const canvas = editor.getContainer().querySelector<HTMLElement>('.tl-canvas')
    if (canvas) updateViewport(canvas)
  }

  const scheduleViewportUpdate = () => {
    updateCurrentCanvas()
    animationFrameIds.push(window.requestAnimationFrame(updateCurrentCanvas))
    timeoutIds.push(window.setTimeout(updateCurrentCanvas, 150))
  }

  scheduleViewportUpdate()
  window.addEventListener('laputa-zoom-change', scheduleViewportUpdate)

  return () => {
    window.removeEventListener('laputa-zoom-change', scheduleViewportUpdate)
    animationFrameIds.forEach((id) => {
      window.cancelAnimationFrame(id)
    })
    timeoutIds.forEach((id) => {
      window.clearTimeout(id)
    })
    editor.updateViewportScreenBounds = updateViewportScreenBounds
    editor.dispatch = dispatch
  }
}

function syncTldrawIconWebkitMask(icon: HTMLElement): void {
  const mask = icon.style.getPropertyValue('mask').trim()
  if (!mask) {
    icon.style.removeProperty(WEBKIT_MASK_PROPERTY)
    return
  }

  if (icon.style.getPropertyValue(WEBKIT_MASK_PROPERTY).trim() === mask) return
  icon.style.setProperty(WEBKIT_MASK_PROPERTY, mask)
}

function syncTldrawIconWebkitMasks(root: HTMLElement): void {
  if (root.matches(TLDRAW_UI_ICON_SELECTOR)) {
    syncTldrawIconWebkitMask(root)
  }

  for (const icon of root.querySelectorAll<HTMLElement>(TLDRAW_UI_ICON_SELECTOR)) {
    syncTldrawIconWebkitMask(icon)
  }
}

function syncAddedTldrawIconMasks(node: Node): void {
  if (!(node instanceof HTMLElement)) return
  syncTldrawIconWebkitMasks(node)
}

function installTldrawWebkitIconMaskBridge(container: HTMLElement): () => void {
  syncTldrawIconWebkitMasks(container)

  const observer = new MutationObserver((mutations) => {
    for (const mutation of mutations) {
      if (mutation.type === 'attributes' && mutation.target instanceof HTMLElement) {
        syncTldrawIconWebkitMasks(mutation.target)
        continue
      }

      mutation.addedNodes.forEach(syncAddedTldrawIconMasks)
    }
  })

  observer.observe(container, {
    attributeFilter: ['class', 'style'],
    attributes: true,
    childList: true,
    subtree: true,
  })

  return () => {
    observer.disconnect()
  }
}

function installWhiteboardRuntimeGuards(editor: Editor, options: WhiteboardRuntimeGuardOptions): () => void {
  const cleanupZoomAwareViewport = installZoomAwareViewport(editor)
  const cleanupWebkitIconMaskBridge = installTldrawWebkitIconMaskBridge(editor.getContainer())
  const cleanupPlatformPermissionGuard = installTldrawPlatformPermissionGuard(options)

  return () => {
    cleanupPlatformPermissionGuard()
    cleanupWebkitIconMaskBridge()
    cleanupZoomAwareViewport()
  }
}

interface TolariaTldrawDialogProps {
  dialog: TLUiDialog
  onClose: (id: string) => void
}

const DIALOG_OPEN_DISMISS_GRACE_MS = 250
let retainedTolariaTldrawDialogs: TLUiDialog[] = []

function useDeferredDialogOpen() {
  const openedAtRef = useRef(0)
  const [readyToOpen, setReadyToOpen] = useState(false)

  useEffect(() => {
    const animationFrameId = window.requestAnimationFrame(() => {
      openedAtRef.current = performance.now()
      setReadyToOpen(true)
    })
    return () => { window.cancelAnimationFrame(animationFrameId) }
  }, [])

  return { openedAtRef, readyToOpen }
}

function canDismissDialog(openedAt: number): boolean {
  return performance.now() - openedAt >= DIALOG_OPEN_DISMISS_GRACE_MS
}

function isOverlayEvent(event: { currentTarget: EventTarget | null; target: EventTarget | null }): boolean {
  return event.target === event.currentTarget
}

function shouldCloseFromOverlayClick(
  event: { currentTarget: EventTarget | null; target: EventTarget | null },
  dialog: TLUiDialog,
  mouseDownInsideContent: boolean
): boolean {
  return isOverlayEvent(event) && !dialog.preventBackgroundClose && !mouseDownInsideContent
}

interface TolariaTldrawDialogContentProps {
  dialog: TLUiDialog
  mouseDownInsideContentRef: MutableRefObject<boolean>
  onClose: () => void
}

function TolariaTldrawDialogContent({
  dialog,
  mouseDownInsideContentRef,
  onClose,
}: TolariaTldrawDialogContentProps) {
  const ModalContent = dialog.component
  const handleClose = () => {
    mouseDownInsideContentRef.current = false
    onClose()
  }

  return (
    <div
      dir="ltr"
      className="tlui-dialog__content"
      aria-describedby={undefined}
      role="dialog"
      onKeyDown={(event) => {
        if (event.key !== 'Escape') return
        event.preventDefault()
        mouseDownInsideContentRef.current = false
        onClose()
      }}
      onMouseDown={() => { mouseDownInsideContentRef.current = true }}
      onMouseUp={() => { mouseDownInsideContentRef.current = false }}
    >
      <ModalContent onClose={handleClose} />
    </div>
  )
}

const TolariaTldrawDialog = memo(function TolariaTldrawDialog({ dialog, onClose }: TolariaTldrawDialogProps) {
  const overlayRef = useRef<HTMLDivElement>(null)
  const mouseDownInsideContentRef = useRef(false)
  const { openedAtRef, readyToOpen } = useDeferredDialogOpen()

  const closeDialogFromBackground = useCallback(() => {
    if (!canDismissDialog(openedAtRef.current)) return
    onClose(dialog.id)
  }, [dialog.id, onClose, openedAtRef])
  const closeDialogNow = useCallback(() => { onClose(dialog.id) }, [dialog.id, onClose])
  const handleOpenChange = useCallback((isOpen: boolean) => {
    if (!isOpen) closeDialogNow()
  }, [closeDialogNow])
  useEffect(() => {
    const overlay = overlayRef.current
    if (!overlay) return

    const handleMouseDown = (event: MouseEvent) => {
      if (event.target === overlay) mouseDownInsideContentRef.current = false
    }
    const handleClick = (event: MouseEvent) => {
      if (shouldCloseFromOverlayClick({ currentTarget: overlay, target: event.target }, dialog, mouseDownInsideContentRef.current)) {
        closeDialogFromBackground()
      }
    }

    overlay.addEventListener('mousedown', handleMouseDown)
    overlay.addEventListener('click', handleClick)
    return () => {
      overlay.removeEventListener('mousedown', handleMouseDown)
      overlay.removeEventListener('click', handleClick)
    }
  }, [closeDialogFromBackground, dialog])

  if (!readyToOpen) return null

  return (
    <DialogPrimitive.Root open onOpenChange={handleOpenChange}>
      <div
        ref={overlayRef}
        dir="ltr"
        className="tlui-dialog__overlay"
      >
        <TolariaTldrawDialogContent
          dialog={dialog}
          mouseDownInsideContentRef={mouseDownInsideContentRef}
          onClose={closeDialogNow}
        />
      </div>
    </DialogPrimitive.Root>
  )
})

function TolariaTldrawDialogs() {
  const { dialogs, removeDialog } = useDialogs()
  const requestedDialogs = useValue('tolaria tldraw dialogs', () => dialogs.get(), [dialogs])
  const [visibleDialogs, setVisibleDialogs] = useState<TLUiDialog[]>(() =>
    retainedTolariaTldrawDialogs.length > 0 ? retainedTolariaTldrawDialogs : dialogs.get()
  )

  const closeVisibleDialog = useCallback((id: string) => {
    const nextDialogs = retainedTolariaTldrawDialogs.filter((dialog) => dialog.id !== id)
    retainedTolariaTldrawDialogs = nextDialogs
    setVisibleDialogs(nextDialogs)
    removeDialog(id)
  }, [removeDialog])

  useEffect(() => {
    if (requestedDialogs.length === 0) return
    // tldraw clears the dialog atom while Radix closes the menu; keep the last requested dialog mounted locally.
    retainedTolariaTldrawDialogs = requestedDialogs
    queueMicrotask(() => {
      setVisibleDialogs(requestedDialogs)
    })
  }, [requestedDialogs])

  return visibleDialogs.map((dialog) => (
    <TolariaTldrawDialog
      key={dialog.id}
      dialog={dialog}
      onClose={closeVisibleDialog}
    />
  ))
}

function useFullscreenWhiteboard() {
  const [fullscreen, setFullscreen] = useState(false)

  useEffect(() => {
    if (!fullscreen) return

    const handleKeyDown = (event: KeyboardEvent) => {
      if (event.key === 'Escape') setFullscreen(false)
    }
    document.body.classList.add(WHITEBOARD_FULLSCREEN_BODY_CLASS)
    window.addEventListener('keydown', handleKeyDown)

    return () => {
      document.body.classList.remove(WHITEBOARD_FULLSCREEN_BODY_CLASS)
      window.removeEventListener('keydown', handleKeyDown)
    }
  }, [fullscreen])

  useEffect(() => {
    const animationFrameId = window.requestAnimationFrame(() => {
      window.dispatchEvent(new Event('resize'))
    })
    return () => { window.cancelAnimationFrame(animationFrameId) }
  }, [fullscreen])

  const toggleFullscreen = useCallback((event: ReactMouseEvent<HTMLButtonElement>) => {
    event.preventDefault()
    event.stopPropagation()
    setFullscreen((current) => !current)
  }, [])

  return { fullscreen, toggleFullscreen }
}

export function TldrawWhiteboard({
  boardId,
  height,
  snapshot,
  width,
  onSnapshotChange,
  onSizeChange,
}: TldrawWhiteboardProps) {
  const store = useMemo(() => createBoardStore(boardId), [boardId])
  const boardRef = useRef<HTMLDivElement | null>(null)
  const savedSnapshotRef = useRef<string | null>(null)
  const savedBoardIdRef = useRef<string | null>(null)
  const onSnapshotChangeRef = useRef(onSnapshotChange)
  const persistedSize = useMemo(() => normalizeSize({ height, width }), [height, width])
  const [resizingSize, setResizingSize] = useState<PixelSize | null>(null)
  const [permissionDeniedBoardId, setPermissionDeniedBoardId] = useState<string | null>(null)
  const platformPermissionDenied = permissionDeniedBoardId === boardId
  const visibleSize = resizingSize ?? persistedSize
  const { fullscreen, toggleFullscreen } = useFullscreenWhiteboard()
  const locale = useDocumentLocale()
  const fullscreenLabel = translate(
    locale,
    fullscreen ? 'editor.whiteboard.exitFullscreen' : 'editor.whiteboard.enterFullscreen',
  )
  const themeMode = useDocumentThemeMode()
  const userPreferences = useMemo(() => tldrawUserPreferences(themeMode), [themeMode])
  const tldrawUser = useTldrawUser({
    setUserPreferences: ignoreTldrawUserPreferencesUpdate,
    userPreferences,
  })
  const tldrawUiComponents = useMemo(() => ({ Dialogs: TolariaTldrawDialogs }), [])
  const handleTldrawMount = useCallback((editor: Editor) =>
    installWhiteboardRuntimeGuards(editor, {
      onPlatformPermissionDenied: () => { setPermissionDeniedBoardId(boardId) },
    }), [boardId])

  useEffect(() => {
    onSnapshotChangeRef.current = onSnapshotChange
  }, [onSnapshotChange])

  useEffect(() => {
    if (boardId === savedBoardIdRef.current && snapshot === savedSnapshotRef.current) return

    const parsed = parseSnapshot(snapshot)
    if (parsed) {
      try {
        loadSnapshot(store, parsed)
        savedBoardIdRef.current = boardId
        savedSnapshotRef.current = snapshot
        return
      } catch {
        // Fall through to an empty board when legacy or hand-edited JSON is invalid.
      }
    }

    const emptySnapshot = getDocumentSnapshot(createTLStore())
    loadSnapshot(store, emptySnapshot)
    savedBoardIdRef.current = boardId
    savedSnapshotRef.current = serializeSnapshot(emptySnapshot)
  }, [boardId, snapshot, store])

  useEffect(() => {
    let timeoutId: number | null = null

    const flushSnapshot = () => {
      timeoutId = null
      const nextSnapshot = serializeSnapshot(getDocumentSnapshot(store))
      if (nextSnapshot === savedSnapshotRef.current) return

      savedBoardIdRef.current = boardId
      savedSnapshotRef.current = nextSnapshot
      onSnapshotChangeRef.current(nextSnapshot)
    }

    const scheduleSnapshotFlush = () => {
      if (timeoutId !== null) window.clearTimeout(timeoutId)
      timeoutId = window.setTimeout(flushSnapshot, 350)
    }

    const cleanup = store.listen(scheduleSnapshotFlush, { source: 'user', scope: 'document' })
    return () => {
      cleanup()
      if (timeoutId !== null) window.clearTimeout(timeoutId)
    }
  }, [boardId, store])

  const startResize = (mode: ResizeMode) => (event: ReactPointerEvent<HTMLButtonElement>) => {
    event.preventDefault()
    event.stopPropagation()

    const rect = boardRef.current?.getBoundingClientRect()
    const start: ResizeStart = {
      height: visibleSize.height,
      pointerX: event.clientX,
      pointerY: event.clientY,
      width: visibleSize.width ?? rect?.width ?? MIN_WIDTH,
    }

    const onPointerMove = (moveEvent: PointerEvent) => {
      const nextSize = {
        height: mode === 'width' ? start.height : start.height + moveEvent.clientY - start.pointerY,
        width: mode === 'height' ? visibleSize.width : start.width + moveEvent.clientX - start.pointerX,
      }
      setResizingSize(normalizeSize(sizeToProps(nextSize)))
    }

    const onPointerUp = (upEvent: PointerEvent) => {
      window.removeEventListener('pointermove', onPointerMove)
      window.removeEventListener('pointerup', onPointerUp)

      const finalSize = {
        height: mode === 'width' ? start.height : start.height + upEvent.clientY - start.pointerY,
        width: mode === 'height' ? visibleSize.width : start.width + upEvent.clientX - start.pointerX,
      }
      const nextProps = sizeToProps(normalizeSize(sizeToProps(finalSize)))
      setResizingSize(null)
      onSizeChange(nextProps)
    }

    window.addEventListener('pointermove', onPointerMove)
    window.addEventListener('pointerup', onPointerUp, { once: true })
  }

  return (
    <div
      ref={boardRef}
      className={fullscreen ? 'tldraw-whiteboard tldraw-whiteboard--fullscreen' : 'tldraw-whiteboard'}
      contentEditable={false}
      data-board-id={boardId}
      style={cssSize(visibleSize)}
    >
      <Tldraw
        assetUrls={tldrawAssetUrls}
        components={tldrawUiComponents}
        key={boardId}
        onMount={handleTldrawMount}
        store={store}
        user={tldrawUser}
      />
      {platformPermissionDenied ? (
        <div
          role="alert"
          className="tldraw-whiteboard__permission-error"
          data-testid="tldraw-whiteboard-permission-error"
        >
          <strong>{translate(locale, 'editor.whiteboard.permissionDeniedTitle')}</strong>
          <span>{translate(locale, 'editor.whiteboard.permissionDeniedBody')}</span>
        </div>
      ) : null}
      <ActionTooltip copy={{ label: fullscreenLabel }} side="left">
        <Button
          type="button"
          variant="outline"
          size="icon-xs"
          aria-label={fullscreenLabel}
          aria-pressed={fullscreen}
          className="tldraw-whiteboard__fullscreen-button"
          data-testid="tldraw-whiteboard-fullscreen-toggle"
          title={fullscreenLabel}
          onClick={toggleFullscreen}
        >
          {fullscreen ? <ArrowsIn aria-hidden="true" /> : <ArrowsOut aria-hidden="true" />}
        </Button>
      </ActionTooltip>
      <button
        type="button"
        aria-label="Resize whiteboard width"
        className="tldraw-whiteboard__resize-handle tldraw-whiteboard__resize-handle--width border-0 bg-transparent p-0"
        onPointerDown={startResize('width')}
      />
      <button
        type="button"
        aria-label="Resize whiteboard height"
        className="tldraw-whiteboard__resize-handle tldraw-whiteboard__resize-handle--height border-0 bg-transparent p-0"
        onPointerDown={startResize('height')}
      />
      <button
        type="button"
        aria-label="Resize whiteboard"
        className="tldraw-whiteboard__resize-handle tldraw-whiteboard__resize-handle--corner border-0 bg-transparent p-0"
        onPointerDown={startResize('both')}
      />
    </div>
  )
}
