import WithDraggable from '@/components/common/draggable/withDraggable'
import QSelectBox from '@/components/common/select/QSelectBox'
import { useState } from 'react'
import { useMessage } from '@/hooks/useMessage'
import { canvasState, dotLineGridSettingState, dotLineIntervalSelector } from '@/store/canvasAtom'
import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil'
import { onlyNumberInputChange } from '@/util/input-utils'
import { fabric } from 'fabric'

const TYPE = {
  DOT: 'DOT',
  LINE: 'LINE',
}

export default function DotLineGrid(props) {
  // const [modalOption, setModalOption] = useRecoilState(modalState); //modal 열림닫힘 state
  const [close, setClose] = useState(false)
  const { setShowDotLineGridModal } = props
  const canvas = useRecoilValue(canvasState)

  const [dotLineGridSetting, setDotLineGridSettingState] = useRecoilState(dotLineGridSettingState)
  const resetDotLineGridSetting = useResetRecoilState(dotLineGridSettingState)
  const interval = useRecoilValue(dotLineIntervalSelector)

  const { getMessage } = useMessage()
  const SelectOption = [
    { id: 1, name: getMessage('modal.canvas.setting.grid.dot.line.setting.line.origin'), value: 1 },
    { id: 2, name: '1/2', value: 1 / 2 },
    {
      id: 3,
      name: '1/4',
      value: 1 / 4,
    },
    { id: 4, name: '1/10', value: 1 / 10 },
  ]
  const [selectOption, setSelectOption] = useState(SelectOption[0])

  const HandleClickClose = () => {
    // setClose(true)
    // setTimeout(() => {
    //   setModalOption({ ...modalOption, gridoption: false })
    //   setClose(false)
    // }, 180)
  }

  const handleCheckBoxChange = (e) => {
    const { value, checked } = e.target
    setDotLineGridSettingState((prev) => {
      return {
        ...prev,
        [value]: checked,
      }
    })
  }

  const handleSave = () => {
    // 1. 점.선 그리드 설정으로 만들어진 기존 오브젝트 제거
    canvas
      ?.getObjects()
      .filter((obj) => obj.name === 'lineGrid')
      .forEach((obj) => canvas?.remove(obj))
    canvas
      ?.getObjects()
      .filter((obj) => obj.name === 'dotGrid')
      .forEach((obj) => canvas?.remove(obj))

    const horizontalInterval = interval.horizontalInterval
    const verticalInterval = interval.verticalInterval

    if (dotLineGridSetting.DOT) {
      const circle = new fabric.Circle({
        radius: 2,
        fill: 'red',
        strokeWidth: 0.7,
        originX: 'center',
        originY: 'center',
        selectable: false,
        lockMovementX: true,
        lockMovementY: true,
        lockRotation: true,
        lockScalingX: true,
        lockScalingY: true,
      })

      const patternSourceCanvas = new fabric.StaticCanvas(null, {
        width: horizontalInterval,
        height: verticalInterval,
      })

      patternSourceCanvas.add(circle)

      circle.set({
        left: patternSourceCanvas.width / 2,
        top: patternSourceCanvas.height / 2,
      })

      patternSourceCanvas.renderAll()

      const pattern = new fabric.Pattern({
        source: patternSourceCanvas.getElement(),
        repeat: 'repeat',
      })

      const backgroundPolygon = new fabric.Polygon(
        [
          { x: 0, y: 0 },
          { x: canvas.width, y: 0 },
          { x: canvas.width, y: canvas.height },
          { x: 0, y: canvas.height },
        ],
        {
          fill: pattern,
          selectable: false,
          name: 'dotGrid',
        },
      )

      canvas.add(backgroundPolygon)
      backgroundPolygon.sendToBack()
      canvas.renderAll()
    }

    if (dotLineGridSetting.LINE) {
      for (let i = 0; i < canvas.height / verticalInterval + 1; i++) {
        const horizontalLine = new fabric.Line(
          [0, i * verticalInterval - verticalInterval / 2, canvas.width, i * verticalInterval - verticalInterval / 2],
          {
            stroke: 'black',
            strokeWidth: 1,
            selectable: true,
            lockMovementX: true,
            lockMovementY: true,
            lockRotation: true,
            lockScalingX: true,
            lockScalingY: true,
            name: 'lineGrid',
            strokeDashArray: [5, 2],
            opacity: 0.3,
            direction: 'horizontal',
          },
        )
        canvas.add(horizontalLine)
      }

      for (let i = 0; i < canvas.width / horizontalInterval + 1; i++) {
        const verticalLine = new fabric.Line(
          [i * horizontalInterval - horizontalInterval / 2, 0, i * horizontalInterval - horizontalInterval / 2, canvas.height],
          {
            stroke: 'black',
            strokeWidth: 1,
            selectable: true,
            lockMovementX: true,
            lockMovementY: true,
            lockRotation: true,
            lockScalingX: true,
            lockScalingY: true,
            name: 'lineGrid',
            strokeDashArray: [5, 2],
            opacity: 0.3,
            direction: 'vertical',
          },
        )
        canvas.add(verticalLine)
      }
    }

    canvas.renderAll()
  }

  const handleRadioChange = (e) => {
    const { value, name, checked, selected } = e.target

    setDotLineGridSettingState((prev) => {
      return {
        ...prev,
        INTERVAL: {
          ...prev.INTERVAL,
          type: Number(value),
        },
      }
    })
  }

  const changeInput = (value, e) => {
    const { name } = e.target
    setDotLineGridSettingState((prev) => {
      return {
        ...prev,
        INTERVAL: {
          ...prev.INTERVAL,
          [name]: value,
        },
      }
    })
  }

  const changeDimension = (result) => {
    const { value } = result
    setDotLineGridSettingState((prev) => {
      return {
        ...prev,
        INTERVAL: {
          ...prev.INTERVAL,
          dimension: value,
        },
      }
    })
  }

  // 초기화
  const reset = () => {
    canvas
      ?.getObjects()
      .filter((obj) => obj.name === 'lineGrid')
      .forEach((obj) => canvas?.remove(obj))
    canvas
      ?.getObjects()
      .filter((obj) => obj.name === 'dotGrid')
      .forEach((obj) => canvas?.remove(obj))
    resetDotLineGridSetting()
    setSelectOption(SelectOption[0])
  }

  return (
    <WithDraggable isShow={true} pos={{ x: -150, y: 300 }}>
      <div className={`modal-pop-wrap ssm mount`}>
        <div className="modal-head">
          <h1 className="title">{getMessage('modal.canvas.setting.grid.dot.line.setting')}</h1>
          <button className="modal-close" onClick={() => setShowDotLineGridModal(false)}>
            닫기
          </button>
        </div>
        <div className="modal-body">
          <div className="grid-check-form">
            <div className="d-check-box pop">
              <input type="checkbox" id="ch01" value={TYPE.DOT} onChange={handleCheckBoxChange} checked={dotLineGridSetting.DOT} />
              <label htmlFor="ch01">{getMessage('modal.canvas.setting.grid.dot.line.setting.dot.display')}</label>
            </div>
            <div className="d-check-box pop">
              <input type="checkbox" id="ch02" value={TYPE.LINE} onChange={handleCheckBoxChange} checked={dotLineGridSetting.LINE} />
              <label htmlFor="ch02">{getMessage('modal.canvas.setting.grid.dot.line.setting.line.display')}</label>
            </div>
          </div>
          <div className="grid-option-wrap">
            <div className="grid-option-box">
              <div className="d-check-radio pop no-text">
                <input
                  type="radio"
                  name="radio01"
                  id="ra01"
                  value={1}
                  onChange={handleRadioChange}
                  checked={dotLineGridSetting.INTERVAL.type === 1}
                />
                <label htmlFor="ra01"></label>
              </div>
              <div className="grid-input-form">
                <span className="mr10">{getMessage('modal.canvas.setting.grid.dot.line.setting.horizon')}</span>
                <div className="input-grid mr5">
                  <input
                    type="text"
                    className="input-origin"
                    name={`horizontalInterval`}
                    value={dotLineGridSetting.INTERVAL.horizontalInterval}
                    onChange={(e) => onlyNumberInputChange(e, changeInput)}
                  />
                </div>
                <span>mm</span>
              </div>
              <div className="grid-input-form">
                <span className="mr10">{getMessage('modal.canvas.setting.grid.dot.line.setting.vertical')}</span>
                <div className="input-grid mr5">
                  <input
                    type="text"
                    className="input-origin"
                    name={`verticalInterval`}
                    value={dotLineGridSetting.INTERVAL.verticalInterval}
                    onChange={(e) => onlyNumberInputChange(e, changeInput)}
                  />
                </div>
                <span>mm</span>
              </div>
            </div>
            <div className="grid-option-box">
              <div className="d-check-radio pop no-text">
                <input
                  type="radio"
                  name="radio01"
                  id="ra02"
                  value={2}
                  onChange={handleRadioChange}
                  checked={dotLineGridSetting.INTERVAL.type === 2}
                />
                <label htmlFor="ra02"></label>
              </div>
              <div className="grid-input-form">
                <span className="mr10">{getMessage('modal.canvas.setting.grid.dot.line.setting.ratio')}</span>
                <div className="input-grid mr5">
                  <input
                    type="text"
                    className="input-origin"
                    name={`ratioInterval`}
                    value={dotLineGridSetting.INTERVAL.ratioInterval}
                    onChange={(e) => onlyNumberInputChange(e, changeInput)}
                  />
                </div>
                <span>mm</span>
              </div>
              <div className="grid-select">
                <QSelectBox options={SelectOption} onChange={changeDimension} value={selectOption} />
              </div>
            </div>
          </div>
          <div className="grid-btn-wrap">
            <button className="btn-frame modal mr5" onClick={reset}>
              {getMessage('modal.canvas.setting.grid.dot.line.setting.reset')}
            </button>
            <button className="btn-frame modal act" onClick={handleSave}>
              {getMessage('modal.canvas.setting.grid.dot.line.setting.save')}
            </button>
          </div>
        </div>
      </div>
    </WithDraggable>
  )
}
