"use client"

import * as React from "react"
import {
  ColumnDef,
  ColumnFiltersState,
  SortingState,
  VisibilityState,
  flexRender,
  getCoreRowModel,
  getFacetedRowModel,
  getFacetedUniqueValues,
  getFilteredRowModel,
  getPaginationRowModel,
  getSortedRowModel,
  useReactTable,
  Table, 
  getGroupedRowModel, 
  getExpandedRowModel,
  ColumnSizingState, ColumnPinningState
} from "@tanstack/react-table"
import {
  Table as UiTable,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table"
import { getCommonPinningStyles } from "@/lib/data-table"
import { ChevronRight, ChevronUp } from "lucide-react"

import { ClientDataTableAdvancedToolbar } from "./data-table-toolbar"
import { ClientDataTablePagination } from "./data-table-pagination"
import { DataTableResizer } from "./data-table-resizer"
import { useAutoSizeColumns } from "@/hooks/useAutoSizeColumns"

interface DataTableProps<TData, TValue> {
  columns: ColumnDef<TData, TValue>[]
  data: TData[]
  advancedFilterFields: any[]
  autoSizeColumns?: boolean
  onSelectedRowsChange?: (selected: TData[]) => void

  /** 추가로 표시할 버튼/컴포넌트 */
  children?: React.ReactNode
}

export function ClientDataTable<TData, TValue>({
  columns,
  data,
  advancedFilterFields,
  autoSizeColumns = true,
  children,
  onSelectedRowsChange
}: DataTableProps<TData, TValue>) {

  
  // (1) React Table 상태
  const [rowSelection, setRowSelection] = React.useState({})
  const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>({})
  const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>([])
  const [sorting, setSorting] = React.useState<SortingState>([])
  const [grouping, setGrouping] = React.useState<string[]>([])
  const [columnSizing, setColumnSizing] = React.useState<ColumnSizingState>({})
  
  // 실제 리사이징 상태만 추적
  const [isResizing, setIsResizing] = React.useState(false)
  
  // 리사이징 상태를 추적하기 위한 ref
  const isResizingRef = React.useRef(false)

  // 리사이징 이벤트 핸들러
  const handleResizeStart = React.useCallback(() => {
    isResizingRef.current = true
    setIsResizing(true)
  }, [])

  const handleResizeEnd = React.useCallback(() => {
    isResizingRef.current = false
    setIsResizing(false)
  }, [])

  const [columnPinning, setColumnPinning] = React.useState<ColumnPinningState>({
    left: [],
    right: ["update"],
  })
  
  const table = useReactTable({
    data,
    columns,
    state: {
      sorting,
      columnVisibility,
      rowSelection,
      columnFilters,
      grouping,
      columnSizing,
      columnPinning
    },
    columnResizeMode: "onChange",
    onColumnSizingChange: setColumnSizing,
    enableRowSelection: true,
    onRowSelectionChange: setRowSelection,
    onSortingChange: setSorting,
    onColumnFiltersChange: setColumnFilters,
    onColumnVisibilityChange: setColumnVisibility,
    onGroupingChange: setGrouping,
    getCoreRowModel: getCoreRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    getSortedRowModel: getSortedRowModel(),
    getFacetedRowModel: getFacetedRowModel(),
    getFacetedUniqueValues: getFacetedUniqueValues(),
    getGroupedRowModel: getGroupedRowModel(),
    autoResetPageIndex: false,
    getExpandedRowModel: getExpandedRowModel(),
    enableColumnPinning:true,
    onColumnPinningChange:setColumnPinning

  })

  useAutoSizeColumns(table, autoSizeColumns)

  // 컴포넌트 마운트 시 강제로 리사이징 상태 초기화
  React.useEffect(() => {
    // 강제로 초기 상태는 리사이징 비활성화
    setIsResizing(false)
    isResizingRef.current = false
    
    // 전역 마우스 이벤트 핸들러
    const handleMouseUp = () => {
      if (isResizingRef.current) {
        handleResizeEnd()
      }
    }
    
    // 이벤트 리스너 등록
    window.addEventListener('mouseup', handleMouseUp)
    window.addEventListener('touchend', handleMouseUp)
    
    return () => {
      // 이벤트 리스너 정리
      window.removeEventListener('mouseup', handleMouseUp)
      window.removeEventListener('touchend', handleMouseUp)
      
      // 컴포넌트 언마운트 시 정리
      setIsResizing(false)
      isResizingRef.current = false
    }
  }, [handleResizeEnd])

  React.useEffect(() => {
    if (!onSelectedRowsChange) return
    const selectedRows = table
      .getSelectedRowModel()
      .flatRows.map((row) => row.original)
    onSelectedRowsChange(selectedRows)
  }, [rowSelection, table, onSelectedRowsChange])

  // (2) 렌더
  return (
    <div className="space-y-4">
      {/* 툴바에 children을 넘기기 */}
      <ClientDataTableAdvancedToolbar
        table={table}
        filterFields={advancedFilterFields}
        shallow={false}
      >
        {children}
      </ClientDataTableAdvancedToolbar>

      <div className="rounded-md border">
        <div className="overflow-auto" style={{maxHeight:'33.6rem'}}>
          <UiTable
            className="[&>thead]:sticky [&>thead]:top-0 [&>thead]:z-10 table-fixed"
          >
            <TableHeader>
              {table.getHeaderGroups().map((headerGroup) => (
                <TableRow key={headerGroup.id}>
                  {headerGroup.headers.map((header) => {
                    // 만약 이 컬럼이 현재 "그룹핑" 상태라면 헤더도 표시하지 않음
                    if (header.column.getIsGrouped()) {
                      return null
                    }

                    return (
                      <TableHead
                        key={header.id}
                        colSpan={header.colSpan}
                        className="relative"
                        style={{
                          ...getCommonPinningStyles({ column: header.column }),
                          width: header.getSize()
                        }}
                      >
                        {header.isPlaceholder
                          ? null
                          : flexRender(
                            header.column.columnDef.header,
                            header.getContext()
                          )}
                          
                        {/* 리사이즈 핸들 - 헤더에만 추가 */}
                        {header.column.getCanResize() && (
                          <DataTableResizer 
                            header={header} 
                            onResizeStart={handleResizeStart}
                            onResizeEnd={handleResizeEnd}
                          />
                        )}
                      </TableHead>
                    )
                  })}
                </TableRow>
              ))}
            </TableHeader>
            <TableBody>
              {table.getRowModel().rows?.length ? (
                table.getRowModel().rows.map((row) => {
                  // ---------------------------------------------------
                  // 1) "그룹핑 헤더" Row인지 확인
                  // ---------------------------------------------------
                  if (row.getIsGrouped()) {
                    // row.groupingColumnId로 어떤 컬럼을 기준으로 그룹화 되었는지 알 수 있음
                    const groupingColumnId = row.groupingColumnId ?? ""
                    const groupingColumn = table.getColumn(groupingColumnId) // 해당 column 객체

                    // 컬럼 라벨 가져오기
                    let columnLabel = groupingColumnId
                    if (groupingColumn) {
                      const headerDef = groupingColumn.columnDef.meta?.excelHeader
                      if (typeof headerDef === "string") {
                        columnLabel = headerDef
                      }
                    }

                    return (
                      <TableRow
                        key={row.id}
                        className="bg-muted/20"
                        data-state={row.getIsExpanded() && "expanded"}
                      >
                        {/* 그룹 헤더는 한 줄에 합쳐서 보여주고, 토글 버튼 + 그룹 라벨 + 값 표기 */}
                        <TableCell colSpan={table.getVisibleFlatColumns().length}>
                          {/* 확장/축소 버튼 (아이콘 중앙 정렬 + Indent) */}
                          {row.getCanExpand() && (
                            <button
                              onClick={row.getToggleExpandedHandler()}
                              className="inline-flex items-center justify-center mr-2 w-5 h-5"
                              style={{
                                // row.depth: 0이면 top-level, 1이면 그 하위 등
                                marginLeft: `${row.depth * 1.5}rem`,
                              }}
                            >
                              {row.getIsExpanded() ? (
                                <ChevronUp size={16} />
                              ) : (
                                <ChevronRight size={16} />
                              )}
                            </button>
                          )}

                          {/* Group Label + 값 */}
                          <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>
                    )
                  }

                  // ---------------------------------------------------
                  // 2) 일반 Row
                  //  → "그룹핑된 컬럼"은 숨긴다
                  // ---------------------------------------------------
                  return (
                    <TableRow
                      key={row.id}
                      data-state={row.getIsSelected() && "selected"}
                    >
                      {row.getVisibleCells().map((cell) => {
                        // 이 셀의 컬럼이 grouped라면 숨긴다
                        if (cell.column.getIsGrouped()) {
                          return null
                        }

                        return (
                          <TableCell
                            key={cell.id}
                            data-column-id={cell.column.id}
                            style={{
                              ...getCommonPinningStyles({ column: cell.column }),
                              width: cell.column.getSize()
                            }}
                          >
                            {flexRender(
                              cell.column.columnDef.cell,
                              cell.getContext()
                            )}
                          </TableCell>
                        )
                      })}
                    </TableRow>
                  )
                })
              ) : (
                // ---------------------------------------------------
                // 3) 데이터가 없을 때
                // ---------------------------------------------------
                <TableRow>
                  <TableCell
                    colSpan={table.getAllColumns().length}
                    className="h-24 text-center"
                  >
                    No results.
                  </TableCell>
                </TableRow>
              )}
            </TableBody>
          </UiTable>
          
          {/* 리사이징 시에만 캡처 레이어 활성화 */}
          {isResizing && (
            <div className="fixed inset-0 cursor-col-resize select-none z-50" />
          )}
        </div>
      </div>

      <ClientDataTablePagination table={table} />
    </div>
  )
}