import React from 'react'
import {
  cloneElement,
  isValidElement,
  ReactNode,
  useRef,
} from 'react'

import styled from 'styled-components'
import { useResizeObserver } from 'usehooks-ts'
import { ConnectorSpecs, ShapeStyle } from './types'


interface BaseAnnotation {
  pos: {
    x: number
    y: number
  }
  id?: string
}

interface CustomAnnotation extends BaseAnnotation {
  type: 'custom'
  content: React.ReactNode
  className?: string
  style?: React.CSSProperties
  width?: number
  height?: number
}

interface StandardAnnotation extends BaseAnnotation {
  type?: never
  content: React.ReactNode
}

export type Annotation = CustomAnnotation | StandardAnnotation





  
export interface AnnotatedImageProps {
  children: ReactNode
  annotations: Array<Annotation>
  className?: string
  shapeStyle?: ShapeStyle
  
  connectorStyle?: ConnectorSpecs
}

const isDev = window.location.hostname === 'localhost'

export const AnnotatedContent = ({
  children,
  annotations = [],
  className = '',
  connectorStyle,
  shapeStyle = {},
}: AnnotatedImageProps) => {
  const ref = useRef<HTMLDivElement>(null)
  const { width = 0, height = 0 } = useResizeObserver({
    ref,
    box: 'border-box',
  })
  const validateAnnotation = (annotation: Annotation): boolean => {
    return (
      annotation.pos.x >= 0 &&
      annotation.pos.x <= 100 &&
      annotation.pos.y >= 0 &&
      annotation.pos.y <= 100
    )
  }

  const renderAnnotation = (annotation: Annotation, index: number) => {
    const basePosition = {
      position: 'absolute',
      left: `${annotation.pos.x}%`,
      top: `${annotation.pos.y}%`,
    } as const

    // If type is explicitly set to 'custom', render as custom annotation
    if (annotation.type === 'custom') {
      return (
        <div
          key={annotation.id ?? index}
          className={annotation.className}
          style={{
            ...basePosition,
            transform: 'translate(-50%, -50%)',
            ...annotation.style,
          }}
        >
          {annotation.content}
        </div>
      )
    }

    // Clone the content element if it's a valid element and inject global styles
    if (isValidElement(annotation.content)) {
      return (
        <div key={annotation.id ?? index} style={basePosition}>
          {cloneElement(annotation.content, {
            ...annotation.content.props,

            connectorStyle: {
              ...connectorStyle,
              ...annotation.content.props.connectorStyle,
            },

            shapeStyle: {
              ...shapeStyle,
              ...annotation.content.props.shapeStyle,
            },

            fullSize: [width, height],
          })}
        </div>
      )
    }

    return (
      <div key={annotation.id ?? index} style={basePosition}>
        {annotation.content}
      </div>
    )
  }

  return (
    <AnnotatedImageContainer
      ref={ref}
      className={`annotated-image ${className}`.trim()}
      onClick={(e) => {
        if (!isDev) return
        if (!e.shiftKey) {
          const rect = e.currentTarget.getBoundingClientRect()
          const x = ((e.clientX - rect.left) / rect.width) * 100
          const y = ((e.clientY - rect.top) / rect.height) * 100
          console.log(`{ x: ${x.toFixed(2)}, y: ${y.toFixed(2)} },`)
        }
      }}
    >
      {children}
      {annotations.filter(validateAnnotation).map(renderAnnotation)}
    </AnnotatedImageContainer>
  )
}

const AnnotatedImageContainer = styled.div`
  width: 100%;
  position: relative;
  line-height: 0;
  * {
    line-height: 1.2em;
  }
  .annotated-image__image {
    width: 100%;
    height: auto;
    display: block;
  }
`
