import { useMessage } from '@/hooks/useMessage'
import WithDraggable from '@/components/common/draggable/WithDraggable'
import { usePopup } from '@/hooks/usePopup'
import { useRecoilValue } from 'recoil'
import { contextPopupPositionState } from '@/store/popupAtom'
import { canvasState, currentObjectState } from '@/store/canvasAtom'
import { useEffect, useState } from 'react'
import Big from 'big.js'
import { calcLineActualSize, calcLinePlaneSize } from '@/util/qpolygon-utils'
import { normalizeDigits } from '@/util/input-utils'

export default function AuxiliarySize(props) {
  const contextPopupPosition = useRecoilValue(contextPopupPositionState)
  const { id, pos = contextPopupPosition } = props
  const [checkedRadio, setCheckedRadio] = useState(null)
  const [value1, setValue1] = useState(null)
  const [value2, setValue2] = useState(null)
  const [size, setSize] = useState(0)
  const { getMessage } = useMessage()
  const { closePopup } = usePopup()
  const currentObject = useRecoilValue(currentObjectState)
  const canvas = useRecoilValue(canvasState)

  useEffect(() => {
    return () => {
      canvas?.discardActiveObject()
    }
  }, [])

  useEffect(() => {
    setValue1('')
    setValue2('')
  }, [checkedRadio])

  useEffect(() => {
    if (currentObject === null) closePopup(id)
  }, [currentObject])

  const handleInput = (e) => {
    let value = e.target.value.replace(/^0+/, '')
    if (value === '') {
      if (checkedRadio === 1) setValue1(value)
      if (checkedRadio === 2) setValue2(value)
      setSize(0)
    } else {
      //value = Big(value.replace(/[^0-9]/g, ''))
      value = Big(normalizeDigits(value))
      if (checkedRadio === 1) setValue1(value.toNumber())
      if (checkedRadio === 2) setValue2(value.toNumber())
      setSize(value.div(10).toNumber())
    }
  }

  const handleSave = () => {
    const { x1, y1, x2, y2 } = currentObject

    // 선택한 선분의 planeSize와 actualSize의 사잇각을 구한다.
    const angleBetweenLines = () => {
      const planeSize = Big(currentObject?.attributes.planeSize)
      const actualSize = Big(currentObject?.attributes.actualSize)
      // actualSize가 planeSize보다 작거나 같을때는 각도가 0
      if (actualSize.lte(planeSize)) {
        return 0
      }
      // 삼각법을 사용하여 각도를 계산합니다
      // cos(theta) = adjacent / hypotenuse
      const cosTheta = planeSize.div(actualSize)
      const thetaRadians = Big(Math.acos(cosTheta.toNumber())) // Angle in radians
      return thetaRadians.times(180).div(Math.PI)
    }
    const degree = angleBetweenLines()

    if (size > 0 && (checkedRadio === 1 || checkedRadio === 2)) {
      // 두 지점 사이의 거리를 구한다.
      const dx = Big(x2).minus(Big(x1))
      const dy = Big(y2).minus(Big(y1))
      const distance = Big(dx.pow(2).plus(dy.pow(2)).sqrt())

      if (distance > 0) {
        // 현재 선분의 길이와 입력된 길이의 차이를 구한다.
        const scaleFactor = Big(size).div(distance)

        //1지점 선택일때는 2지점의 좌표, 2지점 선택일때는 1지점의 좌표를 조정한다.
        if (checkedRadio === 1) {
          const newX2 = Big(x1).plus(dx.times(scaleFactor))
          const newY2 = Big(y1).plus(dy.times(scaleFactor))
          currentObject.set({ x2: newX2, y2: newY2 })
        } else if (checkedRadio === 2) {
          const newX1 = Big(x2).minus(dx.times(scaleFactor))
          const newY1 = Big(y2).minus(dy.times(scaleFactor))
          currentObject.set({ x1: newX1, y1: newY1 })
        }
        //planeSize와 actualSize를 재계산한다.
        currentObject.attributes.planeSize = calcLinePlaneSize({
          x1: currentObject.x1,
          y1: currentObject.y1,
          x2: currentObject.x2,
          y2: currentObject.y2,
        })
        currentObject.attributes.actualSize = calcLineActualSize(
          {
            x1: currentObject.x1,
            y1: currentObject.y1,
            x2: currentObject.x2,
            y2: currentObject.y2,
          },
          degree,
        )
        currentObject.addLengthText()
      }
      canvas.renderAll()
    }
    closePopup(id)
  }
  return (
    <WithDraggable isShow={true} pos={pos} className="xm">
      <WithDraggable.Header title={getMessage('modal.auxiliary.size.edit')} onClose={() => closePopup(id)} />
      <WithDraggable.Body>
        <div className="discrimination-box mb10">
          <div className="d-check-radio pop mb10">
            <input type="radio" name="radio01" id="ra01" onClick={(e) => setCheckedRadio(1)} />
            <label htmlFor="ra01">1{getMessage('modal.auxiliary.size.edit.point')}</label>
          </div>
          <div className="outline-form mb15">
            <div className="input-grid mr5" style={{ flex: '1 1 auto' }}>
              <input type="text" className="input-origin block" defaultValue={currentObject?.attributes.planeSize} readOnly={true} />
            </div>
            <span className="thin">mm</span>
          </div>
          <div className="outline-form">
            <span style={{ width: 'auto' }}>{getMessage('length')}</span>
            <div className="input-grid mr5">
              <input type="text" className="input-origin block" value={value1} readOnly={checkedRadio !== 1} onChange={handleInput} />
            </div>
            <span className="thin">mm</span>
          </div>
        </div>
        <div className="discrimination-box ">
          <div className="d-check-radio pop mb10">
            <input type="radio" name="radio01" id="ra02" onClick={(e) => setCheckedRadio(2)} />
            <label htmlFor="ra02">2{getMessage('modal.auxiliary.size.edit.point')}</label>
          </div>
          <div className="outline-form mb15">
            <div className="input-grid mr5" style={{ flex: '1 1 auto' }}>
              <input type="text" className="input-origin block" defaultValue={currentObject?.attributes.planeSize} readOnly={true} />
            </div>
            <span className="thin">mm</span>
          </div>
          <div className="outline-form">
            <span style={{ width: 'auto' }}>{getMessage('length')}</span>
            <div className="input-grid mr5">
              <input type="text" className="input-origin block" value={value2} readOnly={checkedRadio !== 2} onChange={handleInput} />
            </div>
            <span className="thin">mm</span>
          </div>
        </div>
        <div className="grid-btn-wrap">
          <button className="btn-frame modal act" onClick={handleSave}>
            {getMessage('modal.common.save')}
          </button>
        </div>
      </WithDraggable.Body>
    </WithDraggable>
  )
}
