"use client"

import * as React from "react"
import { flexRender, type Table as TanstackTable } from "@tanstack/react-table"
import { ChevronRight, ChevronUp, ChevronDown } from "lucide-react"

import { cn } from "@/lib/utils"
import { getCommonPinningStylesWithBorder, debugPinningInfo } from "@/lib/data-table"
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table"
import { DataTablePagination } from "@/components/data-table/data-table-pagination"
import { DataTableResizer } from "@/components/data-table/data-table-resizer"
import { useAutoSizeColumns } from "@/hooks/useAutoSizeColumns"

interface ExpandableDataTableProps<TData> extends React.HTMLAttributes<HTMLDivElement> {
  table: TanstackTable<TData>
  floatingBar?: React.ReactNode | null
  autoSizeColumns?: boolean
  compact?: boolean
  expandedRows?: Set<string>
  setExpandedRows?: React.Dispatch<React.SetStateAction<Set<string>>>
  renderExpandedContent?: (row: TData) => React.ReactNode
  expandable?: boolean
  maxHeight?: string | number
  expandedRowClassName?: string
  debug?: boolean // 디버깅 옵션 추가
  simpleExpansion?: boolean // 🎯 간단한 확장 방식 선택 옵션 추가
}

export function ExpandableDataTable<TData>({
  table,
  floatingBar = null,
  autoSizeColumns = true,
  compact = false,
  expandedRows = new Set(),
  setExpandedRows,
  renderExpandedContent,
  expandable = false,
  maxHeight,
  expandedRowClassName,
  debug = false,
  simpleExpansion = false, // 🎯 기본값 false (전체 확장 방식)
  children,
  className,
  ...props
}: ExpandableDataTableProps<TData>) {

  useAutoSizeColumns(table, autoSizeColumns)

  const containerRef = React.useRef<HTMLDivElement>(null)
  const scrollRef = React.useRef<HTMLDivElement>(null) // 🎯 스크롤 컨테이너 ref 추가
  const [expandedHeights, setExpandedHeights] = React.useState<Map<string, number>>(new Map())
  const [isScrolled, setIsScrolled] = React.useState(false)
  const [isScrolledToEnd, setIsScrolledToEnd] = React.useState(true) // 🎯 초기값을 true로 설정 (아직 계산 안됨)
  const [isInitialized, setIsInitialized] = React.useState(false) // 🎯 초기화 상태 추가
  const [containerWidth, setContainerWidth] = React.useState<number>(0)

  // 🎯 컨테이너 너비 감지 (패딩 제외된 실제 사용 가능한 너비)
  React.useEffect(() => {
    if (!containerRef.current) return

    const updateContainerWidth = () => {
      if (containerRef.current) {
        // clientWidth는 패딩을 제외한 실제 사용 가능한 너비
        setContainerWidth(containerRef.current.clientWidth)
      }
    }

    const resizeObserver = new ResizeObserver(updateContainerWidth)
    resizeObserver.observe(containerRef.current)
    
    // 초기 너비 설정
    updateContainerWidth()

    return () => resizeObserver.disconnect()
  }, [])

  // 🎯 초기 스크롤 상태 체크 (더 확실한 초기화)
  React.useEffect(() => {
    if (!scrollRef.current) return
    
    const checkScrollState = () => {
      if (scrollRef.current) {
        const { scrollLeft, scrollWidth, clientWidth } = scrollRef.current
        const newIsScrolled = scrollLeft > 0
        const newIsScrolledToEnd = Math.abs(scrollWidth - clientWidth - scrollLeft) < 1
        
        setIsScrolled(newIsScrolled)
        setIsScrolledToEnd(newIsScrolledToEnd)
        setIsInitialized(true)
        
        if (debug) {
          console.log('Initial scroll check:', {
            scrollLeft,
            scrollWidth,
            clientWidth,
            newIsScrolled,
            newIsScrolledToEnd,
            canScroll: scrollWidth > clientWidth
          })
        }
      }
    }
    
    // 즉시 체크
    checkScrollState()
    
    // 짧은 지연 후 재체크 (테이블 렌더링 완료 대기)
    const timeouts = [50, 100, 200].map(delay => 
      setTimeout(checkScrollState, delay)
    )
    
    // ResizeObserver로 테이블 크기 변화 감지
    const resizeObserver = new ResizeObserver(() => {
      setTimeout(checkScrollState, 10)
    })
    resizeObserver.observe(scrollRef.current)
    
    return () => {
      timeouts.forEach(clearTimeout)
      resizeObserver.disconnect()
    }
  }, [table, debug])

  // 🎯 데이터 변경 시 스크롤 상태 재설정
  React.useEffect(() => {
    setIsInitialized(false) // 🎯 데이터 변경 시 초기화 상태 리셋
    setIsScrolledToEnd(true) // 🎯 안전한 기본값으로 리셋
  }, [table.getRowModel().rows.length])

  const handleScroll = (e: React.UIEvent<HTMLDivElement>) => {
    const scrollLeft = e.currentTarget.scrollLeft
    const scrollWidth = e.currentTarget.scrollWidth
    const clientWidth = e.currentTarget.clientWidth
    
    // 🎯 왼쪽으로부터 스크롤 상태 (왼쪽 핀용)
    setIsScrolled(scrollLeft > 0)
    
    // 🎯 오른쪽 끝까지 스크롤 상태 (오른쪽 핀용)
    const isAtEnd = Math.abs(scrollWidth - clientWidth - scrollLeft) < 1 // 1px 오차 허용
    setIsScrolledToEnd(isAtEnd)
    setIsInitialized(true) // 🎯 스크롤 이벤트 발생 시 초기화 완료
    
    if (debug) {
      console.log('Scroll state:', {
        scrollLeft,
        scrollWidth,
        clientWidth,
        isScrolled: scrollLeft > 0,
        isScrolledToEnd: isAtEnd,
        remainingScroll: scrollWidth - clientWidth - scrollLeft
      })
    }
  }

  // 🔧 개선된 핀 스타일 함수 (좌/우 핀 구분 처리)
  const getPinnedStyle = React.useCallback((column: any, isHeader: boolean = false) => {
    if (debug) {
      debugPinningInfo(column)
    }

    try {
      const baseStyle = getCommonPinningStylesWithBorder({ 
        column, 
        withBorder: true 
      })
      
      const pinnedSide = column.getIsPinned()
      
      if (!pinnedSide) {
        // width를 제외한 나머지 스타일만 반환
        const { width, ...restStyle } = baseStyle
        // 헤더인 경우 핀되지 않았어도 배경 필요 (sticky 때문에)
        return {
          ...restStyle,
          ...(isHeader && {
            background: "hsl(var(--background))",
            transition: "none",
          }),
        }
      }

      // 확장 버튼이 있을 때 left pin된 컬럼들을 오른쪽으로 이동
      let leftPosition = baseStyle.left
      if (expandable && pinnedSide === "left") {
        const expandButtonWidth = 40 // w-10 = 40px
        if (typeof baseStyle.left === 'string') {
          const currentLeft = parseFloat(baseStyle.left.replace('px', ''))
          leftPosition = `${currentLeft + expandButtonWidth}px`
        } else if (typeof baseStyle.left === 'number') {
          leftPosition = `${baseStyle.left + expandButtonWidth}px`
        } else {
          leftPosition = `${expandButtonWidth}px`
        }
      }
      
      // 🎯 핀 위치에 따른 배경 결정
      let shouldShowBackground = false
      if (isHeader) {
        // 헤더는 항상 배경 표시
        shouldShowBackground = true
      } else {
        // 바디 셀의 경우 핀 위치에 따라 다른 조건 적용
        if (pinnedSide === "left") {
          // 왼쪽 핀: 오른쪽으로 스크롤했을 때 배경 표시
          shouldShowBackground = isScrolled
        } else if (pinnedSide === "right") {
          // 오른쪽 핀: 초기화 전이거나 오른쪽 끝까지 스크롤하지 않았을 때 배경 표시
          shouldShowBackground = !isInitialized || !isScrolledToEnd
        }
      }
      
      // width를 제외한 스타일 적용
      const { width, ...restBaseStyle } = baseStyle
      
      const finalStyle = {
        ...restBaseStyle,
        left: leftPosition,
        background: shouldShowBackground 
          ? "hsl(var(--background))" 
          : "transparent",
        transition: isHeader ? "none" : "background-color 0.15s ease-out",
      }

      if (debug) {
        console.log("Final pinned style:", {
          columnId: column.id,
          pinnedSide,
          isHeader,
          isScrolled,
          isScrolledToEnd,
          isInitialized,
          shouldShowBackground,
          finalStyle
        })
      }

      return finalStyle
    } catch (error) {
      console.error("Error in getPinnedStyle:", error)
      // fallback 스타일
      return {
        position: 'relative' as const,
        ...(isHeader && {
          background: "hsl(var(--background))",
        }),
      }
    }
  }, [expandable, isScrolled, isScrolledToEnd, isInitialized, debug])

  // 확장 버튼용 스타일 (안정성 개선)
  const getExpandButtonStyle = React.useCallback(() => {
    return {
      position: 'sticky' as const,
      left: 0,
      zIndex: 1,
      background: "hsl(var(--background))",
      minWidth: '40px',
      maxWidth: '40px',
      width: '40px',
    }
  }, [])

  // 🎯 테이블 총 너비 계산
  const getTableWidth = React.useCallback(() => {
    const expandButtonWidth = expandable ? 40 : 0
    const totalSize = table.getCenterTotalSize() + table.getLeftTotalSize() + table.getRightTotalSize()
    return Math.max(totalSize + expandButtonWidth, 800) // 최소 800px 보장
  }, [table, expandable])

  // 행 확장/축소 핸들러
  const toggleRowExpansion = React.useCallback((rowId: string, event?: React.MouseEvent) => {
    if (!setExpandedRows) return
    
    if (event) {
      event.stopPropagation()
    }
    
    const newExpanded = new Set(expandedRows)
    if (newExpanded.has(rowId)) {
      newExpanded.delete(rowId)
      setExpandedHeights(prev => {
        const newHeights = new Map(prev)
        newHeights.delete(rowId)
        return newHeights
      })
    } else {
      newExpanded.add(rowId)
    }
    setExpandedRows(newExpanded)
  }, [expandedRows, setExpandedRows])

  // 키보드 네비게이션 핸들러
  const handleKeyDown = React.useCallback((event: React.KeyboardEvent, rowId: string) => {
    if (event.key === 'Enter' || event.key === ' ') {
      event.preventDefault()
      toggleRowExpansion(rowId)
    }
  }, [toggleRowExpansion])

  // 🎯 확장된 내용 스타일 계산 함수 (컨테이너 너비 기준)
  const getExpandedContentStyle = React.useCallback(() => {
    const expandButtonWidth = expandable ? 40 : 0
    const availableWidth = containerWidth || 800 // 🎯 컨테이너 너비 사용 (fallback 800px)
    const contentWidth = availableWidth - expandButtonWidth - 32 // 버튼 + 여백(16px * 2) 제외
    
    // 🎯 디버그 정보
    if (debug) {
      console.log('Expanded content sizing:', {
        containerWidth,
        availableWidth,
        expandButtonWidth,
        contentWidth,
        finalWidth: Math.max(contentWidth, 300)
      })
    }
    
    return {
      width: `${Math.max(contentWidth, 300)}px`, // 🎯 최소 300px 보장
      marginLeft: `${expandButtonWidth + 8}px`, // 🎯 확장 버튼 + 여백
      marginRight: '16px',
      padding: '12px 16px',
      backgroundColor: 'hsl(var(--background))',
      borderRadius: '0 0 6px 6px',
      boxShadow: '0 2px 4px -1px rgba(0, 0, 0, 0.1)',
      border: '1px solid hsl(var(--border))',
      borderTop: 'none',
      marginBottom: '4px',
      maxWidth: `${availableWidth - expandButtonWidth - 16}px`, // 🎯 컨테이너 너비 초과 방지
      overflow: 'auto',
    }
  }, [expandable, containerWidth, debug])

  // 🎯 간단한 확장 스타일 (컨테이너 너비 기준)
  const getSimpleExpandedStyle = React.useCallback(() => {
    const expandButtonWidth = expandable ? 40 : 0
    const availableWidth = containerWidth || 800
    const contentWidth = availableWidth - expandButtonWidth - 48 // 버튼 + 여백 제외
    
    return {
      marginLeft: `${expandButtonWidth + 8}px`,
      marginRight: '16px',
      width: `${Math.max(contentWidth, 300)}px`,
      maxWidth: `${availableWidth - expandButtonWidth - 24}px`,
      padding: '12px 16px',
      backgroundColor: 'hsl(var(--muted) / 0.5)',
      borderRadius: '6px',
      border: '1px solid hsl(var(--border))',
      marginTop: '8px',
      marginBottom: '8px',
      overflow: 'auto',
    }
  }, [expandable, containerWidth])

  // 🎯 사용할 확장 스타일 선택 (props로 제어)
  const useSimpleExpansion = simpleExpansion
  const getExpandedPlaceholderHeight = React.useCallback((contentHeight: number) => {
    const padding = 24 + 4 // padding (12px * 2) + marginBottom (4px)
    return Math.max(contentHeight + padding, 220)
  }, [])
  const updateExpandedHeight = React.useCallback((rowId: string, height: number) => {
    setExpandedHeights(prev => {
      if (prev.get(rowId) !== height) {
        const newHeights = new Map(prev)
        newHeights.set(rowId, height)
        return newHeights
      }
      return prev
    })
  }, [])

  // 컴팩트 모드 스타일
  const compactStyles = compact ? {
    row: "h-7",
    cell: "py-1 px-2 text-sm",
    header: "py-1 px-2 text-sm",
    headerRow: "h-8",
    expandedCell: "py-2 px-4",
    groupRow: "py-1 bg-muted/20 text-sm",
    emptyRow: "h-16",
  } : {
    row: "",
    cell: "",
    header: "",
    headerRow: "",
    expandedCell: "py-0 px-0",
    groupRow: "bg-muted/20",
    emptyRow: "h-24",
  }

  // 확장 버튼 렌더링
  const renderExpandButton = (rowId: string) => {
    if (!expandable || !setExpandedRows) return null
    
    const isExpanded = expandedRows.has(rowId)
    
    return (
      <button
        onClick={(e) => toggleRowExpansion(rowId, e)}
        onKeyDown={(e) => handleKeyDown(e, rowId)}
        className="inline-flex items-center justify-center w-6 h-6 hover:bg-gray-100 rounded transition-colors focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-1"
        aria-label={isExpanded ? "행 축소" : "행 확장"}
        aria-expanded={isExpanded}
        tabIndex={0}
        type="button"
      >
        {isExpanded ? (
          <ChevronDown className="w-4 h-4" />
        ) : (
          <ChevronRight className="w-4 h-4" />
        )}
      </button>
    )
  }

  // 확장된 내용 래퍼 컴포넌트
  const ExpandedContentWrapper = React.memo<{
    rowId: string
    children: React.ReactNode
  }>(({ rowId, children }) => {
    const contentRef = React.useRef<HTMLDivElement>(null)

    React.useEffect(() => {
      if (contentRef.current) {
        const resizeObserver = new ResizeObserver((entries) => {
          for (const entry of entries) {
            updateExpandedHeight(rowId, entry.contentRect.height)
          }
        })

        resizeObserver.observe(contentRef.current)
        return () => resizeObserver.disconnect()
      }
    }, [rowId])

    return (
      <div ref={contentRef} className="w-full">
        {children}
      </div>
    )
  })

  ExpandedContentWrapper.displayName = "ExpandedContentWrapper"

  return (
    <div className={cn("w-full space-y-2.5", className)} {...props}>
      {children}
      
      <div 
        ref={containerRef} // 🎯 컨테이너 wrapper ref (패딩 제외 너비 계산용)
        className="relative rounded-md border"
        style={{ 
          minHeight: '200px'
        }}
      >
        <div 
          ref={scrollRef} // 🎯 스크롤 컨테이너 ref 연결
          className="overflow-auto"
          style={{ maxHeight: maxHeight || '34rem' }}
          onScroll={handleScroll} // 🎯 스크롤 이벤트 핸들러
        >
          <Table 
            className="[&>thead]:sticky [&>thead]:top-0 [&>thead]:z-10"
            style={{ 
              width: getTableWidth(), // 🎯 동적 너비 계산
              minWidth: '100%'
            }}
          >
            <TableHeader className="bg-background">
              {table.getHeaderGroups().map((headerGroup) => (
                <TableRow key={headerGroup.id} className={compactStyles.headerRow}>
                  {expandable && (
                    <TableHead 
                      className={cn("w-10", compactStyles.header)}
                      style={getExpandButtonStyle()}
                    />
                  )}
                  
                  {headerGroup.headers.map((header) => {
                    if (header.column.getIsGrouped()) {
                      return null
                    }

                    return (
                      <TableHead
                        key={header.id}
                        colSpan={header.colSpan}
                        data-column-id={header.column.id}
                        className={cn(
                          compactStyles.header,
                          "bg-background"
                        )}
                        style={{
                          ...getPinnedStyle(header.column, true), // 🎯 동적 스타일
                          width: header.getSize() // 🎯 width 별도 설정
                        }}
                      >
                        <div style={{ position: "relative" }}>
                          {header.isPlaceholder
                            ? null
                            : flexRender(
                              header.column.columnDef.header,
                              header.getContext()
                            )}

                          {header.column.getCanResize() && (
                            <DataTableResizer header={header} />
                          )}
                        </div>
                      </TableHead>
                    )
                  })}
                </TableRow>
              ))}
            </TableHeader>

            <TableBody>
              {table.getRowModel().rows?.length ? (
                table.getRowModel().rows.map((row) => {
                  const isExpanded = expandedRows.has(row.id)
                  const expandedHeight = expandedHeights.get(row.id) || 0
                  
                  if (row.getIsGrouped()) {
                    const groupingColumnId = row.groupingColumnId ?? ""
                    const groupingColumn = table.getColumn(groupingColumnId)

                    let columnLabel = groupingColumnId
                    if (groupingColumn) {
                      const headerDef = groupingColumn.columnDef.meta?.excelHeader
                      if (typeof headerDef === "string") {
                        columnLabel = headerDef
                      }
                    }

                    return (
                      <TableRow
                        key={row.id}
                        className={compactStyles.groupRow}
                        data-state={row.getIsExpanded() && "expanded"}
                      >
                        <TableCell 
                          colSpan={table.getVisibleFlatColumns().length + (expandable ? 1 : 0)}
                          className={compact ? "py-1 px-2" : ""}
                        >
                          {row.getCanExpand() && (
                            <button
                              onClick={row.getToggleExpandedHandler()}
                              className="inline-flex items-center justify-center mr-2 w-5 h-5 hover:bg-gray-100 rounded focus:outline-none focus:ring-2 focus:ring-blue-500"
                              style={{
                                marginLeft: `${row.depth * 1.5}rem`,
                              }}
                              aria-label={row.getIsExpanded() ? "그룹 축소" : "그룹 확장"}
                            >
                              {row.getIsExpanded() ? (
                                <ChevronUp size={compact ? 14 : 16} />
                              ) : (
                                <ChevronRight size={compact ? 14 : 16} />
                              )}
                            </button>
                          )}

                          <span className="font-semibold">
                            {columnLabel}: {row.getValue(groupingColumnId)}
                          </span>
                          <span className="ml-2 text-xs text-muted-foreground">
                            ({row.subRows.length} rows)
                          </span>
                        </TableCell>
                      </TableRow>
                    )
                  }

                  return (
                    <React.Fragment key={row.id}>
                      <TableRow
                        className={cn(
                          compactStyles.row,
                          isExpanded && "bg-muted/30 border-b-0"
                        )}
                        data-state={row.getIsSelected() && "selected"}
                      >
                        {expandable && (
                          <TableCell 
                            className={cn("w-10", compactStyles.cell)}
                            style={getExpandButtonStyle()}
                          >
                            {renderExpandButton(row.id)}
                          </TableCell>
                        )}

                        {row.getVisibleCells().map((cell) => {
                          if (cell.column.getIsGrouped()) {
                            return null
                          }

                          return (
                            <TableCell
                              key={cell.id}
                              data-column-id={cell.column.id}
                              className={compactStyles.cell}
                              style={{
                                ...getPinnedStyle(cell.column, false), // 🎯 동적 스타일
                                width: cell.column.getSize() // 🎯 width 별도 설정
                              }}
                            >
                              {flexRender(
                                cell.column.columnDef.cell,
                                cell.getContext()
                              )}
                            </TableCell>
                          )
                        })}
                      </TableRow>

                      {isExpanded && renderExpandedContent && (
                        <TableRow className="hover:bg-transparent">
                          <TableCell
                            colSpan={table.getVisibleFlatColumns().length + (expandable ? 1 : 0)}
                            className={cn(
                              compactStyles.expandedCell,
                              "border-t-0 relative",
                              expandedRowClassName
                            )}
                            style={{
                              minHeight: expandedHeight || 'auto',
                            }}
                          >
                            {useSimpleExpansion ? (
                              // 🎯 간단한 확장 방식: 테이블 내부에서만 확장
                              <div style={getSimpleExpandedStyle()}>
                                <ExpandedContentWrapper rowId={row.id}>
                                  {renderExpandedContent(row.original)}
                                </ExpandedContentWrapper>
                              </div>
                            ) : (
                              // 🎯 전체 화면 확장 방식: 테이블 너비 기준으로 개선
                              <div className="relative w-full">
                                <div 
                                  className="absolute top-0"
                                  style={getExpandedContentStyle()}
                                >
                                  <ExpandedContentWrapper rowId={row.id}>
                                    {renderExpandedContent(row.original)}
                                  </ExpandedContentWrapper>
                                </div>
                                
                                <div 
                                  className="opacity-0 pointer-events-none"
                                  style={{ height: getExpandedPlaceholderHeight(expandedHeight) }}
                                />
                              </div>
                            )}
                          </TableCell>
                        </TableRow>
                      )}
                    </React.Fragment>
                  )
                })
              ) : (
                <TableRow>
                  <TableCell
                    colSpan={table.getAllColumns().length + (expandable ? 1 : 0)}
                    className={compactStyles.emptyRow + " text-center"}
                  >
                    No results.
                  </TableCell>
                </TableRow>
              )}
            </TableBody>
          </Table>
        </div>
      </div>

      <div className="flex flex-col gap-2.5">
        <DataTablePagination table={table} />
        {table.getFilteredSelectedRowModel().rows.length > 0 && floatingBar}
      </div>
    </div>
  )
}