"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
  // ✅ 새로운 props 추가
  clickableColumns?: string[] // 클릭 가능한 컬럼 ID들
  excludeFromClick?: string[] // 클릭에서 제외할 컬럼 ID들
}

export function ExpandableDataTable<TData>({
  table,
  floatingBar = null,
  autoSizeColumns = true,
  compact = false,
  expandedRows = new Set(),
  setExpandedRows,
  renderExpandedContent,
  expandable = false,
  maxHeight,
  expandedRowClassName,
  debug = false,
  simpleExpansion = false,
  // ✅ 새로운 props
  clickableColumns,
  excludeFromClick = ['actions'],
  children,
  className,
  ...props
}: ExpandableDataTableProps<TData>) {

  useAutoSizeColumns(table, autoSizeColumns)

  const containerRef = React.useRef<HTMLDivElement>(null)
  const scrollRef = React.useRef<HTMLDivElement>(null)
  const [expandedHeights, setExpandedHeights] = React.useState<Map<string, number>>(new Map())
  const [isScrolled, setIsScrolled] = React.useState(false)
  const [isScrolledToEnd, setIsScrolledToEnd] = React.useState(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) {
        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)
    )
    
    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)
    
    if (debug) {
      const allColumns = table.getAllColumns().map(col => col.id)
      const visibleColumns = table.getVisibleFlatColumns().map(col => col.id)
      console.log('🔍 Available columns:', { allColumns, visibleColumns, clickableColumns, excludeFromClick })
    }
  }, [table.getRowModel().rows.length, clickableColumns, excludeFromClick, debug])

  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
    setIsScrolledToEnd(isAtEnd)
    setIsInitialized(true)
    
    if (debug) {
      console.log('Scroll state:', {
        scrollLeft,
        scrollWidth,
        clientWidth,
        isScrolled: scrollLeft > 0,
        isScrolledToEnd: isAtEnd,
        remainingScroll: scrollWidth - clientWidth - scrollLeft
      })
    }
  }

  // 행 확장/축소 핸들러
  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 isCellClickable = React.useCallback((columnId: string) => {
    if (!expandable || !setExpandedRows) return false
    
    if (excludeFromClick.includes(columnId)) {
      if (debug) console.log('🚫 Column excluded:', columnId)
      return false
    }
    
    if (clickableColumns && clickableColumns.length > 0) {
      const isClickable = clickableColumns.includes(columnId)
      if (debug) console.log('📋 Column clickable check:', { columnId, clickableColumns, isClickable })
      return isClickable
    }
    
    if (debug) console.log('✅ Column clickable by default:', columnId)
    return true
  }, [expandable, setExpandedRows, clickableColumns, excludeFromClick, debug])

  // ✅ 셀 클릭 핸들러
  const handleCellClick = React.useCallback((rowId: string, columnId: string, event: React.MouseEvent) => {
    if (debug) console.log('🔍 Cell clicked:', { rowId, columnId, clickable: isCellClickable(columnId) })
    
    if (!isCellClickable(columnId)) {
      if (debug) console.log('❌ Cell not clickable:', columnId)
      return
    }
    
    const target = event.target as HTMLElement
    
    // 실제 BUTTON과 A 태그만 제외
    if (target.tagName === 'BUTTON' || target.tagName === 'A') {
      if (debug) console.log('❌ Button or link clicked, ignoring')
      return
    }
    
    if (debug) console.log('✅ Toggling row expansion for:', rowId)
    toggleRowExpansion(rowId, event)
  }, [isCellClickable, toggleRowExpansion, debug])

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

  // 핀 스타일 함수
  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) {
        const { width, ...restStyle } = baseStyle
        return {
          ...restStyle,
          ...(isHeader && {
            background: "hsl(var(--background))",
            transition: "none",
          }),
        }
      }

      let leftPosition = baseStyle.left
      if (expandable && pinnedSide === "left") {
        const expandButtonWidth = 40
        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
        }
      }
      
      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)
      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)
  }, [table, expandable])

  // 확장된 내용 스타일 계산
  const getExpandedContentStyle = React.useCallback(() => {
    const expandButtonWidth = expandable ? 40 : 0
    const availableWidth = containerWidth || 800
    const contentWidth = availableWidth - expandButtonWidth - 32
    
    if (debug) {
      console.log('Expanded content sizing:', {
        containerWidth,
        availableWidth,
        expandButtonWidth,
        contentWidth,
        finalWidth: Math.max(contentWidth, 300)
      })
    }
    
    return {
      width: `${Math.max(contentWidth, 300)}px`,
      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])

  const useSimpleExpansion = simpleExpansion
  const getExpandedPlaceholderHeight = React.useCallback((contentHeight: number) => {
    const padding = 24 + 4
    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}
        className="relative rounded-md border"
        style={{ 
          minHeight: '200px'
        }}
      >
        <div 
          ref={scrollRef}
          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),
                          // 부모 그룹 헤더는 colSpan으로 너비가 결정되므로 width 설정하지 않음
                          // 자식 헤더만 개별 width 설정
                          ...(!('columns' in header.column.columnDef) && { width: header.getSize() }),
                        }}
                      >
                        <div style={{ position: "relative" }}>
                          {header.isPlaceholder
                            ? null
                            : flexRender(
                              header.column.columnDef.header,
                              header.getContext()
                            )}

                          {/* 부모 그룹 헤더는 리사이즈 불가, 자식 헤더만 리사이즈 가능 */}
                          {header.column.getCanResize() && !('columns' in header.column.columnDef) && (
                            <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
                          }

                          const isClickable = isCellClickable(cell.column.id)

                          return (
                            <TableCell
                              key={cell.id}
                              data-column-id={cell.column.id}
                              className={cn(
                                compactStyles.cell,
                                // ✅ 클릭 가능한 셀에 시각적 피드백 추가
                                isClickable && "cursor-pointer hover:bg-muted/50 transition-colors"
                              )}
                              style={{
                                ...getPinnedStyle(cell.column, false),
                                width: cell.column.getSize()
                              }}
                              // ✅ 클릭 이벤트 추가
                              onClick={isClickable ? (e) => handleCellClick(row.id, cell.column.id, e) : undefined}
                              // ✅ 접근성 개선
                              role={isClickable ? "button" : undefined}
                              tabIndex={isClickable ? 0 : undefined}
                              onKeyDown={isClickable ? (e) => {
                                if (e.key === 'Enter' || e.key === ' ') {
                                  e.preventDefault()
                                  handleCellClick(row.id, cell.column.id, e as any)
                                }
                              } : undefined}
                              aria-label={isClickable ? `${isExpanded ? '행 축소' : '행 확장'} - ${cell.column.id}` : undefined}
                            >
                              {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>
  )
}