'use client'

import { AppSidebar } from "@/components/layout/app-sidebar"
import { SiteHeader } from "@/components/layout/site-header"
import { CowNumberDisplay } from "@/components/common/cow-number-display"
import {
  SidebarInset,
  SidebarProvider,
} from "@/components/ui/sidebar"
import { Button } from "@/components/ui/button"
import { Cow, CowWithGenes, RankingItem } from "@/types/cow.types"
import { useEffect, useState, useRef } from "react"
import { useRouter } from "next/navigation"
import { ChevronLeft, ChevronRight, Search, Filter, Settings } from "lucide-react"
import { Input } from "@/components/ui/input"
import { Badge } from "@/components/ui/badge"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { cowApi } from "@/lib/api/cow.api"
import { TRAIT_DISPLAY_NAMES } from "@/constants/traits"
import { useAuthStore } from "@/store/auth-store"
import { useFilterStore } from "@/store/filter-store"
import { AnalysisYearProvider } from "@/contexts/AnalysisYearContext"
import { AuthGuard } from "@/components/auth/auth-guard"

/**
 * 개체 리스트 페이지
 */
function MyCowContent() {
  const [cows, setCows] = useState<CowWithGenes[]>([])
  const [filteredCows, setFilteredCows] = useState<CowWithGenes[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const router = useRouter()
  const { user } = useAuthStore()
  const { filters, isLoading: isFilterLoading } = useFilterStore()

  // 로컬 필터 상태 (검색, 랭킹모드, 정렬) - localStorage에서 초기값 로드
  const [searchKeyword, setSearchKeyword] = useState(() => {
    if (typeof window !== 'undefined') {
      const saved = localStorage.getItem('cowListSearchKeyword')
      return saved || ''
    }
    return ''
  })
  const [rankingMode, setRankingMode] = useState<'gene' | 'genome'>('gene') // 유전자순/유전체순
  const [sortBy, setSortBy] = useState<'rank' | 'number' | 'birth' | 'dam' | 'sire' | 'monthAge' | 'analysisDate' | 'score'>(() => {
    if (typeof window !== 'undefined') {
      const saved = localStorage.getItem('cowListSortBy')
      if (saved && ['rank', 'number', 'birth', 'dam', 'sire', 'monthAge', 'analysisDate', 'score'].includes(saved)) {
        return saved as 'rank' | 'number' | 'birth' | 'dam' | 'sire' | 'monthAge' | 'analysisDate' | 'score'
      }
    }
    return 'rank'
  })
  const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>(() => {
    if (typeof window !== 'undefined') {
      const saved = localStorage.getItem('cowListSortOrder')
      if (saved === 'asc' || saved === 'desc') {
        return saved
      }
    }
    return 'asc'
  })
  const [analysisFilter, setAnalysisFilter] = useState<'all' | 'pedigreeMatch' | 'pedigreeMismatch' | 'mptOnly'>(() => {
    if (typeof window !== 'undefined') {
      const saved = localStorage.getItem('cowListAnalysisFilter')
      if (saved && ['all', 'pedigreeMatch', 'pedigreeMismatch', 'mptOnly'].includes(saved)) {
        return saved as 'all' | 'pedigreeMatch' | 'pedigreeMismatch' | 'mptOnly'
      }
    }
    return 'all'
  })

  // 커스텀 컬럼 표시 필터
  const [selectedDisplayGenes, setSelectedDisplayGenes] = useState<string[]>([]) // 테이블에 표시할 유전자
  const [selectedDisplayTraits, setSelectedDisplayTraits] = useState<string[]>([]) // 테이블에 표시할 형질
  const [availableGenes, setAvailableGenes] = useState<string[]>([]) // 선택 가능한 유전자 목록
  const [availableTraits, setAvailableTraits] = useState<string[]>([]) // 선택 가능한 형질 목록 (전역 필터 순서 유지)
  const [expandedRows, setExpandedRows] = useState<Set<number | string>>(new Set()) // 유전자형 더보기 펼침 상태 (pkCowNo 또는 "pkCowNo-traits" 형태)
  const [theadTraitIndex, setTheadTraitIndex] = useState<number>(0) // thead 형질 네비게이션 시작 인덱스
  const [rowTraitIndices, setRowTraitIndices] = useState<Map<number, number>>(new Map()) // 각 행별 형질 인덱스
  
  // 형질 태그 실제 크기 측정용
  const firstTraitRef = useRef<HTMLDivElement>(null)
  const [calculatedMoveDistance, setCalculatedMoveDistance] = useState(78) // 동적 계산된 이동 거리

  // 초기 마운트 추적
  const isInitialMount = useRef(true)
  
  // 이전 값 추적 (실제 변경 감지용)
  const prevAnalysisFilter = useRef<string | null>(null)
  const prevItemsPerPage = useRef<number | null>(null)
  const prevSearchKeyword = useRef<string | null>(null)

  // 형질 태그 실제 크기 측정 및 이동 거리 계산
  useEffect(() => {
    const measureTraitWidth = () => {
      if (firstTraitRef.current) {
        const traitWidth = firstTraitRef.current.offsetWidth
        const gap = 8 // gap-2
        const moveDistance = traitWidth + gap
        
        setCalculatedMoveDistance(moveDistance)
        
        console.log('[형질 이동 거리 계산]', {
          형질폭: traitWidth,
          gap간격: gap,
          이동거리: moveDistance
        })
      }
    }

    // 초기 측정
    const timer = setTimeout(measureTraitWidth, 100)

    // 화면 크기 변경 감지
    const resizeObserver = new ResizeObserver(measureTraitWidth)
    if (firstTraitRef.current) {
      resizeObserver.observe(firstTraitRef.current)
    }

    return () => {
      clearTimeout(timer)
      resizeObserver.disconnect()
    }
  }, [selectedDisplayTraits, filteredCows])

  // 무한 스크롤 페이지네이션
  const [currentLoadedPage, setCurrentLoadedPage] = useState(() => {
    if (typeof window !== 'undefined') {
      const saved = localStorage.getItem('cowListLoadedPage')
      return saved ? parseInt(saved, 10) : 1
    }
    return 1
  })
  const [itemsPerPage, setItemsPerPage] = useState(() => {
    if (typeof window !== 'undefined') {
      const saved = localStorage.getItem('cowListItemsPerPage')
      return saved ? parseInt(saved, 10) : 50
    }
    return 50
  })
  const [displayedCows, setDisplayedCows] = useState<CowWithGenes[]>([]) // 화면에 표시되는 소 목록
  const tableScrollRef = useRef<HTMLDivElement>(null) // 테이블 스크롤 ref
  const [isLoadingMore, setIsLoadingMore] = useState(false) // 추가 로딩 중


  // 형질 가중치가 1개 이상 설정되어야 필터 활성화
  const isFilterSet = filters.isActive && Object.values(filters.traitWeights).some(w => w > 0)

  // ========================================
  // URL 파라미터로 초기화 여부 확인 (사이드바 클릭 시)
  // ========================================
  useEffect(() => {
    if (typeof window !== 'undefined') {
      const urlParams = new URLSearchParams(window.location.search)
      const reset = urlParams.get('reset')
      
      if (reset === 'true') {
        // 초기화
        setCurrentLoadedPage(1)
        setItemsPerPage(50)
        setAnalysisFilter('all')
        setSortBy('rank')
        setSortOrder('asc')
        setSearchKeyword('')
        
        // localStorage 초기화
        localStorage.setItem('cowListLoadedPage', '1')
        localStorage.setItem('cowListItemsPerPage', '50')
        localStorage.setItem('cowListAnalysisFilter', 'all')
        localStorage.setItem('cowListSortBy', 'rank')
        localStorage.setItem('cowListSortOrder', 'asc')
        localStorage.setItem('cowListSearchKeyword', '')
        
        // URL에서 reset 파라미터 제거
        window.history.replaceState({}, '', '/cow')
      }
    }
  }, [])

  // ========================================
  // 상태를 localStorage에 저장
  // ========================================
  // localStorage 저장은 displayedCows useEffect에서 처리
  // useEffect(() => {
  //   if (typeof window !== 'undefined') {
  //     localStorage.setItem('cowListLoadedPage', currentLoadedPage.toString())
  //   }
  // }, [currentLoadedPage])

  useEffect(() => {
    if (typeof window !== 'undefined') {
      localStorage.setItem('cowListItemsPerPage', itemsPerPage.toString())
    }
  }, [itemsPerPage])

  useEffect(() => {
    if (typeof window !== 'undefined') {
      localStorage.setItem('cowListSearchKeyword', searchKeyword)
    }
  }, [searchKeyword])

  useEffect(() => {
    if (typeof window !== 'undefined') {
      localStorage.setItem('cowListAnalysisFilter', analysisFilter)
    }
  }, [analysisFilter])

  useEffect(() => {
    if (typeof window !== 'undefined') {
      localStorage.setItem('cowListSortBy', sortBy)
    }
  }, [sortBy])

  useEffect(() => {
    if (typeof window !== 'undefined') {
      localStorage.setItem('cowListSortOrder', sortOrder)
    }
  }, [sortOrder])

  // ========================================
  // 전역 필터 → 개체 리스트 표시 항목 동기화
  // ========================================
  useEffect(() => {
    if (isFilterLoading) return  // 필터 로딩 중이면 건너뛰기

    const hasGenes = filters.isActive && filters.selectedGenes && filters.selectedGenes.length > 0
    const hasTraits = filters.isActive && Object.values(filters.traitWeights).some(w => w > 0)

    // 1. 마커 유전자 표시 목록 동기화 (육량형 , 육질형 추후 추가 연동 예정)
    if (hasGenes) {
      const pinnedGenes = filters.pinnedGenes || []
      setAvailableGenes(filters.selectedGenes)
      const pinnedInOrder = filters.selectedGenes.filter(g => pinnedGenes.includes(g))
      setSelectedDisplayGenes(pinnedGenes.length > 0 ? pinnedInOrder : filters.selectedGenes)
    } else {
      setAvailableGenes([])
      setSelectedDisplayGenes([])
    }

    // 2. 형질 표시 목록 동기화 (유전체형질: traitWeights > 0인 것만, 상위 7개)
    if (filters.isActive && filters.traitWeights) {
      // traitWeights > 0인 형질만 추출 (유전체형질)
      const genomeTraits = Object.entries(filters.traitWeights)
        .filter(([_, weight]) => weight > 0)
        .map(([traitName, _]) => traitName)
      
      // 상위 7개까지만 표시
      const topSevenTraits = genomeTraits.slice(0, 7)
      setAvailableTraits(topSevenTraits)
      setSelectedDisplayTraits(topSevenTraits)
    } else {
      setAvailableTraits([])
      setSelectedDisplayTraits([])
    }

    // 3. 랭킹 모드 자동 설정
    //    - 유전자 선택됨 → 유전자순 (GENE 모드)
    //    - 형질만 선택됨 → 유전체순 (GENOME 모드)
    if (filters.isActive) {
      if (hasGenes) {
        setRankingMode('gene')
      } else if (hasTraits) {
        setRankingMode('genome')
      }
    }
  }, [isFilterLoading, filters.isActive, filters.selectedGenes, filters.selectedTraits, filters.pinnedGenes, filters.pinnedTraits, filters.traitWeights])

  // ========================================
  // 개체 데이터 조회 (Ranking API)
  // ========================================
  useEffect(() => {
    const fetchCows = async () => {
      if (!isFilterSet) {
        setLoading(false)  // 필터가 설정되지 않았으면 API 호출하지 않음
        setCows([])
        setFilteredCows([])
        return
      }

      try {
        setLoading(true) // 필터가 설정되면 API 호출
        setError(null)

        // 1. 사용자 농장 필터 생성
        let farmFilters: { field: string; operator: 'in'; value: number[] }[] = []
        try {
          const userNo = user?.pkUserNo
          if (userNo) {
            const { default: apiClient } = await import('@/lib/api-client')
            const farmsResponse = await apiClient.get(`/farm?userId=${userNo}`)
            const farms = (farmsResponse.data || farmsResponse) as { pkFarmNo: number }[]
            if (farms && Array.isArray(farms) && farms.length > 0) {
              const farmNos = farms.map((f) => f.pkFarmNo)
              farmFilters = [{ field: 'cow.fkFarmNo', operator: 'in', value: farmNos }]
            }
          }
        } catch (err) {
          console.error('Failed to fetch farms:', err)
        }

        // 2. 랭킹 옵션 구성
        //    - GENE 모드: 마커 유전자 기반 정렬 (우량동형 → 이형 → 유전체점수) 추후 구현 예정
        //    - GENOME 모드: 형질 가중치 기반 정렬
        let rankingOptions: any

        const traitConditions = Object.entries(filters.traitWeights) // 형질 가중치 조건 1이 기본 (유전체 점수 계산용)
          .filter(([, weight]) => weight > 0)
          .map(([traitNm, weight]) => ({ traitNm, weight }))

        if (rankingMode === 'gene' && filters.isActive && filters.selectedGenes && filters.selectedGenes.length > 0) {
          // GENE 모드
          rankingOptions = {
            criteriaType: 'GENE',
            geneConditions: filters.selectedGenes.map(markerNm => ({ markerNm, order: 'DESC' })),
            traitConditions
          }
        } else if (rankingMode === 'genome' || !filters.isActive || !filters.selectedGenes || filters.selectedGenes.length === 0) {
          // GENOME 모드
          if (!filters.isActive) {
            rankingOptions = {
              criteriaType: 'GENOME',
              traitConditions: [],
              inbreedingCondition: { maxThreshold: 0, order: 'ASC' }
            }
          } else if (rankingMode === 'genome' && traitConditions.length === 0) {
            rankingOptions = {
              criteriaType: 'GENOME',
              traitConditions: [],
              inbreedingCondition: { maxThreshold: filters.inbreedingThreshold ?? 0, order: 'ASC' }
            }
          } else {
            rankingOptions = {
              criteriaType: 'GENOME',
              traitConditions,
              inbreedingCondition: { maxThreshold: filters.inbreedingThreshold ?? 0, order: 'ASC' }
            }
          }
        } else {
          // 기본값 (GENOME 모드)
          rankingOptions = {
            criteriaType: 'GENOME',
            traitConditions: [],
            inbreedingCondition: { maxThreshold: 0, order: 'ASC' }
          }
        }

        // 3. API 호출 및 응답 매핑
        const rankingRequest = {
          filterOptions: { filters: farmFilters }, // 필터옵션과
          rankingOptions // 랭킹옵션을 담아서 백엔드로 전달
        }
        const response = await cowApi.getRanking(rankingRequest)

        const cowsData = response.items.map((item: RankingItem) => ({
          ...item.entity,
          rank: item.rank,
          genomeScore: item.sortValue,
          inbreedingPercent: item.entity.inbreedingPercent ?? 0,
          traits: item.ranking?.traits?.reduce((acc: Record<string, { breedVal: number | null, traitVal: number | null }>, t) => {
            acc[t.traitName] = { breedVal: t.traitEbv, traitVal: t.traitVal }
            return acc
          }, {}) || {},
        }))

        setCows(cowsData)
        setFilteredCows(cowsData)
      } catch (err) {
        console.error('개체 데이터 조회 실패:', err)
        setError(err instanceof Error ? err.message : '데이터를 불러오는데 실패했습니다')
      } finally {
        setLoading(false)
      }
    }

    fetchCows()
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [filters, rankingMode, isFilterSet])

  // ========================================
  // 클라이언트 측 필터링 및 정렬
  // ========================================
  useEffect(() => {
    let result = [...cows]

    // 1. 검색 필터
    if (searchKeyword) {
      const keyword = searchKeyword.toLowerCase()
      result = result.filter(cow =>
        (cow.cowId && cow.cowId.toLowerCase().includes(keyword)) ||
        (cow.cowShortNo && cow.cowShortNo.toLowerCase().includes(keyword)) ||
        String(cow.pkCowNo).includes(searchKeyword)
      )
    }

    // 2. 전역 필터 (유전자 기반)
    if (filters.isActive && filters.analysisIndex === 'GENE' && filters.selectedGenes.length > 0) {
      result = result.filter(cow => {
        if (!cow.genes || !Array.isArray(cow.genes)) return false
        return filters.selectedGenes.every(selectedGene =>
          cow.genes!.some(g => g.name === selectedGene)
        )
      })
    }

    // 3. 분석 상태 필터
    if (analysisFilter === 'pedigreeMatch') {
      result = result.filter(cow => cow.unavailableReason === null || cow.unavailableReason === undefined)
    } else if (analysisFilter === 'pedigreeMismatch') {
      result = result.filter(cow => cow.unavailableReason !== null && cow.unavailableReason !== undefined)
    } else if (analysisFilter === 'mptOnly') {
      result = result.filter(cow => cow.hasMpt === true)
    }

    // 4. 정렬
    switch (sortBy) {
      case 'rank':
        result.sort((a, b) => {
          const rankA = a.rank ?? 9999
          const rankB = b.rank ?? 9999
          return sortOrder === 'asc' ? rankA - rankB : rankB - rankA
        })
        break
      case 'number':
        result.sort((a, b) => {
          const comparison = (a.cowId || '').localeCompare(b.cowId || '')
          return sortOrder === 'asc' ? comparison : -comparison
        })
        break
      case 'birth':
        result.sort((a, b) => {
          const dateA = a.cowBirthDt ? new Date(a.cowBirthDt).getTime() : 0
          const dateB = b.cowBirthDt ? new Date(b.cowBirthDt).getTime() : 0
          return sortOrder === 'asc' ? dateA - dateB : dateB - dateA
        })
        break
      case 'dam':
        result.sort((a, b) => {
          const damA = a.damCowId || ''
          const damB = b.damCowId || ''
          const comparison = damA.localeCompare(damB)
          return sortOrder === 'asc' ? comparison : -comparison
        })
        break
      case 'sire':
        result.sort((a, b) => {
          const sireA = a.sireKpn || ''
          const sireB = b.sireKpn || ''
          const comparison = sireA.localeCompare(sireB)
          return sortOrder === 'asc' ? comparison : -comparison
        })
        break
      case 'monthAge':
        result.sort((a, b) => {
          let monthAgeA = 0
          let monthAgeB = 0
          
          const hasMptOnlyA = a.hasMpt && !a.genomeScore && !a.anlysDt
          const hasMptOnlyB = b.hasMpt && !b.genomeScore && !b.anlysDt
          
          if (analysisFilter === 'mptOnly' || hasMptOnlyA) {
            if (a.cowBirthDt && a.mptTestDt) {
              monthAgeA = Math.floor((new Date(a.mptTestDt).getTime() - new Date(a.cowBirthDt).getTime()) / (1000 * 60 * 60 * 24 * 30.44))
            }
          } else if (a.cowBirthDt && a.anlysDt) {
            monthAgeA = Math.floor((new Date(a.anlysDt).getTime() - new Date(a.cowBirthDt).getTime()) / (1000 * 60 * 60 * 24 * 30.44))
          }
          
          if (analysisFilter === 'mptOnly' || hasMptOnlyB) {
            if (b.cowBirthDt && b.mptTestDt) {
              monthAgeB = Math.floor((new Date(b.mptTestDt).getTime() - new Date(b.cowBirthDt).getTime()) / (1000 * 60 * 60 * 24 * 30.44))
            }
          } else if (b.cowBirthDt && b.anlysDt) {
            monthAgeB = Math.floor((new Date(b.anlysDt).getTime() - new Date(b.cowBirthDt).getTime()) / (1000 * 60 * 60 * 24 * 30.44))
          }
          
          return sortOrder === 'asc' ? monthAgeA - monthAgeB : monthAgeB - monthAgeA
        })
        break
      case 'analysisDate':
        result.sort((a, b) => {
          const hasMptOnlyA = a.hasMpt && !a.genomeScore && !a.anlysDt
          const hasMptOnlyB = b.hasMpt && !b.genomeScore && !b.anlysDt
          
          let dateA = 0
          let dateB = 0
          
          if (analysisFilter === 'mptOnly' || hasMptOnlyA) {
            dateA = a.mptTestDt ? new Date(a.mptTestDt).getTime() : 0
          } else {
            dateA = a.anlysDt ? new Date(a.anlysDt).getTime() : 0
          }
          
          if (analysisFilter === 'mptOnly' || hasMptOnlyB) {
            dateB = b.mptTestDt ? new Date(b.mptTestDt).getTime() : 0
          } else {
            dateB = b.anlysDt ? new Date(b.anlysDt).getTime() : 0
          }
          
          return sortOrder === 'asc' ? dateA - dateB : dateB - dateA
        })
        break
      case 'score':
        result.sort((a, b) => {
          const scoreA = a.genomeScore ?? 0
          const scoreB = b.genomeScore ?? 0
          return sortOrder === 'asc' ? scoreA - scoreB : scoreB - scoreA
        })
        break
    }

    setFilteredCows(result)
    // 페이지 번호는 유지 (정렬/필터 변경 시 페이지 유지)
  }, [searchKeyword, sortBy, sortOrder, cows, filters, analysisFilter])

  // 초기 마운트 후 플래그 업데이트 및 이전 값 설정
  useEffect(() => {
    if (isInitialMount.current) {
      isInitialMount.current = false
      // 초기 값 설정
      prevAnalysisFilter.current = analysisFilter
      prevItemsPerPage.current = itemsPerPage
      prevSearchKeyword.current = searchKeyword
    }
  }, [])

  // 검색어, 필터, 리스트 개수가 실제로 변경되었을 때만 페이지를 1로 리셋
  useEffect(() => {
    if (!isInitialMount.current) {
      let shouldReset = false
      
      // 검색어 변경 확인
      if (prevSearchKeyword.current !== null && prevSearchKeyword.current !== searchKeyword) {
        shouldReset = true
      }
      
      // 필터 변경 확인
      if (prevAnalysisFilter.current !== null && prevAnalysisFilter.current !== analysisFilter) {
        shouldReset = true
      }
      
      // 리스트 개수 변경 확인
      if (prevItemsPerPage.current !== null && prevItemsPerPage.current !== itemsPerPage) {
        shouldReset = true
      }
      
      // 이전 값 업데이트
      prevSearchKeyword.current = searchKeyword
      prevAnalysisFilter.current = analysisFilter
      prevItemsPerPage.current = itemsPerPage
      
      // 변경이 있었으면 페이지 리셋
      if (shouldReset) {
        setCurrentLoadedPage(1)
      }
    }
  }, [searchKeyword, analysisFilter, itemsPerPage])

  // 무한 스크롤: 로드된 페이지까지의 데이터 표시
  useEffect(() => {
    const totalItems = currentLoadedPage * itemsPerPage
    const newDisplayedCows = filteredCows.slice(0, totalItems)
    setDisplayedCows(newDisplayedCows)
    
    // localStorage에 현재 로드된 페이지 저장
    localStorage.setItem('cowListLoadedPage', currentLoadedPage.toString())
  }, [filteredCows, currentLoadedPage, itemsPerPage])

  // 스크롤 이벤트 핸들러: 끝에 도달하면 다음 페이지 로드
  useEffect(() => {
    const scrollContainer = tableScrollRef.current
    if (!scrollContainer) return

    const handleScroll = () => {
      const { scrollTop, scrollHeight, clientHeight } = scrollContainer
      const isNearBottom = scrollHeight - scrollTop - clientHeight < 100 // 100px 여유

      if (isNearBottom && !isLoadingMore) {
        const totalPages = Math.ceil(filteredCows.length / itemsPerPage)
        if (currentLoadedPage < totalPages) {
          setIsLoadingMore(true)
          setTimeout(() => {
            setCurrentLoadedPage(prev => prev + 1)
            setIsLoadingMore(false)
          }, 300) // 약간의 딜레이
        }
      }
    }

    scrollContainer.addEventListener('scroll', handleScroll)
    return () => scrollContainer.removeEventListener('scroll', handleScroll)
  }, [currentLoadedPage, filteredCows.length, itemsPerPage, isLoadingMore])

  // 페이지네이션 (참고용 - 무한 스크롤로 대체)
  const totalPages = Math.ceil(filteredCows.length / itemsPerPage)

  // handleCowClick - cowId 또는 pkCowNo로 상세 페이지 이동
  const handleCowClick = (cowNo: number | string) => {
    router.push(`/cow/${cowNo}?from=list`)
  }

  // 무한 스크롤로 대체됨
  // const handlePageChange = (page: number) => {
  //   setCurrentLoadedPage(page)
  //   window.scrollTo({ top: 0, behavior: 'smooth' })
  // }

  // 정렬 핸들러
  const handleSort = (column: typeof sortBy) => {
    if (sortBy === column) {
      setSortOrder(sortOrder === 'asc' ? 'desc' : 'asc')
    } else {
      setSortBy(column)
      setSortOrder('asc')
    }
  }

  // thead 형질 네비게이션 핸들러 - 모든 행의 인덱스를 thead와 동일하게 통일
  const handleGlobalTraitNext = () => {
    if (theadTraitIndex + 2 < selectedDisplayTraits.length) {
      const newIndex = theadTraitIndex + 2
      setTheadTraitIndex(newIndex)
      // 모든 tbody 행의 인덱스를 thead 인덱스로 통일
      const newIndices = new Map<number, number>()
      displayedCows.forEach(cow => {
        newIndices.set(cow.pkCowNo, newIndex)
      })
      setRowTraitIndices(newIndices)
    }
  }

  const handleGlobalTraitPrev = () => {
    if (theadTraitIndex > 0) {
      const newIndex = Math.max(0, theadTraitIndex - 2)
      setTheadTraitIndex(newIndex)
      // 모든 tbody 행의 인덱스를 thead 인덱스로 통일
      const newIndices = new Map<number, number>()
      displayedCows.forEach(cow => {
        newIndices.set(cow.pkCowNo, newIndex)
      })
      setRowTraitIndices(newIndices)
    }
  }


  // 랭킹 가져오기 (백엔드에서 계산된 값 사용)
  const getRank = (cow: CowWithGenes): number => {
    return cow.rank ?? 9999
  }

  if (loading) {
    return (
      <SidebarProvider>
        <AppSidebar />
        <SidebarInset>
          <SiteHeader />
          <div className="flex flex-1 flex-col items-center justify-center">
            <p>로딩 중...</p>
          </div>
        </SidebarInset>
      </SidebarProvider>
    )
  }

  if (error) {
    return (
      <SidebarProvider>
        <AppSidebar />
        <SidebarInset>
          <SiteHeader />
          <div className="flex flex-1 flex-col items-center justify-center">
            <p className="text-red-500">에러: {error}</p>
          </div>
        </SidebarInset>
      </SidebarProvider>
    )
  }

  // 필터 미설정 시 안내 화면
  if (!isFilterSet) {
    return (
      <SidebarProvider>
        <AppSidebar />
        <SidebarInset>
          <SiteHeader />
          <div className="flex flex-1 flex-col items-center justify-center p-8">
            <div className="w-24 h-24 rounded-full bg-muted flex items-center justify-center mb-8">
              <Filter className="h-12 w-12 text-muted-foreground" />
            </div>
            <h2 className="text-2xl font-semibold mb-4">필터 설정이 필요합니다</h2>
            <p className="text-base text-muted-foreground mb-8 text-center max-w-md">
              개체 목록을 조회하려면 먼저 분석에 사용할 형질(유전체)을 1개 이상 선택해주세요.
            </p>
            <Button
              onClick={() => {
                // SiteHeader의 필터 버튼 클릭
                const filterButton = document.querySelector('[data-filter-button]') as HTMLButtonElement
                if (filterButton) filterButton.click()
              }}
              className="gap-2 h-12 px-6 text-base"
            >
              <Settings className="h-5 w-5" />
              필터 설정하기
            </Button>
          </div>
        </SidebarInset>
      </SidebarProvider>
    )
  }

  // 본문시작 ====================================================================================================
  return (
    <SidebarProvider>
      <AppSidebar />
      <SidebarInset>
        <SiteHeader />
        <div className="flex flex-1 flex-col h-screen overflow-hidden">
          <div className="@container/main flex flex-1 flex-col gap-1 overflow-hidden">
            <div className="cow_list_header flex flex-col gap-2 sm:gap-2.5 md:gap-3 py-3 sm:py-3 md:py-4 flex-shrink-0">
              {/* 헤더 */}
              <div className="px-3 sm:px-4 md:px-6 lg:px-8">
                <div className="flex flex-col gap-2">
                  {/* 제목 */}
                  <div className="flex items-center justify-between gap-4">
                    <div>
                      <h1 className="text-3xl sm:text-4xl md:text-5xl font-bold text-slate-900">개체 목록</h1>
                      <p className="text-base sm:text-lg text-slate-500 mt-1">{'농장'} 보유 개체 현황</p>
                    </div>
                    <Select
                      value={itemsPerPage.toString()}
                      onValueChange={(value) => {
                        setItemsPerPage(parseInt(value, 10))
                      }}
                    >
                      <SelectTrigger className="cnt_per_list w-[120px] sm:w-[140px] h-12 sm:h-14 text-lg sm:text-xl font-medium">
                        <SelectValue />
                      </SelectTrigger>
                      <SelectContent className="cnt_per_list_opts">
                        <SelectItem value="50" className="text-lg sm:text-xl">50두</SelectItem>
                        <SelectItem value="100" className="text-lg sm:text-xl">100두</SelectItem>
                      </SelectContent>
                    </Select>
                  </div>

                  {/* 분석 상태 탭 필터 - 모바일: 2x2 그리드, 데스크톱: 가로 배치 */}
                  <div className="grid grid-cols-2 sm:grid-cols-4 rounded-lg border border-slate-200 bg-slate-50 p-1 gap-1">
                    <button
                      onClick={() => setAnalysisFilter('all')}
                      className={`px-3 sm:px-4 py-3 sm:py-3.5 rounded-md text-xl sm:text-2xl md:text-3xl font-bold transition-colors ${analysisFilter === 'all'
                        ? 'bg-white text-slate-900 shadow-sm border border-slate-200'
                        : 'text-slate-500 hover:text-slate-700'
                        }`}
                    >
                      전체 {cows.length}두
                    </button>
                    <button
                      onClick={() => setAnalysisFilter('pedigreeMatch')}
                      className={`px-3 sm:px-4 py-3 sm:py-3.5 rounded-md text-xl sm:text-2xl md:text-3xl font-bold transition-colors ${analysisFilter === 'pedigreeMatch'
                        ? 'bg-white text-emerald-600 shadow-sm border border-slate-200'
                        : 'text-slate-500 hover:text-slate-700'
                        }`}
                    >
                      <span className="flex items-center justify-center gap-2">
                        <span className="w-3 h-3 sm:w-4 sm:h-4 rounded-full bg-emerald-500"></span>
                        혈통일치 {cows.filter(c => c.unavailableReason === null || c.unavailableReason === undefined).length}두
                      </span>
                    </button>
                    <button
                      onClick={() => setAnalysisFilter('pedigreeMismatch')}
                      className={`px-3 sm:px-4 py-3 sm:py-3.5 rounded-md text-xl sm:text-2xl md:text-3xl font-bold transition-colors ${analysisFilter === 'pedigreeMismatch'
                        ? 'bg-white text-red-600 shadow-sm border border-slate-200'
                        : 'text-slate-500 hover:text-slate-700'
                        }`}
                    >
                      <span className="flex items-center justify-center gap-2">
                        <span className="w-3 h-3 sm:w-4 sm:h-4 rounded-full bg-red-400"></span>
                        혈통불일치 {cows.filter(c => c.unavailableReason !== null && c.unavailableReason !== undefined).length}두
                      </span>
                    </button>
                    <button
                      onClick={() => setAnalysisFilter('mptOnly')}
                      className={`px-3 sm:px-4 py-3 sm:py-3.5 rounded-md text-xl sm:text-2xl md:text-3xl font-bold transition-colors ${analysisFilter === 'mptOnly'
                        ? 'bg-white text-amber-600 shadow-sm border border-slate-200'
                        : 'text-slate-500 hover:text-slate-700'
                        }`}
                    >
                      <span className="flex items-center justify-center gap-2">
                        <span className="w-3 h-3 sm:w-4 sm:h-4 rounded-full bg-amber-500"></span>
                        MPT검사 {cows.filter(c => c.hasMpt === true).length}두
                      </span>
                    </button>
                  </div>

                  {/* 검색 박스 */}
                  <div className="flex flex-col gap-2 sm:gap-2.5 p-2.5 sm:p-3 rounded-xl bg-slate-50/50 border border-slate-200/50">
                    {/* 검색창 */}
                    <div className="relative w-full">
                      <Search className="absolute left-4 top-1/2 -translate-y-1/2 w-5 h-5 sm:w-6 sm:h-6 text-slate-400" />
                      <Input
                        placeholder="개체번호 검색..."
                        className="pl-12 sm:pl-14 h-14 sm:h-16 text-lg sm:text-xl border-slate-200 bg-white focus:border-blue-400 focus:ring-blue-100"
                        value={searchKeyword}
                        onChange={(e) => setSearchKeyword(e.target.value)}
                      />
                    </div>
                  </div>
                  </div>
                </div>
              </div>

              {/* 리스트 뷰 */}
              <div className="px-3 sm:px-4 md:px-6 lg:px-8">
                {/* 데스크톱 테이블 뷰 */}
                {(
                  <div className="hidden md:block border rounded-lg overflow-hidden">
                    <div ref={tableScrollRef} className="cows_list_table overflow-y-auto" style={{ height: 'calc(100vh - 410px)', maxHeight: 'calc(100vh - 350px)' }}>
                      <table className="w-full">
                        <thead className="border-b sticky top-0 z-1">
                        {/* <thead className="border-b"> */}
                          <tr className="bg-gray-100">
                            <th 
                              className="cow-table-header text-lg sm:text-xl cursor-pointer transition-colors select-none" 
                              style={{ width: '70px' }}
                              onClick={() => handleSort('rank')}
                            >
                              <div className="flex items-center justify-center gap-1">
                                순위
                                {sortBy === 'rank' && (
                                  <span className="text-base">{sortOrder === 'asc' ? '↑' : '↓'}</span>
                                )}
                              </div>
                            </th>
                            <th 
                              className="cow-table-header text-lg sm:text-xl cursor-pointer transition-colors select-none" 
                              style={{ width: '150px' }}
                              onClick={() => handleSort('number')}
                            >
                              <div className="flex items-center justify-center gap-1">
                                개체번호
                                {sortBy === 'number' && (
                                  <span className="text-base">{sortOrder === 'asc' ? '↑' : '↓'}</span>
                                )}
                              </div>
                            </th>
                            <th 
                              className="cow-table-header text-lg sm:text-xl cursor-pointer transition-colors select-none" 
                              style={{ width: '90px', whiteSpace: 'nowrap' }}
                              onClick={() => handleSort('monthAge')}
                            >
                              <div className="flex items-center justify-center gap-1">
                                {analysisFilter === 'mptOnly' ? '월령(검사일)' : '월령(분석일)'}
                                {sortBy === 'monthAge' && (
                                  <span className="text-base">{sortOrder === 'asc' ? '↑' : '↓'}</span>
                                )}
                              </div>
                            </th>
                            <th 
                              className="cow-table-header text-lg sm:text-xl cursor-pointer transition-colors select-none" 
                              style={{ width: '100px' }}
                              onClick={() => handleSort('birth')}
                            >
                              <div className="flex items-center justify-center gap-1">
                                생년월일
                                {sortBy === 'birth' && (
                                  <span className="text-base">{sortOrder === 'asc' ? '↑' : '↓'}</span>
                                )}
                              </div>
                            </th>
                            <th 
                              className="cow-table-header text-lg sm:text-xl cursor-pointer transition-colors select-none" 
                              style={{ width: '150px' }}
                              onClick={() => handleSort('dam')}
                            >
                              <div className="flex items-center justify-center gap-1">
                                모개체번호
                                {sortBy === 'dam' && (
                                  <span className="text-base">{sortOrder === 'asc' ? '↑' : '↓'}</span>
                                )}
                              </div>
                            </th>
                            <th 
                              className="cow-table-header text-lg sm:text-xl cursor-pointer transition-colors select-none" 
                              style={{ width: '100px' }}
                              onClick={() => handleSort('sire')}
                            >
                              <div className="flex items-center justify-center gap-1">
                                아비 KPN
                                {sortBy === 'sire' && (
                                  <span className="text-base">{sortOrder === 'asc' ? '↑' : '↓'}</span>
                                )}
                              </div>
                            </th>
                            <th 
                              className="cow-table-header text-lg sm:text-xl cursor-pointer transition-colors select-none" 
                              style={{ width: '100px' }}
                              onClick={() => handleSort('analysisDate')}
                            >
                              <div className="flex items-center justify-center gap-1">
                                {analysisFilter === 'mptOnly' ? '검사일자' : '분석일자'}
                                {sortBy === 'analysisDate' && (
                                  <span className="text-base">{sortOrder === 'asc' ? '↑' : '↓'}</span>
                                )}
                              </div>
                            </th>
                            <th 
                              className="cow-table-header border-r-2 border-r-gray-300 cursor-pointer transition-colors select-none text-lg sm:text-xl" 
                              style={{ width: '110px' }}
                              onClick={() => handleSort('score')}
                            >
                              <div className="flex items-center justify-center gap-1">
                                선발지수
                                {sortBy === 'score' && (
                                  <span className="text-base">{sortOrder === 'asc' ? '↑' : '↓'}</span>
                                )}
                              </div>
                            </th>
                            {selectedDisplayGenes.length > 0 && (
                              <th className="cow-table-header text-lg sm:text-xl" style={{ width: '150px' }}>유전자형</th>
                            )}
                            {selectedDisplayTraits.length > 0 && (
                              <th className="cow-table-header text-lg sm:text-xl" style={{ width: '250px', paddingLeft: '0.8rem' , paddingRight: '0.8rem'}}>
                                <div className="flex items-center w-full h-full gap-2">
                                  {/* 1번 영역: 왼쪽 버튼 */}
                                  <div className="flex-shrink-0 w-8">
                                    <Button
                                      variant={theadTraitIndex === 0 ? "outline" : "default"}
                                      size="icon"
                                      onClick={handleGlobalTraitPrev}
                                      disabled={theadTraitIndex === 0}
                                      className="h-8 w-full"
                                    >
                                      <ChevronLeft className="w-5 h-5" />
                                    </Button>
                                  </div>
                                  
                                  {/* 2번 영역: 형질 타이틀 */}
                                  <div className="flex-1 flex items-center justify-center">
                                    <span className="font-bold">유전체형질</span>
                                  </div>
                                  
                                  {/* 3번 영역: 오른쪽 버튼 */}
                                  <div className="flex-shrink-0 w-8">
                                    <Button
                                      variant={theadTraitIndex + 2 >= selectedDisplayTraits.length ? "outline" : "default"}
                                      size="icon"
                                      onClick={handleGlobalTraitNext}
                                      disabled={theadTraitIndex + 2 >= selectedDisplayTraits.length}
                                      className="h-8 w-full"
                                    >
                                      <ChevronRight className="w-5 h-5" />
                                    </Button>
                                  </div>
                                </div>
                              </th>
                            )}
                          </tr>
                        </thead>
                        <tbody>
                          {displayedCows.map((cow) => {
                            const rank = getRank(cow)

                            return (
                              <tr
                                key={cow.pkCowNo}
                                className="border-b transition-colors hover:bg-muted/50"
                              >
                                <td className="cow-table-cell cursor-pointer" onClick={() => handleCowClick(cow.cowId)}>
                                  <span className="font-bold text-2xl">{rank}</span>
                                </td>
                                <td className="cow-table-cell cursor-pointer" onClick={() => handleCowClick(cow.cowId)}>
                                  <div className="font-bold text-xl">
                                    <CowNumberDisplay cowId={cow.cowId || cow.pkCowNo} cowShortNo={cow.cowShortNo} format="noKor" />
                                  </div>
                                </td>
                                <td className="cow-table-cell cursor-pointer" onClick={() => handleCowClick(cow.cowId)}>
                                  {(() => {
                                    // 번식능력만 있는 개체 판단
                                    const hasMptOnly = cow.hasMpt && !cow.genomeScore && !cow.anlysDt
                                    // 번식능력 탭이거나 번식능력만 있는 개체: MPT 검사일 기준 월령
                                    if (analysisFilter === 'mptOnly' || hasMptOnly) {
                                      if (cow.cowBirthDt && cow.mptTestDt) {
                                        const birthDate = new Date(cow.cowBirthDt)
                                        const refDate = new Date(cow.mptTestDt)
                                        return `${Math.floor((refDate.getTime() - birthDate.getTime()) / (1000 * 60 * 60 * 24 * 30.44))}개월`
                                      }
                                      return '-'
                                    }
                                    // 유전체 분석일 기준 월령
                                    if (cow.cowBirthDt && cow.anlysDt) {
                                      const birthDate = new Date(cow.cowBirthDt)
                                      const refDate = new Date(cow.anlysDt)
                                      return `${Math.floor((refDate.getTime() - birthDate.getTime()) / (1000 * 60 * 60 * 24 * 30.44))}개월`
                                    }
                                    return '-'
                                  })()}
                                </td>
                                <td className="cow-table-cell cursor-pointer" onClick={() => handleCowClick(cow.cowId)}>
                                  {(() => {
                                    // 번식능력만 있는 개체 판단 (유전체 데이터 없음)
                                    const hasMptOnly = cow.hasMpt && !cow.genomeScore && !cow.anlysDt
                                    // 번식능력 탭이거나 번식능력만 있는 개체: cowBirthDt 없으면 MPT로 역산
                                    if ((analysisFilter === 'mptOnly' || hasMptOnly) && !cow.cowBirthDt && cow.mptTestDt && cow.mptMonthAge) {
                                      const testDate = new Date(cow.mptTestDt)
                                      const birthDate = new Date(testDate)
                                      birthDate.setMonth(birthDate.getMonth() - cow.mptMonthAge)
                                      return birthDate.toLocaleDateString('ko-KR', {
                                        year: '2-digit',
                                        month: '2-digit',
                                        day: '2-digit'
                                      })
                                    }
                                    return cow.cowBirthDt ? new Date(cow.cowBirthDt).toLocaleDateString('ko-KR', {
                                      year: '2-digit',
                                      month: '2-digit',
                                      day: '2-digit'
                                    }) : '-'
                                  })()}
                                </td>
                                <td className="cow-table-cell cursor-pointer" onClick={() => handleCowClick(cow.cowId)}>
                                  {cow.damCowId && cow.damCowId !== '0' ? (() => {
                                    // KOR 제거 및 포맷팅
                                    const cleaned = cow.damCowId.replace(/^KOR/i, '').replace(/\D/g, '')
                                    if (cleaned.length === 12) {
                                      return `${cleaned.slice(0, 3)} ${cleaned.slice(3, 7)} ${cleaned.slice(7, 11)} ${cleaned.slice(11)}`
                                    }
                                    return cow.damCowId.replace(/^KOR/i, '').trim()
                                  })() : '-'}
                                </td>
                                <td className="cow-table-cell cursor-pointer" onClick={() => handleCowClick(cow.cowId)}>
                                  {cow.sireKpn && cow.sireKpn !== '0' ? cow.sireKpn : '-'}
                                </td>
                                <td className="cow-table-cell cursor-pointer" onClick={() => handleCowClick(cow.cowId)}>
                                  {(() => {
                                    // 번식능력만 있는 개체 판단
                                    const hasMptOnly = cow.hasMpt && !cow.genomeScore && !cow.anlysDt
                                    // 번식능력 탭이거나 번식능력만 있는 개체: MPT 검사일 사용
                                    if (analysisFilter === 'mptOnly' || hasMptOnly) {
                                      return cow.mptTestDt ? new Date(cow.mptTestDt).toLocaleDateString('ko-KR', {
                                        year: '2-digit',
                                        month: '2-digit',
                                        day: '2-digit'
                                      }) : '-'
                                    }
                                    // 유전체 탭: unavailableReason 있으면 배지, 없으면 분석일자
                                    if (cow.unavailableReason) {
                                      return (
                                        <span className={`inline-flex items-center px-2.5 py-1 rounded-full text-sm font-semibold ${
                                          cow.unavailableReason.includes('부') ? 'bg-red-100 text-red-700' :
                                          cow.unavailableReason.includes('모') ? 'bg-orange-100 text-orange-700' :
                                          'bg-slate-100 text-slate-600'
                                        }`}>
                                          {cow.unavailableReason}
                                        </span>
                                      )
                                    }
                                    return cow.anlysDt ? new Date(cow.anlysDt).toLocaleDateString('ko-KR', {
                                      year: '2-digit',
                                      month: '2-digit',
                                      day: '2-digit'
                                    }) : '-'
                                  })()}
                                </td>
                                <td className="cow-table-cell cursor-pointer border-r-2 border-r-gray-300 !py-3 !px-2" onClick={() => handleCowClick(cow.cowId)}>
                                  {(cow.genomeScore !== undefined && cow.genomeScore !== null) ? (
                                    <div className="font-bold text-primary text-xl">
                                      {cow.genomeScore.toFixed(2)}
                                    </div>
                                  ) : (

                                    cow.anlysDt ? (
                                      <Badge className="text-sm px-3 py-1.5 bg-slate-600 text-white border-0 font-semibold">
                                        분석불가
                                      </Badge>
                                      ) : (
                                        <Badge className="text-sm px-3 py-1.5 bg-slate-300 text-white border-0 font-semibold">
                                          검사결과없음
                                        </Badge>
                                      )
                                    // <Badge className="text-sm px-3 py-1.5 bg-slate-600 text-white border-0 font-semibold">
                                    //   분석불가
                                    // </Badge>
                                  )}
                                </td>
                                {selectedDisplayGenes.length > 0 && (
                                  <td
                                    className="py-3 px-2 text-sm cursor-pointer"
                                    onClick={() => handleCowClick(cow.cowId)}
                                  >
                                    {(() => {
                                      const isExpanded = expandedRows.has(cow.pkCowNo)
                                      const displayGenes = isExpanded ? selectedDisplayGenes : selectedDisplayGenes.slice(0, 3)
                                      const remainingCount = selectedDisplayGenes.length - 3

                                      return (
                                        <div className="flex flex-col gap-1.5">
                                          {displayGenes.map((geneName) => {
                                            const gene = cow.genes?.find(g => g.name === geneName)
                                            const genotype = gene?.genotype || '-'

                                            return (
                                              <div key={geneName} className="flex items-center gap-2">
                                                <span className="text-sm text-slate-600 min-w-[70px] font-medium">{geneName}</span>
                                                {gene ? (
                                                  <Badge className="text-sm font-semibold bg-blue-500 text-white px-2 py-0.5">
                                                    {genotype}
                                                  </Badge>
                                                ) : (
                                                  <Badge variant="outline" className="text-sm text-muted-foreground">
                                                    -
                                                  </Badge>
                                                )}
                                              </div>
                                            )
                                          })}
                                          {selectedDisplayGenes.length > 3 && (
                                            <button
                                              onClick={() => {
                                                const newExpanded = new Set(expandedRows)
                                                if (isExpanded) {
                                                  newExpanded.delete(cow.pkCowNo)
                                                } else {
                                                  newExpanded.add(cow.pkCowNo)
                                                }
                                                setExpandedRows(newExpanded)
                                              }}
                                              className="text-sm text-blue-600 hover:text-blue-800 font-semibold cursor-pointer text-center mt-0.5"
                                            >
                                              {isExpanded ? '접기' : `+${remainingCount}개 더보기`}
                                            </button>
                                          )}
                                        </div>
                                      )
                                    })()}
                                  </td>
                                )}
                                {selectedDisplayTraits.length > 0 && (
                                  <td
                                    className="py-2 px-2 text-sm select-none relative"
                                    style={{ width: '250px', maxWidth: '250px', userSelect: 'none', paddingLeft: '0.8rem' , paddingRight: '0.8rem'}}
                                  >
                                    <div className="flex items-center w-full h-full gap-2">
                                      {/* 1번 영역: 왼쪽 버튼 */}
                                      <div className="flex-shrink-0 w-8">
                                        <Button
                                          variant={(rowTraitIndices.get(cow.pkCowNo) ?? theadTraitIndex) === 0 ? "outline" : "default"}
                                          size="icon"
                                          onClick={(e) => {
                                            e.stopPropagation()
                                            const currentIndex = rowTraitIndices.get(cow.pkCowNo) ?? theadTraitIndex
                                            if (currentIndex > 0) {
                                              const newIndices = new Map(rowTraitIndices)
                                              newIndices.set(cow.pkCowNo, Math.max(0, currentIndex - 2))
                                              setRowTraitIndices(newIndices)
                                            }
                                          }}
                                          disabled={(rowTraitIndices.get(cow.pkCowNo) ?? theadTraitIndex) === 0}
                                          className="h-full w-full"
                                        >
                                          <ChevronLeft className="w-4 h-4" />
                                        </Button>
                                      </div>
                                      
                                      {/* 2번 영역: 형질 표시 */}
                                      <div 
                                        className="overflow-hidden cursor-grab active:cursor-grabbing relative flex-1"
                                        onMouseDown={(e) => {
                                          e.stopPropagation()
                                          const container = e.currentTarget
                                          const innerDiv = container.firstElementChild as HTMLElement
                                          if (!innerDiv) return
                                          
                                          let isDown = true
                                          const startX = e.pageX
                                          const currentIndex = rowTraitIndices.get(cow.pkCowNo) ?? theadTraitIndex
                                          const startTranslate = -currentIndex * calculatedMoveDistance
                                          let currentTranslate = startTranslate
                                          
                                          const handleMouseMove = (e: MouseEvent) => {
                                            if (!isDown) return
                                            e.preventDefault()
                                            const deltaX = e.pageX - startX
                                            currentTranslate = startTranslate + deltaX
                                            
                                            // 최소/최대 범위 제한
                                            const maxTranslate = 0
                                            const minTranslate = -(selectedDisplayTraits.length - 2) * calculatedMoveDistance
                                            currentTranslate = Math.max(minTranslate, Math.min(maxTranslate, currentTranslate))
                                            
                                            innerDiv.style.transform = `translateX(${currentTranslate}px)`
                                            innerDiv.style.transition = 'none'
                                          }
                                          
                                          const handleMouseUp = () => {
                                            isDown = false
                                            document.removeEventListener('mousemove', handleMouseMove)
                                            document.removeEventListener('mouseup', handleMouseUp)
                                            
                                            // 드래그 끝: 현재 위치로부터 인덱스 계산
                                            const offset = -currentTranslate
                                            const calculatedIndex = Math.round(offset / calculatedMoveDistance)
                                            const maxIndex = Math.max(0, selectedDisplayTraits.length - 2)
                                            const finalIndex = Math.min(maxIndex, Math.max(0, calculatedIndex))
                                            
                                            // 인덱스 저장
                                            const newIndices = new Map(rowTraitIndices)
                                            newIndices.set(cow.pkCowNo, finalIndex)
                                            setRowTraitIndices(newIndices)
                                            
                                            // transition 복원
                                            innerDiv.style.transition = ''
                                          }
                                          
                                          document.addEventListener('mousemove', handleMouseMove)
                                          document.addEventListener('mouseup', handleMouseUp)
                                        }}
                                      >
                                        <div className="flex gap-2 transition-transform duration-300" style={{
                                          transform: `translateX(-${(rowTraitIndices.get(cow.pkCowNo) ?? theadTraitIndex) * calculatedMoveDistance}px)`
                                        }}>
                                          {selectedDisplayTraits.map((trait, index) => {
                                            let traitValue = '-'
                                            if (cow.traits && cow.traits[trait] !== undefined) {
                                              const traitData = cow.traits[trait]
                                              if (typeof traitData === 'object' && traitData.traitVal !== undefined && traitData.traitVal !== null) {
                                                traitValue = Number(traitData.traitVal).toFixed(1)
                                              } else if (typeof traitData === 'object' && traitData.breedVal !== undefined) {
                                                traitValue = Number(traitData.breedVal).toFixed(1)
                                              } else if (typeof traitData === 'number') {
                                                traitValue = Number(traitData).toFixed(1)
                                              }
                                            }

                                            return (
                                              <div 
                                                key={trait} 
                                                ref={index === 0 ? firstTraitRef : null}
                                                className="flex flex-col items-center gap-0.5 shrink-0 w-[50%]"
                                              >
                                                <span className="text-lg text-muted-foreground text-center whitespace-nowrap font-bold">{TRAIT_DISPLAY_NAMES[trait] || trait}</span>
                                                <span className="font-bold text-xl">{traitValue}</span>
                                              </div>
                                            )
                                          })}
                                        </div>
                                      </div>

                                      {/* 3번 영역: 오른쪽 버튼 */}
                                      <div className="flex-shrink-0 w-8">
                                        <Button
                                          variant={(rowTraitIndices.get(cow.pkCowNo) ?? theadTraitIndex) + 2 >= selectedDisplayTraits.length ? "outline" : "default"}
                                          size="icon"
                                          onClick={(e) => {
                                            e.stopPropagation()
                                            const currentIndex = rowTraitIndices.get(cow.pkCowNo) ?? theadTraitIndex
                                            if (currentIndex + 2 < selectedDisplayTraits.length) {
                                              const newIndices = new Map(rowTraitIndices)
                                              newIndices.set(cow.pkCowNo, currentIndex + 2)
                                              setRowTraitIndices(newIndices)
                                            }
                                          }}
                                          disabled={(rowTraitIndices.get(cow.pkCowNo) ?? theadTraitIndex) + 2 >= selectedDisplayTraits.length}
                                          className="h-full w-full"
                                        >
                                          <ChevronRight className="w-4 h-4" />
                                        </Button>
                                      </div>
                                    </div>
                                  </td>
                                )}
                              </tr>
                            )
                          })}
                        </tbody>
                      </table>
                    </div>
                  </div>
                )}

                {/* 모바일 컴팩트 카드 뷰 */}
                {(
                  <div className="md:hidden space-y-3">
                    {displayedCows.map((cow) => {
                      const rank = getRank(cow)

                      return (
                        <div
                          key={cow.pkCowNo}
                          className="relative border rounded-lg p-4 hover:bg-muted/50 cursor-pointer transition-colors overflow-hidden"
                          onClick={() => handleCowClick(cow.cowId)}
                        >
                          {/* 1행: 순위, 개체번호, 선발지수 */}
                          <div className="flex items-center justify-between mb-3">
                            <div className="flex items-center gap-2.5 min-w-0 flex-1">
                              <span className="text-lg font-bold text-muted-foreground">{rank}위</span>
                              <span className="font-bold text-xl truncate">
                                <CowNumberDisplay cowId={cow.cowId || cow.pkCowNo} cowShortNo={cow.cowShortNo} format="noKor" />
                              </span>
                            </div>
                            <div className="flex-shrink-0 ml-3">
                              {cow.genomeScore !== undefined && cow.genomeScore !== null ? (
                                <span className="font-bold text-2xl text-primary">
                                  {cow.genomeScore.toFixed(2)}
                                </span>
                              ) : (
                                cow.anlysDt ? (
                                <Badge className="text-xs px-2 py-1 bg-slate-500 text-white border-0 font-medium">
                                  분석불가
                                </Badge>
                                ) : (
                                  <Badge className="text-xs px-2 py-1 bg-slate-300 text-white border-0 font-medium">
                                    검사결과없음
                                  </Badge>
                                )
                              )}
                            </div>
                          </div>

                          {/* 2행: 기본 정보 */}
                          <div className="grid grid-cols-2 gap-x-5 gap-y-2 text-base border-t pt-3">
                            <div className="flex justify-between">
                              <span className="text-muted-foreground">생년월일</span>
                              <span className="font-medium">
                                {(() => {
                                  // 번식능력만 있는 개체 판단
                                  const hasMptOnly = cow.hasMpt && !cow.genomeScore && !cow.anlysDt
                                  // 번식능력 탭이거나 번식능력만 있는 개체: cowBirthDt 없으면 MPT로 역산
                                  if ((analysisFilter === 'mptOnly' || hasMptOnly) && !cow.cowBirthDt && cow.mptTestDt && cow.mptMonthAge) {
                                    const testDate = new Date(cow.mptTestDt)
                                    const birthDate = new Date(testDate)
                                    birthDate.setMonth(birthDate.getMonth() - cow.mptMonthAge)
                                    return birthDate.toLocaleDateString('ko-KR', { year: '2-digit', month: 'numeric', day: 'numeric' })
                                  }
                                  return cow.cowBirthDt ? new Date(cow.cowBirthDt).toLocaleDateString('ko-KR', { year: '2-digit', month: 'numeric', day: 'numeric' }) : '-'
                                })()}
                              </span>
                            </div>
                            <div className="flex justify-between">
                              <span className="text-muted-foreground">
                                {(() => {
                                  const hasMptOnly = cow.hasMpt && !cow.genomeScore && !cow.anlysDt
                                  return (analysisFilter === 'mptOnly' || hasMptOnly) ? '월령 (검사일)' : '월령 (분석일)'
                                })()}
                              </span>
                              <span className="font-medium">
                                {(() => {
                                  // 번식능력만 있는 개체 판단
                                  const hasMptOnly = cow.hasMpt && !cow.genomeScore && !cow.anlysDt
                                  // 번식능력 탭이거나 번식능력만 있는 개체: MPT 검사일 기준 월령
                                  if (analysisFilter === 'mptOnly' || hasMptOnly) {
                                    if (cow.cowBirthDt && cow.mptTestDt) {
                                      return `${Math.floor((new Date(cow.mptTestDt).getTime() - new Date(cow.cowBirthDt).getTime()) / (1000 * 60 * 60 * 24 * 30.44))}개월`
                                    }
                                    return '-'
                                  }
                                  // 유전체 분석일 기준 월령
                                  if (cow.cowBirthDt && cow.anlysDt) {
                                    return `${Math.floor((new Date(cow.anlysDt).getTime() - new Date(cow.cowBirthDt).getTime()) / (1000 * 60 * 60 * 24 * 30.44))}개월`
                                  }
                                  return '-'
                                })()}
                              </span>
                            </div>
                            <div className="flex justify-between">
                              <span className="text-muted-foreground">모</span>
                              <span className="font-medium text-sm sm:text-base">
                                {cow.damCowId && cow.damCowId !== '0' ? (() => {
                                  // KOR 제거 및 포맷팅
                                  const cleaned = cow.damCowId.replace(/^KOR/i, '').replace(/\D/g, '')
                                  if (cleaned.length === 12) {
                                    return `${cleaned.slice(0, 3)} ${cleaned.slice(3, 7)} ${cleaned.slice(7, 11)} ${cleaned.slice(11)}`
                                  }
                                  return cow.damCowId.replace(/^KOR/i, '').trim()
                                })() : '-'}
                              </span>
                            </div>
                            <div className="flex justify-between">
                              <span className="text-muted-foreground">부</span>
                              <span className="font-medium">{cow.sireKpn && cow.sireKpn !== '0' ? cow.sireKpn : '-'}</span>
                            </div>
                            <div className="flex justify-between items-center">
                              <span className="text-muted-foreground">
                                {(() => {
                                  const hasMptOnly = cow.hasMpt && !cow.genomeScore && !cow.anlysDt
                                  return (analysisFilter === 'mptOnly' || hasMptOnly) ? '검사일' : (cow.anlysDt ? '분석일' : '분석결과')
                                })()}
                              </span>
                              <span className="font-medium">
                                {(() => {
                                  // 번식능력만 있는 개체 판단
                                  const hasMptOnly = cow.hasMpt && !cow.genomeScore && !cow.anlysDt
                                  // 번식능력 탭이거나 번식능력만 있는 개체: MPT 검사일 사용
                                  if (analysisFilter === 'mptOnly' || hasMptOnly) {
                                    return cow.mptTestDt ? new Date(cow.mptTestDt).toLocaleDateString('ko-KR', { year: '2-digit', month: 'numeric', day: 'numeric' }) : '-'
                                  }
                                  if (cow.anlysDt) {
                                    return new Date(cow.anlysDt).toLocaleDateString('ko-KR', { year: '2-digit', month: 'numeric', day: 'numeric' })
                                  }
                                  if (cow.unavailableReason) {
                                    return (
                                      <span className={`inline-flex items-center px-2 py-0.5 rounded-full text-xs font-semibold ${
                                        cow.unavailableReason.includes('부') ? 'bg-red-100 text-red-700' :
                                        cow.unavailableReason.includes('모') ? 'bg-orange-100 text-orange-700' :
                                        'bg-slate-100 text-slate-600'
                                      }`}>
                                        {cow.unavailableReason}
                                      </span>
                                    )
                                  }
                                  return '-'
                                })()}
                              </span>
                            </div>
                          </div>

                          {/* 유전자형 섹션 */}
                          {selectedDisplayGenes.length > 0 && (
                            <div className="pt-3 border-t mt-3" onClick={(e) => e.stopPropagation()}>
                              <div className="flex items-center gap-2 flex-wrap">
                                <span className="text-sm text-muted-foreground mr-1 font-medium">유전자</span>
                                {(() => {
                                  const isExpanded = expandedRows.has(`${cow.pkCowNo}-mobile-genes`)
                                  // selectedDisplayGenes가 이미 전역 필터 순서를 반영하고 있음
                                  const displayGenes = isExpanded ? selectedDisplayGenes : selectedDisplayGenes.slice(0, 4)
                                  const remainingCount = selectedDisplayGenes.length - 4

                                  return (
                                    <>
                                      {displayGenes.map((geneName) => {
                                        const gene = cow.genes?.find(g => g.name === geneName)
                                        const genotype = gene?.genotype || '-'

                                        return (
                                          <Badge key={geneName} className="text-sm px-2 py-1 font-medium bg-blue-500 text-white">
                                            {geneName} {genotype}
                                          </Badge>
                                        )
                                      })}
                                      {selectedDisplayGenes.length > 4 && (
                                        <button
                                          onClick={() => {
                                            const newExpanded = new Set(expandedRows)
                                            const key = `${cow.pkCowNo}-mobile-genes`
                                            if (isExpanded) {
                                              newExpanded.delete(key)
                                            } else {
                                              newExpanded.add(key)
                                            }
                                            setExpandedRows(newExpanded)
                                          }}
                                          className="text-sm text-blue-600 hover:text-blue-800 font-medium"
                                        >
                                          {isExpanded ? '접기' : `+${remainingCount}개 더`}
                                        </button>
                                      )}
                                    </>
                                  )
                                })()}
                              </div>
                            </div>
                          )}

                          {/* 형질 섹션 */}
                          {selectedDisplayTraits.length > 0 && (
                            <div className="pt-3 border-t mt-3" onClick={(e) => e.stopPropagation()}>
                              {(() => {
                                // 상위 4개만 표시
                                const isExpanded = expandedRows.has(`${cow.pkCowNo}-mobile-traits`)
                                const displayTraits = selectedDisplayTraits.slice(0, 4) // 상위 4개만
                                const remainingCount = selectedDisplayTraits.length - 4

                                return (
                                  <>
                                    <div className="grid grid-cols-2 gap-x-5 gap-y-2 text-base">
                                      {displayTraits.map((trait) => {
                                        let traitValue = '-'
                                        if (cow.traits && cow.traits[trait] !== undefined) {
                                          const traitData = cow.traits[trait]
                                          if (typeof traitData === 'object' && traitData.traitVal !== undefined && traitData.traitVal !== null) {
                                            traitValue = Number(traitData.traitVal).toFixed(1)
                                          } else if (typeof traitData === 'object' && traitData.breedVal !== undefined) {
                                            traitValue = Number(traitData.breedVal).toFixed(1)
                                          } else if (typeof traitData === 'number') {
                                            traitValue = Number(traitData).toFixed(1)
                                          }
                                        }
                                        return (
                                          <div key={trait} className="flex items-center justify-between">
                                            <span className="text-muted-foreground font-medium">{TRAIT_DISPLAY_NAMES[trait] || trait}</span>
                                            <span className="font-semibold">{traitValue}</span>
                                          </div>
                                        )
                                      })}
                                    </div>
                                    {/* 형질 더보기 버튼 주석처리 */}
                                    {/* {selectedDisplayTraits.length > 4 && (
                                      <button
                                        onClick={() => {
                                          const newExpanded = new Set(expandedRows)
                                          const key = `${cow.pkCowNo}-mobile-traits`
                                          if (isExpanded) {
                                            newExpanded.delete(key)
                                          } else {
                                            newExpanded.add(key)
                                          }
                                          setExpandedRows(newExpanded)
                                        }}
                                        className="text-sm text-teal-600 hover:text-teal-800 font-medium w-full text-center mt-2"
                                      >
                                        {isExpanded ? '접기' : `+${remainingCount}개 더`}
                                      </button>
                                    )} */}
                                  </>
                                )
                              })()}
                            </div>
                          )}
                        </div>
                      )
                    })}
                  </div>
                )}

                {filteredCows.length === 0 && selectedDisplayGenes.length > 0 && (
                  <div className="text-center py-12 text-muted-foreground">
                    {searchKeyword
                      ? '검색 결과가 없습니다.'
                      : '등록된 소가 없습니다.'}
                  </div>
                )}

                {/* 페이지네이션 - 무한 스크롤로 대체됨 */}
                {/* {totalPages > 1 && (
                  <div className="flex items-center justify-center gap-2 sm:gap-2.5 mt-3 sm:mt-4 px-3 sm:px-4 md:px-6 lg:px-8 pb-5 flex-shrink-0">
                    <Button
                      variant="outline"
                      size="icon"
                      className="h-11 w-11 sm:h-12 sm:w-12"
                      onClick={() => handlePageChange(currentPage - 1)}
                      disabled={currentPage === 1}
                    >
                      <ChevronLeft className="h-5 w-5 sm:h-6 sm:w-6" />
                    </Button>

                    <div className="flex gap-1.5 sm:gap-2">
                      {Array.from({ length: totalPages }, (_, i) => i + 1).map((page) => {
                        // 모바일: 앞뒤 1개씩만, 데스크톱: 앞뒤 2개씩
                        const isMobileVisible = page === 1 || page === totalPages || (page >= currentPage - 1 && page <= currentPage + 1)
                        if (isMobileVisible) {
                          return (
                            <Button
                              key={page}
                              variant={currentPage === page ? "default" : "outline"}
                              size="icon"
                              className="h-11 w-11 sm:h-12 sm:w-12 text-base sm:text-lg"
                              onClick={() => handlePageChange(page)}
                            >
                              {page}
                            </Button>
                          )
                        } else if (page === currentPage - 2 || page === currentPage + 2) {
                          return <span key={page} className="px-1 text-base text-muted-foreground">...</span>
                        }
                        return null
                      })}
                    </div>

                    <Button
                      variant="outline"
                      size="icon"
                      className="h-11 w-11 sm:h-12 sm:w-12"
                      onClick={() => handlePageChange(currentPage + 1)}
                      disabled={currentPage === totalPages}
                    >
                      <ChevronRight className="h-5 w-5 sm:h-6 sm:w-6" />
                    </Button>
                  </div>
                )} */}
                
                {/* 현황 정보 표시 */}
                <div className="flex items-center justify-center py-4 border-t">
                  <span className="text-lg font-bold text-muted-foreground">
                    {filteredCows.length > 0 ? (
                      <>
                        전체 {filteredCows.length.toLocaleString()}개 중 1-{displayedCows.length.toLocaleString()}번째
                        {isLoadingMore && ' (로딩 중...)'}
                      </>
                    ) : (
                      '데이터 없음'
                    )}
                  </span>
                </div>
              </div>
            </div>
          </div>

      </SidebarInset>
    </SidebarProvider>
  )
}

export default function MyCowPage() {
  return (
    <AuthGuard>
      
        <AnalysisYearProvider>
          <MyCowContent />
        </AnalysisYearProvider>
      
    </AuthGuard>
  )
}
