'use client'

import Image from 'next/image'
import { useState, useEffect, useCallback, useRef, useMemo } from 'react'
import SuitableButton from './SuitableButton'
import SuitableNoData from './SuitableNoData'
import { useSuitable } from '@/hooks/useSuitable'
import { useSuitableStore } from '@/store/useSuitableStore'
import { useSpinnerStore } from '@/store/spinnerStore'
import { SUITABLE_HEAD_CODE, type Suitable, type SuitableDetail } from '@/types/Suitable'

export default function SuitableList() {
  const {
    toCodeName,
    toSuitableDetail,
    toSuitableDetailIds,
    suitables,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
    isLoading,
    suitableCheckIcon,
  } = useSuitable()
  const { selectedItems, addSelectedItem, removeSelectedItem } = useSuitableStore()
  const [openItems, setOpenItems] = useState<Set<number>>(new Set())
  const observerTarget = useRef<HTMLDivElement>(null)

  /* 선택된 아이템 확인 - 메인 하위 아이템 indeterminate 확인 */
  const isMainIndeterminate = useMemo(
    () => (mainId: number, detailCnt: number) => {
      const mainItem = selectedItems.get(mainId)
      if (!mainItem) return false
      return mainItem.size > 0 && mainItem.size < detailCnt
    },
    [selectedItems],
  )

  /* 선택된 아이템 확인 */
  const isItemSelected = useCallback(
    (mainId: number, detailId?: number): boolean => {
      const mainItem = selectedItems.get(mainId)
      if (!mainItem) return false
      if (!detailId) return true
      return mainItem.has(detailId)
    },
    [selectedItems],
  )

  /* 아이템 클릭 */
  const handleItemClick = useCallback(
    (mainId: number, detailId?: number, detailIds?: Set<number>): void => {
      isItemSelected(mainId, detailId) ? removeSelectedItem(mainId, detailId) : addSelectedItem(mainId, detailId, detailIds)
    },
    [isItemSelected, addSelectedItem, removeSelectedItem],
  )

  /* 아이템 열기/닫기 */
  const toggleItemOpen = useCallback((itemId: number) => {
    setOpenItems((prev) => {
      const newOpenItems = new Set(prev)
      newOpenItems.has(itemId) ? newOpenItems.delete(itemId) : newOpenItems.add(itemId)
      return newOpenItems
    })
  }, [])

  /* 아이템 렌더링 */
  const renderItem = useCallback(
    (item: Suitable) => {
      return (
        <div className={`compliance-check-bx ${openItems.has(item.id) ? 'act' : ''}`} key={item.id}>
          <div className="check-name-wrap">
            <div className={`check-form-box ${isMainIndeterminate(item.id, item.detailCnt) ? 'space' : ''}`}>
              <input
                type="checkbox"
                id={`ch${item.id}`}
                checked={isItemSelected(item.id)}
                onChange={() => handleItemClick(item.id, undefined, toSuitableDetailIds(item.detail))}
              />
              <label htmlFor={`ch${item.id}`}>{item.productName}</label>
            </div>
            <div className="check-name-btn">
              <button className="bx-btn" onClick={() => toggleItemOpen(item.id)}></button>
            </div>
          </div>
          <ul className="reference-list check">
            {toSuitableDetail(item.detail)?.map((subItem: SuitableDetail) => (
              <li className="reference-item" key={subItem.id}>
                <div className="check-item-wrap">
                  <div className="check-form-box light">
                    <input
                      type="checkbox"
                      id={`ch${subItem.id}`}
                      checked={isItemSelected(item.id, subItem.id)}
                      onChange={() => handleItemClick(item.id, subItem.id)}
                    />
                    <label htmlFor={`ch${subItem.id}`}>{toCodeName(SUITABLE_HEAD_CODE.TRESTLE_MFPC_CD, subItem.trestleMfpcCd)}</label>
                  </div>
                  <div className="compliance-icon-wrap">
                    <div className="compliance-icon">
                      <Image src={suitableCheckIcon(subItem.trestleManufacturerProductName)} width={22} height={22} alt="" />
                    </div>
                    {subItem.memo && (
                      <div className="compliance-icon">
                        <Image src={'/assets/images/sub/compliance_tip_icon.svg'} width={22} height={22} alt=""></Image>
                      </div>
                    )}
                  </div>
                </div>
              </li>
            ))}
          </ul>
        </div>
      )
    },
    [isItemSelected, openItems, handleItemClick, toggleItemOpen, toCodeName, toSuitableDetail],
  )

  /* 조회 데이터 리스트 */
  const suitableList = useMemo(() => suitables?.pages.flat() ?? [], [suitables?.pages])

  /* Intersection Observer 설정 */
  useEffect(() => {
    const observer = new IntersectionObserver(
      (entries) => {
        if (entries[0].isIntersecting && hasNextPage && !isFetchingNextPage) {
          fetchNextPage()
        }
      },
      {
        threshold: 0,
        rootMargin: `${window.innerHeight * 0.2}px`,
      },
    )

    if (observerTarget.current) {
      observer.observe(observerTarget.current)
    }

    return () => observer.disconnect()
  }, [hasNextPage, isFetchingNextPage, fetchNextPage])

  /* 데이터 로딩 상태 처리 */
  useEffect(() => {
    useSpinnerStore.getState().setIsShow(isLoading || isFetchingNextPage)
  }, [isLoading, isFetchingNextPage])

  /* 조회 데이터 없는 경우 */
  if (!suitableList.length) return <SuitableNoData />

  return (
    <>
      {suitableList.map(renderItem)}
      <div ref={observerTarget} />
      <SuitableButton />
    </>
  )
}
