import WithDraggable from '@/components/common/draggable/WithDraggable'
import { useState, useEffect, useContext } from 'react'
import PowerConditionalSelect from '@/components/floor-plan/modal/circuitTrestle/step/PowerConditionalSelect'
import CircuitAllocation from '@/components/floor-plan/modal/circuitTrestle/step/CircuitAllocation'
import StepUp from '@/components/floor-plan/modal/circuitTrestle/step/StepUp'
import { useMessage } from '@/hooks/useMessage'
import { usePopup } from '@/hooks/usePopup'
import PassivityCircuitAllocation from './step/type/PassivityCircuitAllocation'
import { useMasterController } from '@/hooks/common/useMasterController'
import { correntObjectNoState } from '@/store/settingAtom'
import { useRecoilValue } from 'recoil'
import { GlobalDataContext } from '@/app/GlobalDataProvider'
import { useRecoilState } from 'recoil'
import { makersState, modelsState, modelState, pcsCheckState, selectedMakerState, selectedModelsState, seriesState } from '@/store/circuitTrestleAtom'
import { POLYGON_TYPE } from '@/common/common'
import { useSwal } from '@/hooks/useSwal'
import { canvasState } from '@/store/canvasAtom'

import { useTrestle } from '@/hooks/module/useTrestle'
import { selectedModuleState } from '@/store/selectedModuleOptions'
import { v4 as uuidv4 } from 'uuid'

import { stepUpListDataState } from '@/store/circuitTrestleAtom'

