import { useEffect, useRef, useState } from 'react'
import { Button, Checkbox, CheckboxGroup, RadioGroup, Radio, Input } from '@nextui-org/react'
import { useRecoilState, useRecoilValue } from 'recoil'
import { modalContent, modalState } from '@/store/modalAtom'
import { guideLineState, horiGuideLinesState, vertGuideLinesState } from '@/store/canvasAtom'
import { fabric } from 'fabric'
import { ColorPicker, useColor } from 'react-color-palette'
import 'react-color-palette/css'

export default function GridSettingsModal(props) {
  const { canvasProps } = props
  const [isCustomGridSetting, setIsCustomGridSetting] = useState(true)
  const [gridCheckedValue, setGridCheckValue] = useState([])
  const [ratioValue, setRatioValue] = useState('1')
  const moduleLength = useRef(null) //모듈 mm 길이 입력
  const customModuleHoriLength = useRef(null)
  const customModuleVertLength = useRef(null)

  const [open, setOpen] = useRecoilState(modalState)
  const [guideLine, setGuideLine] = useRecoilState(guideLineState)
  const [horiGuideLines, setHoriGuideLines] = useRecoilState(horiGuideLinesState)
  const [vertGuideLines, setVertGuideLines] = useRecoilState(vertGuideLinesState)

  const gridSettingArray = []

  const [guideColor, setGuideColor] = useColor('rgb(200, 15, 15)')
  const [colorPickerShow, setColorPickerShow] = useState(false)

  const boxStyle = {
    width: '50px',
    height: '30px',
    border: '1px solid black',
    backgroundColor: guideColor.hex,
  }
  useEffect(() => {
    moduleLength.current.value = 90
    customModuleHoriLength.current.value = 90
    customModuleVertLength.current.value = 90
  }, [])

  useEffect(() => {
    setIsCustomGridSetting(ratioValue !== 'custom')
  }, [ratioValue])

  const drawGridSettings = () => {
    //기존에 선택된 데이터가 있으면 그 데이터를 포함한다
    if (!(Object.keys(guideLine).length === 0 && guideLine.constructor === Object)) {
      gridSettingArray.push(...guideLine)
    }

    let moduleHoriLength = moduleLength.current.value //가로 간격
    let moduleVertLength = moduleLength.current.value //새로 간격

    if (ratioValue === 'custom') {
      moduleHoriLength = customModuleHoriLength.current.value
      moduleVertLength = customModuleVertLength.current.value
    } else {
      moduleHoriLength = moduleHoriLength / ratioValue
      moduleVertLength = moduleVertLength / ratioValue
    }

    if (gridCheckedValue.includes('line')) {
      const horizontalLineArray = []
      const verticalLineArray = []

      for (let i = 0; i < canvasProps.height / moduleVertLength + 1; i++) {
        const horizontalLine = new fabric.Line(
          [0, i * moduleVertLength - moduleVertLength / 2, canvasProps.width, i * moduleVertLength - moduleVertLength / 2],
          {
            stroke: guideColor.hex,
            strokeWidth: 1,
            selectable: true,
            lockMovementX: true,
            lockMovementY: true,
            lockRotation: true,
            lockScalingX: true,
            lockScalingY: true,
            name: 'guideLine',
            strokeDashArray: [5, 2],
            opacity: 0.3,
            direction: 'horizontal',
          },
        )
        canvasProps.add(horizontalLine)
        horizontalLineArray.push(horizontalLine)
      }

      for (let i = 0; i < canvasProps.width / moduleHoriLength + 1; i++) {
        const verticalLine = new fabric.Line(
          [i * moduleHoriLength - moduleHoriLength / 2, 0, i * moduleHoriLength - moduleHoriLength / 2, canvasProps.height],
          {
            stroke: guideColor.hex,
            strokeWidth: 1,
            selectable: true,
            lockMovementX: true,
            lockMovementY: true,
            lockRotation: true,
            lockScalingX: true,
            lockScalingY: true,
            name: 'guideLine',
            strokeDashArray: [5, 2],
            opacity: 0.3,
            direction: 'vertical',
          },
        )
        canvasProps.add(verticalLine)
        verticalLineArray.push(verticalLine)
      }
      canvasProps.renderAll()

      const snapDistance = 10

      const recoilObj = {
        guideMode: 'guideLine',
        horizontalLineArray,
        verticalLineArray,
        moduleVertLength: moduleVertLength,
        moduleHoriLength: moduleHoriLength,
      }
      gridSettingArray.push(recoilObj)
      const newHoriGuideLines = [...horiGuideLines]
      horizontalLineArray.forEach((line) => {
        newHoriGuideLines.push(line)
      })
      const newVertGuideLines = [...vertGuideLines]
      verticalLineArray.forEach((line) => {
        newVertGuideLines.push(line)
      })
      setHoriGuideLines(newHoriGuideLines)
      setVertGuideLines(newVertGuideLines)
    }

    if (gridCheckedValue.includes('dot')) {
      const circle = new fabric.Circle({
        radius: 2,
        fill: 'white',
        stroke: guideColor.hex,
        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: moduleHoriLength,
        height: moduleVertLength,
      })

      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: canvasProps.width, y: 0 },
          { x: canvasProps.width, y: canvasProps.height },
          { x: 0, y: canvasProps.height },
        ],
        {
          fill: pattern,
          selectable: false,
          name: 'guideDot',
        },
      )

      canvasProps.add(backgroundPolygon)
      backgroundPolygon.sendToBack()
      canvasProps.renderAll()

      const recoilObj = {
        guideMode: 'guideDot',
        moduleVertLength: moduleVertLength,
        moduleHoriLength: moduleHoriLength,
      }

      gridSettingArray.push(recoilObj)
    }
    canvasProps.renderAll()
    setGuideLine(gridSettingArray)
  }

  const removeGuideLines = () => {
    if (!(Object.keys(guideLine).length === 0 && guideLine.constructor === Object)) {
      const guideLines = canvasProps._objects.filter((obj) => obj.name === 'guideLine' || obj.name === 'guideDot')
      guideLines?.forEach((item) => canvasProps.remove(item))
      canvasProps.renderAll()
      setGuideLine([])
      setHoriGuideLines([])
      setVertGuideLines([])
    } else {
      alert('그리드가 없습니다.')
      return
    }
  }

  return (
    <>
      <div>
        <div className="flex w-full flex-wrap md:flex-nowrap gap-4">
          <label style={{ display: 'block', marginBottom: '5px' }}>
            <CheckboxGroup label="그리드 설정" value={gridCheckedValue} defaultChecked={gridCheckedValue} onValueChange={setGridCheckValue}>
              <Checkbox value="dot">점 그리드</Checkbox>
              <Checkbox value="line">점선 그리드</Checkbox>
            </CheckboxGroup>
          </label>
        </div>
        <div className="flex w-full flex-wrap md:flex-nowrap gap-4">
          <Input type="number" label="모듈" ref={moduleLength} />
          mm
        </div>
        <div className="flex w-full flex-wrap md:flex-nowrap gap-4">
          <RadioGroup label="비율 설정" value={ratioValue} defaultValue={ratioValue} onValueChange={setRatioValue}>
            <Radio value="1">원치수</Radio>
            <Radio value="2">1/2</Radio>
            <Radio value="4">1/4</Radio>
            <Radio value="10">1/10</Radio>
            <Radio value="custom">임의간격</Radio>
          </RadioGroup>
        </div>
        <div className="flex w-full flex-wrap md:flex-nowrap gap-4">
          가이드컬러 <div style={boxStyle} onClick={() => setColorPickerShow(!colorPickerShow)}></div>
        </div>
        {colorPickerShow && (
          <ColorPicker color={guideColor} onChange={setGuideColor} hideInput={['hsv', 'rgb', 'hex']} height={100} hideAlpha={true} />
        )}

        <div className="flex w-full flex-wrap md:flex-nowrap gap-4">
          <Checkbox value="linked" isDisabled={isCustomGridSetting}>
            종횡연동
          </Checkbox>
        </div>
      </div>
      <div className="flex w-full flex-wrap md:flex-nowrap gap-4">
        <Input type="number" label="가로간격" ref={customModuleHoriLength} min={0} isDisabled={isCustomGridSetting} />
        mm
      </div>
      <div className="flex w-full flex-wrap md:flex-nowrap gap-4">
        <Input type="number" label="세로간격" ref={customModuleVertLength} min={0} isDisabled={isCustomGridSetting} />
        mm
      </div>

      <div className="flex gap-4 items-center">
        <Button size="sm">초기화</Button>
        <Button size="sm" color="secondary" onClick={drawGridSettings} isDisabled={gridCheckedValue.length === 0}>
          저장
        </Button>
        <Button size="sm" onClick={() => setOpen(!open)}>
          취소
        </Button>
        <Button size="sm" onClick={() => removeGuideLines()}>
          그리드 삭제
        </Button>
      </div>
    </>
  )
}
