import WithDraggable from '@/components/common/draggable/WithDraggable'
import QSelectBox from '@/components/common/select/QSelectBox'
import { useEffect, useState } from 'react'
import { useMessage } from '@/hooks/useMessage'
import { canvasState, dotLineGridSettingState, dotLineIntervalSelector } from '@/store/canvasAtom'
import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil'
import { onlyNumberInputChange } from '@/util/input-utils'
import { fabric } from 'fabric'
import { gridColorState } from '@/store/gridAtom'
import { gridDisplaySelector, settingModalGridOptionsState } from '@/store/settingAtom'
import { useAxios } from '@/hooks/useAxios'
import { useSwal } from '@/hooks/useSwal'
import { usePopup } from '@/hooks/usePopup'

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

export default function DotLineGrid(props) {
  // const [modalOption, setModalOption] = useRecoilState(modalState); //modal 열림닫힘 state
  const [objectNo, setObjectNo] = useState('test123240912001') // 이후 삭제 필요
  const [close, setClose] = useState(false)
  const { id, setShowDotLineGridModal } = props
  const setSettingModalGridOptions = useSetRecoilState(settingModalGridOptionsState)
  const gridColor = useRecoilValue(gridColorState)
  const canvas = useRecoilValue(canvasState)
  const isGridDisplay = useRecoilValue(gridDisplaySelector)

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

  const { getMessage } = useMessage()
  const { get, post } = useAxios()
  const { swalFire } = useSwal()
  const { closePopup } = usePopup()

  useEffect(() => {
    return () => {
      setSettingModalGridOptions((prev) => {
        const newSettingOptions = [...prev]
        newSettingOptions[1].selected = false
        return [...newSettingOptions]
      })
    }
  }, [])

  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])

  // 데이터를 최초 한 번만 조회
  useEffect(() => {
    console.log('DotLineGrid useEffect 실행')
    fetchGridSettings()
  }, [objectNo])

  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,
      }
    })
  }

  // Canvas Grid Setting 조회 및 초기화
  const fetchGridSettings = async () => {
    try {
      const res = await get({ url: `/api/canvas-management/canvas-grid-settings/by-object/${objectNo}` })

      const patternData = {
        INTERVAL: {
          type: res.gridType,
          horizontalInterval: res.gridHorizon,
          verticalInterval: res.gridVertical,
          ratioInterval: res.gridRatio,
        },
        dimension: res.gridDimen,
        DOT: res.dotGridDisplay,
        LINE: res.lineGridDisplay,
      }

      const matchedOption = SelectOption.find((option) => option.value == res.gridDimen)

      // dimension 값에 맞는 옵션을 선택
      setSelectOption(matchedOption)

      // 서버에서 받은 데이터로 상태 업데이트
      setDotLineGridSettingState(patternData)
    } catch (error) {
      console.error('Data fetching error:', error)
    }
  }

  const handleSave = async () => {
    if (!dotLineGridSetting.DOT && !dotLineGridSetting.LINE) {
      swalFire({ text: '배치할 그리드를 설정해주세요.' })
      return
    }
    try {
      const patternData = {
        objectNo,
        dotGridDisplay: dotLineGridSetting.DOT,
        lineGridDisplay: dotLineGridSetting.LINE,
        gridType: dotLineGridSetting.INTERVAL.type,
        gridHorizon: dotLineGridSetting.INTERVAL.horizontalInterval,
        gridVertical: dotLineGridSetting.INTERVAL.verticalInterval,
        gridRatio: dotLineGridSetting.INTERVAL.ratioInterval,
        gridDimen: dotLineGridSetting.INTERVAL.dimension,
      }

      // HTTP POST 요청 보내기
      await post({ url: `/api/canvas-management/canvas-grid-settings`, data: patternData }).then((res) => {
        swalFire({ text: getMessage(res.returnMessage) })

        // 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 (patternData.dotGridDisplay) {
          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: patternData.gridHorizon,
            height: patternData.gridVertical,
          })

          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',
              visible: isGridDisplay,
            },
          )

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

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

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

        canvas.renderAll()
      })
      setShowDotLineGridModal(false)
      closePopup(id)
    } catch (error) {
      swalFire({ text: getMessage(res.returnMessage), icon: 'error' })
    }
  }

  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: 840, y: -815 }}>
      <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)
              closePopup(id)
            }}
          >
            닫기
          </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.DOT || dotLineGridSetting.LINE) && dotLineGridSetting.INTERVAL.type === 1}
                  readOnly={!dotLineGridSetting.DOT && !dotLineGridSetting.LINE}
                />
                <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.DOT || dotLineGridSetting.LINE) && dotLineGridSetting.INTERVAL.type === 2}
                  readOnly={!dotLineGridSetting.DOT && !dotLineGridSetting.LINE}
                />
                <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>
  )
}
