import React from 'react'
import { useMeasure } from 'react-use'
import { AppProps, ExtensionType } from 'src/types'
import 'src/style.css'

import {
  getRotateAngleConfig,
  getSizeConfig,
  getShadowConfig,
  getStrokeConfig
} from 'src/utils'

import {
  Large_Canvas_Width
} from 'src/contants'

const Line: React.FC<AppProps> = (props) => {
  const {
    properties,
    theme
  } = props
  const [containerRef, { width: offsetWidth, height: offsetHeight }] = useMeasure()

  const rotateAngle = React.useMemo(() => {
    return getRotateAngleConfig(properties)
  }, [properties])

  const shadow = React.useMemo(() => {
    return getShadowConfig(properties, theme)
  }, [properties, theme])

  const {
    containerWidth,
    containerHeight,
    w,
    h
  } = React.useMemo(() => {
    return getSizeConfig(offsetWidth, offsetHeight, rotateAngle)
  }, [offsetWidth, offsetHeight, rotateAngle])

  const {
    strokeDasharray,
    strokeLinecap,
    stroke,
    strokeWidth
  } = React.useMemo(() => {
    return getStrokeConfig(properties, theme, offsetWidth, Large_Canvas_Width, ExtensionType.Line)
  }, [properties, theme, offsetWidth])

  const get = (rotateAngle) => {
    let x1, y1, x2, y2
    // 需要考虑strokeWidth对于线本身产生的额外尺寸，否则会出现首尾削去的情况
    let strokeWidthOffset = 0
    // 需要考虑strokeWidth旋转后产生的额外尺寸，否则会出现首尾夹角削去的情况
    let strokeOffset = 0
    let curRotateAngle = rotateAngle % 180
    let angle = Math.PI * 2 * (curRotateAngle) / 360
    let ch = containerHeight, cw = containerWidth

    y1 = ch / 2
    y2 = ch / 2

    if (curRotateAngle != 90) {
      if (Math.abs(Math.tan(angle)) <= (ch / cw)) {
        // 左右接
        strokeOffset = strokeWidth * Math.tan(angle) / 2
        strokeWidthOffset = Math.tan(angle) > 0 ? strokeWidth / 2 : -(strokeWidth / 2)
        x1 = cw * (Math.cos(angle) - 1) / (2 * Math.cos(angle)) + strokeOffset + strokeWidthOffset
        x2 = cw * (Math.cos(angle) + 1) / (2 * Math.cos(angle)) - strokeOffset - strokeWidthOffset
      } else {
        // 上下接
        strokeOffset = Math.abs(strokeWidth / (2 * Math.tan(angle)))
        strokeWidthOffset = strokeWidth / 2
        x1 = (cw * Math.sin(angle) - ch) / (2 * Math.sin(angle)) + strokeOffset + strokeWidthOffset
        x2 = (cw * Math.sin(angle) + ch) / (2 * Math.sin(angle)) - strokeOffset - strokeWidthOffset
      }
    } else if (curRotateAngle == 90) {
      x1 = (cw - ch) / 2
      y1 = ch / 2
      x2 = (cw + ch) / 2
      y2 = ch / 2
    }
    return {
      start: [x1, y1],
      end: [x2, y2]
    }
  }

  const coor = get(rotateAngle)

  return (
    <div className='graphicsContainer' ref={containerRef}>
      <svg
        className="graphics"
        version="1.1"
        xmlns="http://www.w3.org/2000/svg"
        height={containerHeight}
        width={containerWidth}
        viewBox={`0 0 ${containerWidth} ${containerHeight}`}
        style={{ filter: shadow }}
      >
        {/* 线 */}
        <line
          x1={coor['start'][0]}
          y1={coor['start'][1]}
          x2={coor['end'][0]}
          y2={coor['end'][1]}
          strokeDasharray={strokeDasharray}
          strokeLinecap={strokeLinecap}
          stroke={stroke}
          strokeWidth={strokeWidth}
          transform={`rotate(${rotateAngle}, ${containerWidth / 2}, ${containerHeight / 2})`}
        />
      </svg>
    </div>
  )
}

export default Line
