import React, { memo } from 'react'
import { cn } from '@/utils/cn'
import { useDominoStore, useDominoSelectionBounds } from './domino-hooks'
import { getElementWorldRect } from './math'
import type { ResizeType } from './domino'
import { icons } from '../ui/icon-mapping'

const getIconDataUri = (path: string) => {
  const content = icons[path]
  if (!content) return ''
  try {
    // Standard SVG data URI with base64 for maximum compatibility
    if (typeof window !== 'undefined') {
      return `data:image/svg+xml;base64,${window.btoa(unescape(encodeURIComponent(content)))}`
    }
  } catch (e) {
    console.error(`Failed to encode icon ${path}`, e)
  }
  return `data:image/svg+xml,${encodeURIComponent(content)}`
}

// --- Sub-components (Fine-grained Subscriptions) ---

const HoverBorder = memo(() => {
  const hoveredElementId = useDominoStore(state => state.hoveredElementId)
  const isSelected = useDominoStore(state =>
    hoveredElementId ? state.selectedIds.includes(hoveredElementId) : false,
  )
  const elements = useDominoStore(state => state.elements)
  const el = hoveredElementId ? elements[hoveredElementId] : null

  if (!el || isSelected) return null

  const worldRect = getElementWorldRect(el, elements)

  return (
    <div
      className='absolute pointer-events-none z-[98]'
      style={{
        width: worldRect.width,
        height: worldRect.height,
        transform: `translate3d(${worldRect.x}px, ${worldRect.y}px, 0) rotate(${worldRect.rotation}deg)`,
        borderWidth: 'max(0.2px, calc(1px / var(--domino-scale)))',
        borderStyle: 'solid',
        borderColor: 'var(--editor-accent)',
      }}
    />
  )
})

const FocusBorder = memo(() => {
  const focusedElementId = useDominoStore(state => state.focusedElementId)
  const isSelected = useDominoStore(state =>
    focusedElementId ? state.selectedIds.includes(focusedElementId) : false,
  )
  const elements = useDominoStore(state => state.elements)
  const el = focusedElementId ? elements[focusedElementId] : null

  if (!el || isSelected || el.type === 'text') return null

  const worldRect = getElementWorldRect(el, elements)

  return (
    <div
      className='absolute pointer-events-none z-[99]'
      style={{
        width: worldRect.width,
        height: worldRect.height,
        transform: `translate3d(${worldRect.x}px, ${worldRect.y}px, 0) rotate(${worldRect.rotation}deg)`,
        borderWidth: 'max(0.4px, calc(1.5px / var(--domino-scale)))',
        borderStyle: 'solid',
        borderColor: 'color-mix(in srgb, var(--editor-accent) 62%, transparent)',
      }}
    />
  )
})

const MultiSelectionOverlay = memo(() => {
  const selectedIds = useDominoStore(state => state.selectedIds)
  const selectionBounds = useDominoSelectionBounds()
  const readOnly = useDominoStore(state => state.readOnly)

  if (selectedIds.length <= 1 || !selectionBounds) return null

  return (
    <div
      className={cn(
        'domino-multi-select-area absolute pointer-events-auto z-[100]',
        !readOnly && 'cursor-move',
      )}
      data-multi-select='true'
      style={{
        transform: `translate3d(${selectionBounds.left}px, ${selectionBounds.top}px, 0)`,
        width: selectionBounds.width,
        height: selectionBounds.height,
        borderWidth: 'max(0.2px, calc(1px / var(--domino-scale)))',
        borderStyle: 'solid',
        borderColor: 'var(--editor-accent)',
      }}
    />
  )
})

function RotateHandles() {
  const nwRotateIcon = getIconDataUri('../../icons/nw-rotate.svg')
  const neRotateIcon = getIconDataUri('../../icons/ne-rotate.svg')
  const swRotateIcon = getIconDataUri('../../icons/sw-rotate.svg')
  const seRotateIcon = getIconDataUri('../../icons/se-rotate.svg')

  const rotateOffset = 'calc(-12px / var(--domino-scale))'
  const totalRotateSize = 'calc(22px / var(--domino-scale))'
  const rotateHandleClassName =
    'domino-rotate-handle absolute pointer-events-auto overflow-visible'

  return (
    <span>
      {/* NW (左上): 避开右下象限 */}
      <svg
        data-rotate='nw'
        className={rotateHandleClassName}
        viewBox='0 0 21 21'
        style={{
          top: rotateOffset,
          left: rotateOffset,
          width: totalRotateSize,
          height: totalRotateSize,
          cursor: `url("${nwRotateIcon}") 12 12, auto`
        }}
      >
        <path
          d='M 10.5 10.5 L 10.5 21 A 10.5 10.5 0 1 1 21 10.5 Z'
          fill='transparent'
          className='pointer-events-auto'
        />
      </svg>
      {/* NE (右上): 避开左下象限 */}
      <svg
        data-rotate='ne'
        className={rotateHandleClassName}
        viewBox='0 0 21 21'
        style={{
          top: rotateOffset,
          right: rotateOffset,
          width: totalRotateSize,
          height: totalRotateSize,
          cursor: `url("${neRotateIcon}") 12 12, auto`,
        }}
      >
        <path
          d='M 9.5 10.5 L -1 10.5 A 10.5 10.5 0 1 1 9.5 21 Z'
          fill='transparent'
          className='pointer-events-auto'
        />
      </svg>
      {/* SW (左下): 避开右上象限 */}
      <svg
        data-rotate='sw'
        className={rotateHandleClassName}
        viewBox='0 0 21 21'
        style={{
          bottom: rotateOffset,
          left: rotateOffset,
          width: totalRotateSize,
          height: totalRotateSize,
          cursor: `url("${swRotateIcon}") 12 12, auto`,
        }}
      >
        <path
          d='M 10.5 9.5 L 21 9.5 A 10.5 10.5 0 1 1 10.5 -1 Z'
          fill='transparent'
          className='pointer-events-auto'
        />
      </svg>
      {/* SE (右下): 避开左上象限 */}
      <svg
        data-rotate='se'
        className={rotateHandleClassName}
        viewBox='0 0 21 21'
        style={{
          bottom: rotateOffset,
          right: rotateOffset,
          width: totalRotateSize,
          height: totalRotateSize,
          cursor: `url("${seRotateIcon}") 12 12, auto`,
        }}
      >
        <path
          d='M 9.5 9.5 L 9.5 -1 A 10.5 10.5 0 1 1 -1 9.5 Z'
          fill='transparent'
          className='pointer-events-auto'
        />
      </svg>
    </span>
  )
}

