"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 { getCommonPinningStyles } 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 // 확장된 행의 커스텀 클래스
}

/**
 * 확장 가능한 데이터 테이블 - 행 확장 시 바로 아래에 컨텐츠 표시
 * 개선사항:
 * - 가로스크롤과 확장된 내용 독립성 보장
 * - 동적 높이 계산으로 세로스크롤 문제 해결
 * - 향상된 접근성 및 키보드 네비게이션
 */
export function ExpandableDataTable<TData>({
  table,
  floatingBar = null,
  autoSizeColumns = true,
  compact = false,
  expandedRows = new Set(),
  setExpandedRows,
  renderExpandedContent,
  expandable = false,
  maxHeight,
  expandedRowClassName,
  children,
  className,
  ...props
}: ExpandableDataTableProps<TData>) {

  useAutoSizeColumns(table, autoSizeColumns)

  // 스크롤 컨테이너 참조
  const scrollContainerRef = React.useRef<HTMLDivElement>(null)
  const [expandedHeights, setExpandedHeights] = React.useState<Map<string, number>>(new Map())

  // 행 확장/축소 핸들러 (개선된 버전)
  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 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",
    expandedCell: "py-2 px-4",
    groupRow: "py-1 bg-muted/20 text-sm",
    emptyRow: "h-16",
  } : {
    row: "",
    cell: "",
    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={scrollContainerRef}
        className="relative rounded-md border"
        style={{ 
          // maxHeight: maxHeight || '35rem',
          minHeight: '200px' // 최소 높이 보장
        }}
      >
        {/* 가로스크롤 영역 */}
        <div className="overflow-x-auto overflow-y-hidden h-full">
          {/* 세로스크롤 영역 (확장된 내용 포함) */}
          <div className="overflow-y-auto h-full">
            <Table className="[&>thead]:sticky [&>thead]:top-0 [&>thead]:z-10 table-fixed">
              {/* 테이블 헤더 */}
              <TableHeader className="bg-background">
                {table.getHeaderGroups().map((headerGroup) => (
                  <TableRow key={headerGroup.id} className={compact ? "h-8" : ""}>
                    {/* 확장 버튼 컬럼 헤더 */}
                    {expandable && (
                      <TableHead 
                        className={cn("w-10 bg-background", compact ? "py-1 px-2" : "")}
                        style={{ position: 'sticky', left: 0, zIndex: 11 }}
                      />
                    )}
                    
                    {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(
                            compact ? "py-1 px-2 text-sm" : "",
                            "bg-background"
                          )}
                          style={{
                            ...getCommonPinningStyles({ column: header.column }),
                            width: header.getSize(),
                          }}
                        >
                          <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
                    
                    // 그룹핑 헤더 Row
                    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>
                      )
                    }

                    // 일반 Row와 확장된 컨텐츠를 함께 렌더링
                    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={{ 
                                position: 'sticky', 
                                left: 0, 
                                zIndex: 1,
                                backgroundColor: isExpanded ? 'rgb(248 250 252)' : 'white'
                              }}
                            >
                              {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={{
                                  ...getCommonPinningStyles({ column: cell.column }),
                                  width: cell.column.getSize(),
                                }}
                              >
                                {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',
                              }}
                            >
                              {/* 확장된 내용을 위한 고정 폭 컨테이너 */}
                              <div className="relative w-full">
                                {/* 가로스크롤과 독립적인 확장 영역 */}
                                <div 
                                  className="absolute left-0 right-0 top-0 border-t"
                                  style={{
                                    width: '80vw',
                                    marginLeft: 'calc(-48vw + 50%)',
                                  }}
                                >
                                  <div className="max-w-none mx-auto">
                                    <ExpandedContentWrapper rowId={row.id}>
                                      {renderExpandedContent(row.original)}
                                    </ExpandedContentWrapper>
                                  </div>
                                </div>
                                
                                {/* 높이 유지를 위한 스페이서 */}
                                <div 
                                  className="opacity-0 pointer-events-none"
                                  style={{ height: Math.max(expandedHeight, 200) }}
                                />
                              </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>

      <div className="flex flex-col gap-2.5">
        {/* Pagination */}
        <DataTablePagination table={table} />

        {/* Floating Bar (선택된 행 있을 때) */}
        {table.getFilteredSelectedRowModel().rows.length > 0 && floatingBar}
      </div>
    </div>
  )
}