import React from 'react'
import * as dmv from 'dicom-microscopy-viewer'
import * as dcmjs from 'dcmjs'
import { Menu, Space, Switch } from 'antd'
import { FaEye, FaEyeSlash } from 'react-icons/fa'

import Description from './Description'

interface AnnotationItemProps {
  roi: dmv.roi.ROI
  index: number
  isVisible: boolean
  onVisibilityChange: ({ roiUID, isVisible }: {
    roiUID: string
    isVisible: boolean
  }) => void
}

/**
 * React component representing a Region of Interest (ROI) annotation.
 */
class AnnotationItem extends React.Component<AnnotationItemProps, {}> {
  constructor (props: AnnotationItemProps) {
    super(props)
    this.handleVisibilityChange = this.handleVisibilityChange.bind(this)
  }

  handleVisibilityChange (checked: boolean, event: Event): void {
    this.props.onVisibilityChange({
      roiUID: this.props.roi.uid,
      isVisible: checked
    })
  }

  render (): React.ReactNode {
    const identifier = `ROI ${this.props.index + 1}`
    const attributes: Array<{ name: string, value: string }> = []
    /**
     * This hack is required for Menu.Item to work properly:
     * https://github.com/react-component/menu/issues/142
     */
    const { isVisible, onVisibilityChange, ...otherProps } = this.props
    this.props.roi.evaluations.forEach((
      item: (
        dcmjs.sr.valueTypes.TextContentItem |
        dcmjs.sr.valueTypes.CodeContentItem
      )
    ) => {
      const nameValue = item.ConceptNameCodeSequence[0].CodeValue
      const nameMeaning = item.ConceptNameCodeSequence[0].CodeMeaning
      const name = `${nameMeaning}`
      if (item.ValueType === dcmjs.sr.valueTypes.ValueTypes.CODE) {
        const codeContentItem = item as dcmjs.sr.valueTypes.CodeContentItem
        const valueMeaning = codeContentItem.ConceptCodeSequence[0].CodeMeaning
        // For consistency with Segment and Annotation Group
        if (nameValue === '276214006') {
          attributes.push({
            name: 'Property category',
            value: `${valueMeaning}`
          })
        } else if (nameValue === '121071') {
          attributes.push({
            name: 'Property type',
            value: `${valueMeaning}`
          })
        } else if (nameValue === '111001') {
          attributes.push({
            name: 'Algorithm Name',
            value: `${valueMeaning}`
          })
        } else {
          attributes.push({
            name: name,
            value: `${valueMeaning}`
          })
        }
      } else if (item.ValueType === dcmjs.sr.valueTypes.ValueTypes.TEXT) {
        const textContentItem = item as dcmjs.sr.valueTypes.TextContentItem
        attributes.push({
          name: name,
          value: textContentItem.TextValue
        })
      }
    })
    this.props.roi.measurements.forEach(item => {
      const nameMeaning = item.ConceptNameCodeSequence[0].CodeMeaning
      const name = `${nameMeaning}`
      const seq = item.MeasuredValueSequence[0]
      const value = seq.NumericValue.toPrecision(6)
      const unit = seq.MeasurementUnitsCodeSequence[0].CodeValue
      attributes.push({
        name: name,
        value: `${value} ${unit}`
      })
    })
    return (
      <Space align='start'>
        <div style={{ paddingLeft: '14px' }}>
          <Switch
            size='small'
            onChange={this.handleVisibilityChange}
            checked={this.props.isVisible}
            checkedChildren={<FaEye />}
            unCheckedChildren={<FaEyeSlash />}
          />
        </div>
        <Menu.Item
          style={{ height: '100%', paddingLeft: '3px' }}
          key={this.props.roi.uid}
          {...otherProps}
        >
          <Description
            header={identifier}
            attributes={attributes}
            selectable
            hasLongValues
          />
        </Menu.Item>
      </Space>
    )
  }
}

export default AnnotationItem