function ResizeHandles() {
  const hitHandleSize = 'calc(14px / var(--domino-scale))'
  const hitOffset = 'calc(-7.5px / var(--domino-scale))'

  const visualHandleStyle: React.CSSProperties = {
    width: 'calc(12px / var(--domino-scale))',
    height: 'calc(12px / var(--domino-scale))',
    borderWidth: 'calc(2px / var(--domino-scale))',
    borderStyle: 'solid',
    borderRadius: '50%',
    boxShadow:
      '0 calc(1px / var(--domino-scale)) calc(3px / var(--domino-scale)) var(--editor-shadow)',
    background: 'var(--editor-surface)',
    borderColor: 'var(--editor-accent)',
  }

  const hitHandleClassName =
    'domino-resize-handle box-border absolute pointer-events-auto z-10 flex items-center justify-center rounded-50%'
  const visualHandleClassName = ''

  return (
    <>
      <div
        data-handle='nw'
        className={cn(hitHandleClassName, 'cursor-nwse-resize')}
        style={{
          width: hitHandleSize,
          height: hitHandleSize,
          top: hitOffset,
          left: hitOffset,
        }}
      >
        <div className={visualHandleClassName} style={visualHandleStyle} />
      </div>
      <div
        data-handle='ne'
        className={cn(hitHandleClassName, 'cursor-nesw-resize')}
        style={{
          width: hitHandleSize,
          height: hitHandleSize,
          top: hitOffset,
          right: hitOffset,
        }}
      >
        <div className={visualHandleClassName} style={visualHandleStyle} />
      </div>
      <div
        data-handle='sw'
        className={cn(hitHandleClassName, 'cursor-nesw-resize')}
        style={{
          width: hitHandleSize,
          height: hitHandleSize,
          bottom: hitOffset,
          left: hitOffset,
        }}
      >
        <div className={visualHandleClassName} style={visualHandleStyle} />
      </div>
      <div
        data-handle='se'
        className={cn(hitHandleClassName, 'cursor-nwse-resize')}
        style={{
          width: hitHandleSize,
          height: hitHandleSize,
          bottom: hitOffset,
          right: hitOffset,
        }}
      >
        <div className={visualHandleClassName} style={visualHandleStyle} />
      </div>
    </>
  )
}

