import { useCanvas } from '@/hooks/useCanvas'
import { useEffect, useState } from 'react'
import { Mode, useMode } from '@/hooks/useMode'
import { Button } from '@nextui-org/react'
import QRect from '@/components/fabric/QRect'
import QPolygon from '@/components/fabric/QPolygon'

import RangeSlider from './ui/RangeSlider'
import { useRecoilState } from 'recoil'
import { canvasSizeState, fontSizeState, sortedPolygonArray } from '@/store/canvasAtom'
import { QLine } from '@/components/fabric/QLine'
import { getCanvasState, insertCanvasState } from '@/lib/canvas'
import { calculateIntersection2 } from '@/util/canvas-util'

export default function Roof2() {
  const { canvas, handleRedo, handleUndo, setCanvasBackgroundWithDots, saveImage, addCanvas } = useCanvas('canvas')

  //canvas 기본 사이즈
  const [canvasSize, setCanvasSize] = useRecoilState(canvasSizeState)

  //canvas 가로 사이즈
  const [verticalSize, setVerticalSize] = useState(canvasSize.vertical)
  //canvas 세로 사이즈
  const [horizontalSize, setHorizontalSize] = useState(canvasSize.horizontal)
  // 글자크기
  const [fontSize, setFontSize] = useRecoilState(fontSizeState)

  const [sortedArray] = useRecoilState(sortedPolygonArray)

  const [angle, setAngle] = useState(0)

  const [showControl, setShowControl] = useState(false)

  const {
    mode,
    changeMode,
    handleClear,
    fillCellInPolygon,
    zoomIn,
    zoomOut,
    zoom,
    togglePolygonLine,
    handleOuterlinesTest,
    handleOuterlinesTest2,
    applyTemplateB,
    makeRoofPatternPolygon,
  } = useMode()

  // const [canvasState, setCanvasState] = useRecoilState(canvasAtom)

  useEffect(() => {
    if (!canvas) {
      return
    }
    changeMode(canvas, mode)
  }, [canvas, mode])

  const makeRect = () => {
    if (canvas) {
      const rect = new QRect({
        left: 100,
        top: 100,
        fill: 'transparent',
        stroke: 'black',
        width: 400,
        height: 100,
        fontSize: fontSize,
      })

      canvas?.add(rect)
    }
  }

  const makeLine = () => {
    if (canvas) {
      const line = new QLine([50, 50, 200, 50], {
        stroke: 'black',
        strokeWidth: 2,
        fontSize: fontSize,
      })

      canvas?.add(line)
    }
  }

  const makePolygon = () => {
    if (canvas) {
      const polygon = new QPolygon(
        [
          { x: 100, y: 100 },
          { x: 600, y: 200 },
          { x: 700, y: 800 },
          { x: 100, y: 800 },
        ],
        {
          fill: 'transparent',
          stroke: 'black',
          strokeWidth: 2,
          selectable: true,
          fontSize: fontSize,
        },
        canvas,
      )

      canvas?.add(polygon)

      polygon.fillCell({ width: 50, height: 30, padding: 10 })
    }
  }

  /**
   * canvas 사이즈 변경 함수
   */
  const canvasSizeMode = () => {
    if (canvas) {
      canvas.setWidth(horizontalSize)
      canvas.setHeight(verticalSize)
      canvas.renderAll()

      setCanvasSize(() => ({
        vertical: verticalSize,
        horizontal: horizontalSize,
      }))
    }
  }

  /**
   * 값 변경시
   */
  useEffect(() => {
    canvasSizeMode()
  }, [verticalSize, horizontalSize])

  const makeQPolygon = () => {
    const type1 = [
      { x: 100, y: 100 },
      { x: 850, y: 100 },
      { x: 850, y: 800 },
      { x: 500, y: 800 },
      { x: 500, y: 400 },
      { x: 100, y: 400 },
    ]
    const type2 = [
      { x: 100, y: 100 },
      { x: 100, y: 1000 },
      { x: 1000, y: 1000 },
      { x: 1000, y: 600 },
      { x: 550, y: 600 },
      { x: 550, y: 100 },
    ]

    const type3 = [
      { x: 200, y: 100 },
      { x: 200, y: 800 },
      { x: 500, y: 800 },
      { x: 500, y: 300 },
      { x: 800, y: 300 },
      { x: 800, y: 100 },
    ]

    const type4 = [
      { x: 150, y: 450 },
      { x: 150, y: 800 },
      { x: 750, y: 800 },
      { x: 750, y: 300 },
      { x: 550, y: 300 },
      { x: 550, y: 450 },
    ]

    const type1A = [
      { x: 67, y: 81 },
      { x: 67, y: 660 },
      { x: 437, y: 660 },
      { x: 437, y: 1190 },
      { x: 858, y: 1190 },
      { x: 858, y: 81 },
    ]

    const type1B = [
      { x: 137, y: 42 },
      { x: 137, y: 621 },
      { x: 667, y: 621 },
      { x: 667, y: 991 },
      { x: 1088, y: 991 },
      { x: 1088, y: 42 },
    ]

    const eightPoint = [
      { x: 240, y: 130 },
      { x: 240, y: 630 },
      { x: 640, y: 630 },
      { x: 640, y: 480 },
      { x: 440, y: 480 },
      { x: 440, y: 280 },
      { x: 740, y: 280 },
      { x: 740, y: 130 },
    ]

    const eightPoint2 = [
      { x: 197, y: 215 },
      { x: 197, y: 815 },
      { x: 397, y: 815 },
      { x: 397, y: 1115 },
      { x: 697, y: 1115 },
      { x: 697, y: 815 },
      { x: 897, y: 815 },
      { x: 897, y: 215 },
    ]

    const eightPoint3 = [
      { x: 200, y: 200 },
      { x: 200, y: 1000 },
      { x: 1000, y: 1000 },
      { x: 1000, y: 800 },
      { x: 600, y: 800 },
      { x: 600, y: 350 },
      { x: 1000, y: 350 },
      { x: 1000, y: 200 },
    ]

    const eightPoint4 = [
      { x: 200, y: 200 },
      { x: 200, y: 400 },
      { x: 500, y: 400 },
      { x: 500, y: 700 },
      { x: 800, y: 700 },
      { x: 800, y: 400 },
      { x: 1100, y: 400 },
      { x: 1100, y: 200 },
    ]

    const octaType1 = [
      { x: 100, y: 100 },
      { x: 100, y: 600 },
      { x: 650, y: 600 },
      { x: 650, y: 400 },
      { x: 350, y: 400 },
      { x: 350, y: 100 },
    ]

    if (canvas) {
      const polygon = new QPolygon(type1A, {
        // const polygon = new QPolygon(eightPoint, {
        fill: 'transparent',
        stroke: 'black',
        strokeWidth: 1,
        selectable: true,
        fontSize: fontSize,
        name: 'QPolygon1',
      })

      canvas?.add(polygon)

      console.log(polygon)

      handleOuterlinesTest2(polygon)

      // const lines = togglePolygonLine(polygon)
      // togglePolygonLine(lines[0])
    }
  }

  const rotateShape = () => {
    if (canvas) {
      const activeObject = canvas?.getActiveObject()

      if (activeObject) {
        activeObject.rotate(angle)
        canvas?.renderAll()
      }
    }
  }

  const makeQLine = () => {
    if (canvas) {
      const line = new QLine(
        [50, 250, 900, 250],
        {
          stroke: 'black',
          strokeWidth: 5,
          fontSize: fontSize,
          selectable: true,
        },
        50,
      )

      const line2 = new QLine(
        [450, 450, 821, 78],
        {
          stroke: 'black',
          strokeWidth: 5,
          fontSize: fontSize,
          selectable: true,
        },
        50,
      )

      canvas?.add(line)
      canvas?.add(line2)

      const interSectionPoint = calculateIntersection2(line, line2)

      if (interSectionPoint) {
        console.log(interSectionPoint)

        const circle = new fabric.Circle({
          radius: 5,
          fill: 'red',
          left: interSectionPoint.x - 5,
          top: interSectionPoint.y - 5,
        })

        canvas?.add(circle)
      }
    }
  }

  const addBackgroundInPolygon = (polygon) => {
    fabric.Image.fromURL('assets/img/check2.png', function(img) {
      // 패턴 객체를 생성합니다.
      const pattern = new fabric.Pattern({
        source: img.getElement(),
        repeat: 'repeat',
      })

      polygon.fillBackground(pattern)
    })
  }

  function PolygonToLine() {
    const polygon = canvas?.getActiveObject()

    if (polygon.type !== 'QPolygon') {
      return
    }

    const lines = togglePolygonLine(polygon)
  }

  /**
   * canvas 내용 저장하기
   */
  const handleSaveCanvas = async () => {
    // const jsonStr = JSON.stringify(canvas?.toDatalessJSON(['type', 'fontSize']))
    const jsonObj = JSON.stringify(canvas?.toDatalessJSON(['type', 'fontSize', 'lines']))
    console.log(jsonObj)

    const param = {
      loginId: 'test',
      canvas: jsonObj,
    }
    console.log(param)

    await insertCanvasState(param)
    handleClear()
  }

  /**
   * canvas 내용 불러오기
   */
  const handleLoadCanvas = async () => {
    const canvasStates = await getCanvasState()
    console.log(JSON.parse(canvasStates.canvas))
    canvas?.loadFromJSON(JSON.parse(canvasStates.canvas))
  }

  /**
   * 컨트롤러 보이기/숨기기
   */
  const handleShowController = () => {
    setShowControl(!showControl)
  }

  const drawRoofPatterns = (roofStyle) => {
    makeRoofPatternPolygon(roofStyle)
  }

  return (
    <>
      {canvas && (
        <>
          <div className=" my-8 w-full text:pretty">
            <Button className="m-1 p-2" color={`${mode === Mode.DEFAULT ? 'primary' : 'default'}`}
                    onClick={fillCellInPolygon}>
              모드 DEFAULT
            </Button>
            <Button
              className="m-1 p-2"
              color={`${mode === Mode.DRAW_LINE ? 'primary' : 'default'}`}
              onClick={() => changeMode(canvas, Mode.DRAW_LINE)}
            >
              기준선 긋기 모드
            </Button>
            <Button className="m-1 p-2" color={`${mode === Mode.EDIT ? 'primary' : 'default'}`}
                    onClick={() => changeMode(canvas, Mode.EDIT)}>
              에디팅모드
            </Button>
            <Button className="m-1 p-2" color={`${mode === Mode.TEMPLATE ? 'primary' : 'default'}`}
                    onClick={() => changeMode(canvas, Mode.TEMPLATE)}>
              템플릿(기둥)
            </Button>
            <Button className="m-1 p-2" color={`${mode === Mode.TEMPLATE ? 'primary' : 'default'}`}
                    onClick={() => changeMode(canvas, Mode.PATTERNA)}>
              템플릿(A 패턴)
            </Button>
            <Button className="m-1 p-2" color={`${mode === Mode.TEMPLATE ? 'primary' : 'default'}`}
                    onClick={() => changeMode(canvas, Mode.PATTERNB)}>
              템플릿(B 패턴)
            </Button>
            <Button className="m-1 p-2" color={`${mode === Mode.TEMPLATE ? 'primary' : 'default'}`}
                    onClick={() => drawRoofPatterns(1)}>
              지붕패턴1
            </Button>
            <Button className="m-1 p-2" color={`${mode === Mode.TEMPLATE ? 'primary' : 'default'}`}
                    onClick={() => drawRoofPatterns(2)}>
              지붕패턴2
            </Button>
            <Button className="m-1 p-2" color={`${mode === Mode.TEXTBOX ? 'primary' : 'default'}`}
                    onClick={() => changeMode(canvas, Mode.TEXTBOX)}>
              텍스트박스 모드
            </Button>
            <Button
              className="m-1 p-2"
              color={`${mode === Mode.DRAW_RECT ? 'primary' : 'default'}`}
              onClick={() => changeMode(canvas, Mode.DRAW_RECT)}
            >
              사각형 생성 모드
            </Button>
            <Button className="m-1 p-2" onClick={handleUndo}>
              Undo
            </Button>
            <Button className="m-1 p-2" onClick={handleRedo}>
              Redo
            </Button>
            <Button className="m-1 p-2" onClick={handleClear}>
              clear
            </Button>
            <Button className="m-1 p-2" onClick={zoomIn}>
              확대
            </Button>
            <Button className="m-1 p-2" onClick={zoomOut}>
              축소
            </Button>
            현재 줌 : {zoom}%
            <Button className="m-1 p-2" onClick={makeRect}>
              사각형만들기
            </Button>
            <Button className="m-1 p-2" onClick={makeLine}>
              선 추가
            </Button>
            <Button className="m-1 p-2" onClick={makePolygon}>
              다각형 추가
            </Button>
            <Button
              className="m-1 p-2"
              onClick={() => {
                setCanvasBackgroundWithDots(canvas, 10)
              }}
            >
              점선 추가
            </Button>
            <Button
              className="m-1 p-2"
              onClick={() => {
                setCanvasBackgroundWithDots(canvas, 20)
              }}
            >
              점선 추가
            </Button>
            <Button className="m-1 p-2" onClick={saveImage}>
              저장
            </Button>
            <Button className="m-1 p-2" onClick={makeQPolygon}>
              QPolygon
            </Button>
            <Button className="m-1 p-2" onClick={rotateShape}>
              회전
            </Button>
            <Button className="m-1 p-2" onClick={makeQLine}>
              QLine
            </Button>
            <Button className="m-1 p-2" onClick={PolygonToLine}>
              PolygonToLine
            </Button>
            {/*<Button className="m-1 p-2" onClick={handleSaveCanvas}>
              canvas 내용 저장하기
            </Button>
            <Button className="m-1 p-2" onClick={handleLoadCanvas}>
              canvas 내용 불러오기
            </Button>*/}
            <Button className="m-1 p-2" onClick={addCanvas}>
              캔버스 추가
            </Button>
            <Button className="m-1 p-2" color={`${showControl ? 'primary' : 'default'}`} onClick={handleShowController}>
              canvas 컨트롤러 {`${showControl ? '숨기기' : '보이기'}`}
            </Button>
          </div>
          <div className={showControl ? `flex justify-center flex-col items-center` : `hidden`}>
            <div className="m-2 p-2 w-80">
              <RangeSlider title={`각도${angle}`} initValue={angle} min="0" step="1" max="360" onchange={setAngle} />
            </div>
            <div className="m-2 p-2 w-80">
              <RangeSlider
                title={`canvas 가로 사이즈${horizontalSize}`}
                initValue={horizontalSize}
                min="500"
                step="100"
                max="2000"
                onchange={setHorizontalSize}
              />
            </div>
            <div className="m-2 p-2 w-80">
              <RangeSlider
                title={`canvas 세로 사이즈${verticalSize}`}
                initValue={verticalSize}
                min="500"
                step="100"
                max="2000"
                onchange={setVerticalSize}
              />
            </div>
            <div className="m-2 p-2 w-80">
              <RangeSlider title={`글자 크기${fontSize}`} initValue={fontSize} onchange={setFontSize} />
            </div>
          </div>
        </>
      )}
      <div className="flex justify-start my-8 mx-2 w-full">
        <canvas id="canvas" style={{ border: '1px solid black' }} />
      </div>
    </>
  )
}