const ALLOCATION_TYPE = {
  AUTO: 'auto',
  PASSIVITY: 'passivity',
}
export default function CircuitTrestleSetting({ id }) {
  const { getMessage } = useMessage()
  const { closePopup } = usePopup()
  const { apply } = useTrestle()
  const { swalFire } = useSwal()
  const canvas = useRecoilValue(canvasState)

  const [makers, setMakers] = useRecoilState(makersState)
  const [selectedMaker, setSelectedMaker] = useRecoilState(selectedMakerState)
  const [series, setSeries] = useRecoilState(seriesState)
  const [models, setModels] = useRecoilState(modelsState)
  const [selectedModels, setSelectedModels] = useRecoilState(selectedModelsState)
  const [pcsCheck, setPcsCheck] = useRecoilState(pcsCheckState)

  const [tabNum, setTabNum] = useState(1)
  const [allocationType, setAllocationType] = useState(ALLOCATION_TYPE.AUTO)
  const [circuitAllocationType, setCircuitAllocationType] = useState(1)
  const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext)
  const selectedModules = useRecoilValue(selectedModuleState)
  const { getPcsAutoRecommendList, getPcsVoltageChk } = useMasterController()

  // 회로할당(승합설정)에서 선택된 값들을 저장할 상태 추가
  const [selectedStepUpValues, setSelectedStepUpValues] = useState({})
  const [getStepUpSelections, setGetStepUpSelections] = useState(null)

  const [stepUpListData, setStepUpListData] = useRecoilState(stepUpListDataState)

  useEffect(() => {
    if (!managementState) {
      setManagementState(managementStateLoaded)
    }
  }, [])

  useEffect(() => {
    if (allocationType === ALLOCATION_TYPE.PASSIVITY && tabNum === 2) {
      const notAllocationModules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE && !obj.circuit)
      canvas.remove(...notAllocationModules)
      canvas.renderAll()
    }
  }, [tabNum])

  useEffect(() => {
    console.log('stepUpListData >>> ', stepUpListData)
  }, [stepUpListData])

  const onAutoRecommend = () => {
    if (series.filter((s) => s.selected).length === 0) {
      swalFire({
        title: '시리즈를 선택해 주세요.',
        type: 'alert',
      })
      return
    }

    const params = {
      ...getOptYn(),
      useModuleItemList: getUseModuleItemList(),
      roofSurfaceList: getRoofSurfaceList(),
      pcsItemList: getPcsItemList(),
    }

    if (selectedModels.length === 0) {
      getPcsAutoRecommendList(params).then((res) => {
        if (res.data?.pcsItemList) {
          const itemList = models.filter((model) => {
            return res.data?.pcsItemList.map((item) => item.itemId).includes(model.itemId)
          })
          const selectedModels = itemList.map((model) => {
            return {
              ...model,
              id: uuidv4(),
            }
          })
          const pcsVoltageChkParams = {
            ...getOptYn(),
            useModuleItemList: getUseModuleItemList(),
            roofSurfaceList: getRoofSurfaceList(),
            pcsItemList: getPcsItemList(),
          }
          setSelectedModels(selectedModels)
          getPcsVoltageChk(pcsVoltageChkParams).then((res) => {
            setTabNum(2)
          })
        } else {
          // 데이터가 없는 경우 오류 메시지 확인 필요
          if (res.result.resultCode === 'E') {
            swalFire({
              title: res.result.resultMsg,
              type: 'alert',
            })
          } else {
            swalFire({
              title: '파워컨디셔너를 추가해 주세요.',
              type: 'alert',
            })
          }
        }
      })
    } else {
      getPcsVoltageChk(params).then((res) => {
        setTabNum(2)
      })
    }
  }

  const getOptYn = () => {
    return {
      maxConnYn: pcsCheck.max ? 'Y' : 'N',
      smpCirYn: pcsCheck.division ? 'Y' : 'N',
      coldZoneYn: managementState?.coldRegionFlg === '1' ? 'Y' : 'N',
    }
  }

  const getPcsItemList = () => {
    return models.map((model) => {
      return {
        itemId: model.itemId,
        pcsMkrCd: model.pcsMkrCd,
        pcsSerCd: model.pcsSerCd,
      }
    })
  }

  const getUseModuleItemList = () => {
    return selectedModules.itemList.map((m) => {
      return {
        itemId: m.itemId,
        mixMatlNo: m.mixMatlNo,
      }
    })
  }

  const getRoofSurfaceList = () => {
    return canvas
      .getObjects()
      .filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
      .map((obj) => {
        getModuleList(obj)
        return {
          roofSurfaceId: obj.id,
          roofSurface: canvas
            .getObjects()
            .filter((o) => o.id === obj.parentId)[0]
            .directionText.replace(/[0-9]/g, ''),
          roofSurfaceIncl: canvas.getObjects().filter((o) => o.id === obj.parentId)[0].roofMaterial.pitch,
          moduleList: getModuleList(obj).map((module) => {
            return {
              itemId: module.moduleInfo.itemId,
              circuit: module.circuitNumber ? module.circuitNumber : null,
              pcsItemId: module.circuit ? module.circuit?.pcsItemId : null,
              uniqueId: module.id ? module.id : null,
            }
          }),
        }
      })
  }

  const getModuleList = (surface) => {
    let moduleList = []
    let [xObj, yObj] = [{}, {}]
    let [xPoints, yPoints] = [[], []]
    surface.modules.forEach((module) => {
      if (!xObj[module.left]) {
        xObj[module.left] = module.left
        xPoints.push(module.left)
      }
      if (!yObj[module.top]) {
        yObj[module.top] = module.top
        yPoints.push(module.top)
      }
    })
    switch (surface.direction) {
      case 'south':
        xPoints.sort((a, b) => a - b)
        yPoints.sort((a, b) => b - a)
        yPoints.forEach((y, index) => {
          let temp = surface.modules.filter((m) => m.top === y)
          if (index % 2 === 0) {
            temp.sort((a, b) => a.left - b.left)
          } else {
            temp.sort((a, b) => b.left - a.left)
          }
          moduleList = [...moduleList, ...temp]
        })
        break
      case 'north':
        xPoints.sort((a, b) => b - a)
        yPoints.sort((a, b) => a - b)
        yPoints.forEach((y, index) => {
          let temp = surface.modules.filter((m) => m.top === y)
          if (index % 2 === 0) {
            temp.sort((a, b) => b.left - a.left)
          } else {
            temp.sort((a, b) => a.left - b.left)
          }
          moduleList = [...moduleList, ...temp]
        })
        break
      case 'west':
        xPoints.sort((a, b) => a - b)
        yPoints.sort((a, b) => a - b)
        xPoints.forEach((x, index) => {
          let temp = surface.modules.filter((m) => m.left === x)
          if (index % 2 === 0) {
            temp.sort((a, b) => a.top - b.top)
          } else {
            temp.sort((a, b) => b.top - a.top)
          }
          moduleList = [...moduleList, ...temp]
        })
        break
      case 'east':
        xPoints.sort((a, b) => b - a)
        yPoints.sort((a, b) => b - a)
        xPoints.forEach((x, index) => {
          let temp = surface.modules.filter((m) => m.left === x)
          if (index % 2 === 0) {
            temp.sort((a, b) => b.top - a.top)
          } else {
            temp.sort((a, b) => a.top - b.top)
          }
          moduleList = [...moduleList, ...temp]
        })
        break
      default:
        return []
    }
    return moduleList
  }

  const onAutoAllocation = () => {
    let moduleStdQty = 0
    let moduleMaxQty = 0
    const selectedModels = models.filter((m) => m.selected)

    if (selectedModels.length === 0) {
      onAutoRecommend()
    } else {
      moduleStdQty = selectedModels.reduce((acc, model) => {
        return acc + parseInt(model.moduleStdQty)
      }, 0)
      moduleMaxQty = selectedModels.reduce((acc, model) => {
        return acc + parseInt(model.moduleMaxQty)
      }, 0)
    }
    // const target = pcsCheck.max ? moduleMaxQty : moduleStdQty
    // const placementModules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE)

    // if (placementModules.length > target) {
    //   swalFire({
    //     title: '배치가능 매수를 초과합니다. 파워컨디셔너를 다시 선택해 주세요.',
    //     type: 'alert',
    //   })
    //   return
    // }

    // setAllocationType(ALLOCATION_TYPE.AUTO)
    // setTabNum(2)
  }

  const onPassivityAllocation = () => {
    if (selectedModels.length === 0) {
      const params = {
        ...getOptYn(),
        useModuleItemList: getUseModuleItemList(),
        roofSurfaceList: getRoofSurfaceList(),
        pcsItemList: getPcsItemList(),
      }

      getPcsAutoRecommendList(params).then((res) => {
        if (res.data?.pcsItemList) {
          const itemList = models.filter((model) => {
            return res.data?.pcsItemList.map((item) => item.itemId).includes(model.itemId)
          })
          const selectedModels = itemList.map((model) => {
            return {
              ...model,
              id: uuidv4(),
            }
          })
          const PcsVoltageChkParams = {
            ...getOptYn(),
            useModuleItemList: getUseModuleItemList(),
            roofSurfaceList: getRoofSurfaceList(),
            pcsItemList: getPcsItemList(),
          }
          setSelectedModels(selectedModels)
          getPcsVoltageChk(PcsVoltageChkParams).then((res) => {})
        } else {
          swalFire({
            title: '파워컨디셔너를 추가해 주세요.',
            type: 'alert',
          })
        }
      })
    } else if (pcsCheck.max) {
      const moduleStdQty = selectedModels.reduce((acc, model) => {
        return acc + parseInt(model.moduleStdQty)
      }, 0)
      const moduleMaxQty = selectedModels.reduce((acc, model) => {
        return acc + parseInt(model.moduleMaxQty)
      }, 0)

      const target = pcsCheck.max ? moduleMaxQty : moduleStdQty
      const placementModules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE)

      if (placementModules.length > target) {
        swalFire({
          title: '배치가능 매수를 초과합니다. 파워컨디셔너를 다시 선택해 주세요.',
          type: 'alert',
        })
        return
      }
    }

    setAllocationType(ALLOCATION_TYPE.PASSIVITY)
  }

  // StepUp에서 선택된 값들을 처리하는 함수 수정
  const handleStepUpValuesSelected = (selectionData) => {
    const { gooodsNo } = selectionData

    setSelectedStepUpValues((prev) => ({
      ...prev,
      [gooodsNo]: selectionData,
    }))
  }

  // StepUp 컴포넌트 초기화 핸들러
  const handleStepUpInitialize = (getCurrentSelections) => {
    setGetStepUpSelections(() => getCurrentSelections)
  }

  // apply 함수 수정
  const onApply = () => {
    // 현재 선택된 값들 가져오기
    const currentSelections = getStepUpSelections ? getStepUpSelections() : {}

    console.log('currentSelections >>> ', currentSelections)

    // 실제 선택된 값이 있는지 더 정확하게 확인
    const hasSelections = Object.values(currentSelections).some((stepUpConfig) => Object.values(stepUpConfig).length > 0)

    console.log('hasSelections >>> ', hasSelections)

    if (!hasSelections) {
      swalFire({
        title: '승압 설정값을 선택해주세요.1',
        type: 'alert',
      })
      return
    }

    // 선택된 값들 로그
    console.log('Applying StepUp configurations:', currentSelections)

    // StepUp 컴포넌트로부터 stepUpListData 받아오기
    //const stepUpData = getStepUpSelections().stepUpListData
    //console.log('stepUpData >>> ', stepUpData)
    // stepUpListData를 Recoil state에 저장
    // setStepUpListData(stepUpData)

    // 선택된 값들을 배열로 변환하여 처리
    const configurations = Object.values(currentSelections)
      .map((stepUpConfig) => {
        const firstConfig = Object.values(stepUpConfig)[0] // 첫 번째 설정만 사용
        return {
          pcsInfo: firstConfig.pcsInfo,
          allocation: firstConfig.allocation,
        }
      })
      .filter((config) => config.pcsInfo && config.allocation) // 유효한 설정만 필터링

    console.log('Processed configurations:', configurations)

    // stepUpListData를 Recoil state에 저장
    setStepUpListData(configurations)

    // 기존 apply 로직 실행 전에 필요한 데이터가 모두 있는지 확인
    if (configurations.length > 0) {
      apply()
    } else {
      swalFire({
        title: '승압 설정값을 선택해주세요.2',
        type: 'alert',
      })
    }
  }

  const onClickPrev = () => {
    setAllocationType(ALLOCATION_TYPE.AUTO)
    swalFire({
      text: '할당한 회로 번호가 초기화됩니다.',
      type: 'alert',
      icon: 'warning',
      confirmFn: () => {
        const circuitModules = canvas
          .getObjects()
          .filter((obj) => obj.name === 'module' && selectedModels.map((model) => model.id).includes(obj.circuit?.circuitInfo?.id))
        canvas.remove(...circuitModules.map((module) => module.circuit))
        circuitModules.forEach((obj) => {
          obj.circuit = null
          obj.pcsItemId = null
        })
      },
    })
  }

  const powerConditionalSelectProps = {
    tabNum,
    setTabNum,
    makers,
    setMakers,
    selectedMaker,
    setSelectedMaker,
    series,
    setSeries,
    models,
    setModels,
    selectedModels,
    setSelectedModels,
    managementState,
  }

  const passivityProps = {
    tabNum,
    setTabNum,
    pcsCheck,
    selectedModels,
    setSelectedModels,
    getOptYn,
    getUseModuleItemList,
    getRoofSurfaceList,
  }

  const stepUpProps = {
    tabNum,
    setTabNum,
    models,
    setModels,
    circuitAllocationType,
    setCircuitAllocationType,
    getOptYn, // 옵션 Y/N
    getUseModuleItemList, // 사용된 모듈아이템 List
    getRoofSurfaceList, // 지붕면 목록
    getPcsItemList, // PCS 아이템 목록
    onValuesSelected: handleStepUpValuesSelected, // 선택된 값들을 처리하는 함수
  }

  return (
    <WithDraggable isShow={true} pos={{ x: 50, y: 230 }}>
      <div className={`modal-pop-wrap l-2`}>
        <div className="modal-head modal-handle">
          <h1 className="title">{getMessage('modal.circuit.trestle.setting')} </h1>
          <button className="modal-close" onClick={() => closePopup(id)}>
            닫기
          </button>
        </div>
        <div className="modal-body">
          <div className="roof-module-tab">
            <div className={`module-tab-bx act`}>{getMessage('modal.circuit.trestle.setting.power.conditional.select')}</div>
            <span className={`tab-arr ${tabNum === 2 ? 'act' : ''}`}></span>
            <div className={`module-tab-bx ${tabNum === 2 ? 'act' : ''}`}>
              {getMessage('modal.circuit.trestle.setting.circuit.allocation')}({getMessage('modal.circuit.trestle.setting.step.up.allocation')})
            </div>
          </div>
          {tabNum === 1 && allocationType === ALLOCATION_TYPE.AUTO && <PowerConditionalSelect {...powerConditionalSelectProps} />}
          {tabNum === 1 && allocationType === ALLOCATION_TYPE.PASSIVITY && <PassivityCircuitAllocation {...passivityProps} />}
          {tabNum === 2 && <StepUp {...stepUpProps} onInitialize={handleStepUpInitialize} />}
          {tabNum === 1 && allocationType === ALLOCATION_TYPE.AUTO && (
            <div className="grid-btn-wrap">
              <button className="btn-frame modal mr5" onClick={() => onAutoAllocation()}>
                {getMessage('modal.circuit.trestle.setting.circuit.allocation.auto')}
              </button>
              <button className="btn-frame modal act" onClick={() => onPassivityAllocation()}>
                {getMessage('modal.circuit.trestle.setting.circuit.allocation.passivity')}
              </button>
            </div>
          )}
          {tabNum === 1 && allocationType === ALLOCATION_TYPE.PASSIVITY && (
            <div className="grid-btn-wrap">
              <button className="btn-frame modal mr5" onClick={() => setAllocationType(ALLOCATION_TYPE.AUTO)}>
                {getMessage('modal.common.prev')}
              </button>
              <button className="btn-frame modal act" onClick={() => setTabNum(2)}>
                {getMessage('modal.circuit.trestle.setting.circuit.allocation')}({getMessage('modal.circuit.trestle.setting.step.up.allocation')})
              </button>
            </div>
          )}
          {tabNum === 2 && (
            <div className="grid-btn-wrap">
              <button className="btn-frame modal mr5" onClick={() => setTabNum(1)}>
                {getMessage('modal.common.prev')}
              </button>
              {/* <button className="btn-frame modal act" onClick={() => apply()}> */}
              <button className="btn-frame modal act" onClick={onApply}>
                {getMessage('modal.common.save')}({getMessage('modal.circuit.trestle.setting.circuit.allocation')})
              </button>
            </div>
          )}
        </div>
        <div className="modal-foot modal-handle"></div>
      </div>
    </WithDraggable>
  )
}