function SideHandles({
  resize,
  width,
  height,
  scale,
}: {
  resize?: ResizeType
  width: number
  height: number
  scale: number
}) {
  if (resize === 'none') return null

  const hitHandleSize = 'calc(14px / var(--domino-scale))'
  const hitOffset = 'calc(-7.5px / var(--domino-scale))'

  const sideHandleStyle: React.CSSProperties = {
    width: 'calc(24px / var(--domino-scale))',
    height: 'calc(8px / var(--domino-scale))',
    backgroundColor: 'var(--editor-surface)',
    border: 'calc(2px / var(--domino-scale)) solid var(--editor-accent)',
    borderRadius: 999,
    boxShadow:
      '0 calc(1px / var(--domino-scale)) calc(3px / var(--domino-scale)) var(--editor-shadow)',
  }

  const sideHandleVerticalStyle: React.CSSProperties = {
    width: 'calc(8px / var(--domino-scale))',
    height: 'calc(24px / var(--domino-scale))',
    backgroundColor: 'var(--editor-surface)',
    border: 'calc(2px / var(--domino-scale)) solid var(--editor-accent)',
    borderRadius: 999,
    boxShadow:
      '0 calc(1px / var(--domino-scale)) calc(3px / var(--domino-scale)) var(--editor-shadow)',
  }

  const hitHandleClassName =
    'domino-resize-handle box-border absolute pointer-events-auto z-10 flex items-center justify-center'

  const VISUAL_THRESHOLD = 38 // 屏幕像素阈值
  const canShowVertical = width * scale > VISUAL_THRESHOLD
  const canShowHorizontal = height * scale > VISUAL_THRESHOLD

  const showVertical =
    (resize === 'both' || resize === 'vertical' || !resize) && canShowVertical
  const showHorizontal =
    (resize === 'both' || resize === 'horizontal' || !resize) &&
    canShowHorizontal

  return (
    <>
      {/* Middle Top */}
      {showVertical && (
        <div
          data-handle='mt'
          className={cn(hitHandleClassName, 'cursor-ns-resize')}
          style={{
            width: 'calc(24px / var(--domino-scale))',
            height: hitHandleSize,
            top: hitOffset,
            left: '50%',
            transform: 'translateX(-50%)',
          }}
        >
          <div style={sideHandleStyle} />
        </div>
      )}
      {/* Middle Bottom */}
      {showVertical && (
        <div
          data-handle='mb'
          className={cn(hitHandleClassName, 'cursor-ns-resize')}
          style={{
            width: 'calc(24px / var(--domino-scale))',
            height: hitHandleSize,
            bottom: hitOffset,
            left: '50%',
            transform: 'translateX(-50%)',
          }}
        >
          <div style={sideHandleStyle} />
        </div>
      )}
      {/* Middle Left */}
      {showHorizontal && (
        <div
          data-handle='ml'
          className={cn(hitHandleClassName, 'cursor-ew-resize')}
          style={{
            width: hitHandleSize,
            height: 'calc(24px / var(--domino-scale))',
            left: hitOffset,
            top: '50%',
            transform: 'translateY(-50%)',
          }}
        >
          <div style={sideHandleVerticalStyle} />
        </div>
      )}
      {/* Middle Right */}
      {showHorizontal && (
        <div
          data-handle='mr'
          className={cn(hitHandleClassName, 'cursor-ew-resize')}
          style={{
            width: hitHandleSize,
            height: 'calc(24px / var(--domino-scale))',
            right: hitOffset,
            top: '50%',
            transform: 'translateY(-50%)',
          }}
        >
          <div style={sideHandleVerticalStyle} />
        </div>
      )}
    </>
  )
}

const SingleSelectionOverlay = memo(() => {
  const selectedIds = useDominoStore(state => state.selectedIds)
  const elementId = selectedIds.length === 1 ? selectedIds[0] : null
  const elements = useDominoStore(state => state.elements)
  const el = elementId ? elements[elementId] : null
  const uiState = useDominoStore(state =>
    elementId ? state.elementUIStates[elementId] : null,
  )
  const scale = useDominoStore(state => state.viewport.scale)
  const readOnly = useDominoStore(state => state.readOnly)

  if (!el) return null

  const isLocked = readOnly || uiState?.status === 'readonly'
  const worldRect = getElementWorldRect(el, elements)

  return (
    <div
      className='absolute pointer-events-none z-[100]'
      style={{
        width: worldRect.width,
        height: worldRect.height,
        transform: `translate3d(${worldRect.x}px, ${worldRect.y}px, 0) rotate(${worldRect.rotation}deg)`,
        borderWidth: 'max(0.4px, calc(2px / var(--domino-scale)))',
        borderStyle: 'solid',
        borderColor: 'var(--editor-accent)',
      }}
    >
      {!isLocked && (
        <>
          {el.rotatable !== false && <RotateHandles />}
          {el.scalable !== false && (
            <>
              <ResizeHandles />
              {el.resize !== 'none' &&
                (el.lockAspectRatio === false || el.resize) && (
                  <SideHandles
                    resize={el.resize}
                    width={el.width}
                    height={el.height}
                    scale={scale}
                  />
                )}
            </>
          )}
        </>
      )}
    </div>
  )
})

const SnapLinesOverlay = memo(() => {
  const snapLines = useDominoStore(state => state.snapLines)

  if (!snapLines || snapLines.length === 0) return null

  return (
    <>
      {snapLines.map((line, i) => (
        <div
          key={`${line.type}-${line.value}-${i}`}
          className='absolute border-[#FF00FF] pointer-events-none z-[120]'
          style={{
            left: line.type === 'x' ? line.value : -10000,
            top: line.type === 'y' ? line.value : -10000,
            width:
              line.type === 'x' ? 'calc(1px / var(--domino-scale))' : 20000,
            height:
              line.type === 'y' ? 'calc(1px / var(--domino-scale))' : 20000,
            borderStyle: 'dashed',
            borderWidth:
              line.type === 'x'
                ? '0 0 0 calc(1px / var(--domino-scale))'
                : 'calc(1px / var(--domino-scale)) 0 0 0',
          }}
        />
      ))}
    </>
  )
})

// --- Main Component ---

export const SelectionOverlay: React.FC = memo(() => {
  return (
    <>
      <HoverBorder />
      <FocusBorder />
      <MultiSelectionOverlay />
      <SingleSelectionOverlay />
      <SnapLinesOverlay />
    </>
  )
})
SelectionOverlay.displayName = 'SelectionOverlay'
