import Text from '../text'
import Circle from '../circle'
import { round, formatMm } from 'shared/utils.js'

const RevealPoint = props => {
  const r = 15 * props.gist.scale
  const { x, y } = props.point
  const { topLeft, bottomRight } = props.part
  const i = Object.keys(props.gist._state.xray.reveal[props.partName].points).indexOf(props.pointName)%10
  const classes = `stroke-sm stroke-color-${i} stroke-dashed`
  return (
    <g>
      <circle
        cx={x}
        cy={y}
        r={r}
        className={classes}
    />
    <path d={`
      M ${x} ${topLeft.y} L ${x} ${y - r}
      m 0 ${2*r} L ${x} ${bottomRight.y}
      M ${topLeft.x} ${y} L ${x - r} ${y}
      m ${2*r} 0 L ${bottomRight.x} ${y}`} className={classes} />
    </g>
  )
}

// Length for the indicators
const lead = 20
// Length for the text on indicators
// this is longer to prevent text from being cropped
const longLead = 40

const Coord = ({id, val, pointName}) => (
  <text>
    <textPath xlinkHref={`#${id}`} startOffset="50%">
      <tspan className="center fill-note text-sm" dy={0}>
        {round(val)}
      </tspan>
    </textPath>
    <textPath xlinkHref={`#${id}`} startOffset="50%">
      <tspan className="center fill-note text-xs" dy={5}>
        {pointName}
      </tspan>
    </textPath>
  </text>
)

const PosX = ({ id, point, scale, pointName }) => (
  <g>
    <path id={id+'_x'} d={`
      M ${point.x - (point.x < 0 ? 0 : lead*scale)} ${point.y}
      l ${lead * scale} 0
    `}
      className="stroke-note stroke-sm"
      markerStart={point.x < 0 ? "url(#grainlineFrom)" : ''}
      markerEnd={point.x < 0 ? '' : "url(#grainlineTo)"}
    />
    <path id={id+'_xlong'} d={`
      M ${point.x - (point.x < 0 ? longLead/2.4*scale : longLead*scale)} ${point.y}
      l ${longLead * scale * 1.4} 0
    `}
      className="hidden"
    />
    <Coord id={`${id}_xlong`} val={point.x} pointName={pointName}/>
  </g>
)


const PosY = ({ id, point, scale, pointName }) => (
  <g>
    <path id={id+'_y'} d={`
      M ${point.x} ${point.y + (point.y < 0 ? lead*scale : 0)}
      l 0 ${lead * scale * -1}
    `}
      className="stroke-note stroke-sm"
      markerStart={point.y < 0 ? '' : "url(#grainlineFrom)"}
      markerEnd={point.y < 0 ? "url(#grainlineTo)" : ''}
    />
    <path id={id+'_ylong'} d={`
      M ${point.x} ${point.y + (point.y < 0 ? longLead/1.25*scale : longLead*scale/5)}
      l 0 ${longLead * scale * -1}
    `}
      className="hidden"
    />
    <Coord id={`${id}_ylong`} val={point.y} pointName={pointName} />
  </g>
)


const ActiveXrayPoint = props => {
  const id = `${props.partName}_${props.pointName}_xray_point`
  const r = 15 * props.gist.scale
  const { x, y } = props.point
  const { topLeft, bottomRight } = props.part
  const i = Object.keys(props.gist._state.xray.parts[props.partName].points).indexOf(props.pointName)%10
  const classes = `stroke-sm stroke-color-${i} stroke-dashed`
  const posProps = {
    id,
    point: props.point,
    pointName: props.pointName,
    scale: props.gist.scale,
  }

  return <g><PosX {...posProps} /><PosY {...posProps} /></g>
}

const PassiveXrayPoint = props => (
  <g>
    <circle
      cx={props.point.x}
      cy={props.point.y}
      r={2 * props.gist.scale}
      className="stroke-sm stroke-lining fill-lining fill-opacity-25" />
    <circle
      cx={props.point.x}
      cy={props.point.y}
      r={7.5 * props.gist.scale}
      className="opacity-0 stroke-lining fill-lining hover:opacity-25 hover:cursor-pointer"
      onClick={props.gist._state.xray?.parts?.[props.partName]?.points?.[props.pointName]
        ? () => props.unsetGist(
          ['_state', 'xray', 'parts', props.partName, 'points', props.pointName]
        )
        : () => props.updateGist(
          ['_state', 'xray', 'parts', props.partName, 'points', props.pointName],
          1
        )
      }
    />
  </g>
)


const Point = props => {
  const { point, pointName, partName, gist } = props
  const output = []
  if (gist._state?.xray?.enabled) {
    // Passive indication for points
    output.push(<PassiveXrayPoint {...props} key={'xp-' + pointName} />)
    // Active indication for points (point that have been clicked on)
    if (gist._state?.xray?.parts?.[partName]?.points?.[pointName])
      output.push(<ActiveXrayPoint {...props} key={'rp-' + pointName} />)
    // Reveal (based on clicking the seach icon in sidebar
    if (gist._state?.xray?.reveal?.[partName]?.points?.[pointName])
      output.push(<RevealPoint {...props} key={'rp-' + pointName} />)
  }
  // Render text
  if (point.attributes && point.attributes.get('data-text'))
    output.push(<Text {...props} key={'point-' + pointName} />)
  // Render circle
  if (point.attributes && point.attributes.get('data-circle'))
    output.push(<Circle point={point} key={'circle-' + pointName} />)

  return output.length < 1 ? null : output
}

export default Point