"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 { getCommonPinningStylesWithBorder } 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
  compact?: boolean // compact 모드 추가
  onSelectedRowsChange?: (selected: TData[]) => void
  maxHeight?: string | number 
  /** 추가로 표시할 버튼/컴포넌트 */
  children?: React.ReactNode
  /** 선택 상태 초기화 트리거 */
  clearSelection?: boolean
}

export function ClientDataTable<TData, TValue>({
  columns,
  data,
  advancedFilterFields,
  autoSizeColumns = true,
  compact = true, // 기본값 true
  children,
  maxHeight,
  onSelectedRowsChange,
  clearSelection
}: 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 [columnPinning, setColumnPinning] = React.useState<ColumnPinningState>({
    left: ["select","TAG_NO", "TAG_DESC", "status"],
    right: ["update", 'actions'],
  })
  
  // 🎯 스크롤 상태 감지 추가
  const [isScrolled, setIsScrolled] = React.useState(false)

  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(() => {
    if (!onSelectedRowsChange) return
    const selectedRows = table
      .getSelectedRowModel()
      .flatRows.map((row) => row.original)
    onSelectedRowsChange(selectedRows)
  }, [rowSelection, table, onSelectedRowsChange])

  // clearSelection prop이 변경되면 선택 상태 초기화
  React.useEffect(() => {
    setRowSelection({})
  }, [clearSelection])

  // 🎯 스크롤 핸들러 추가
  const handleScroll = (e: React.UIEvent<HTMLDivElement>) => {
    const scrollLeft = e.currentTarget.scrollLeft
    setIsScrolled(scrollLeft > 0)
  }

  // 🎯 동적 핀 스타일 함수 (width 중복 제거)
  const getPinnedStyle = (column: any, isHeader: boolean = false) => {
    const baseStyle = getCommonPinningStylesWithBorder({ column })
    const pinnedSide = column.getIsPinned()
    
    // width를 제외한 나머지 스타일만 반환
    const { width, ...restBaseStyle } = baseStyle
    
    return {
      ...restBaseStyle,
      // 헤더는 핀 여부와 관계없이 항상 배경 유지 (sticky로 고정되어 있기 때문)
      ...(isHeader && {
        background: "hsl(var(--background))",
        transition: "none",
      }),
      // 바디 셀은 핀된 경우에만 스크롤 상태에 따라 동적 변경
      ...(!isHeader && pinnedSide && {
        background: isScrolled 
          ? "hsl(var(--background))" 
          : "transparent",
        transition: "background-color 0.15s ease-out",
      }),
    }
  }

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

  // 컴팩트 모드를 위한 클래스 정의
  const compactStyles = compact ? {
    row: "h-7", // 행 높이 축소
    cell: "py-1 px-2 text-sm", // 셀 패딩 축소 및 폰트 크기 조정
    header: "py-1 px-2 text-sm", // 헤더 패딩 축소
    headerRow: "h-8", // 헤더 행 높이 축소
    groupRow: "py-1 bg-muted/20 text-sm", // 그룹 행 패딩 축소
    emptyRow: "h-16", // 데이터 없을 때 행 높이 조정
  } : {
    row: "",
    cell: "",
    header: "",
    headerRow: "",
    groupRow: "bg-muted/20",
    emptyRow: "h-24",
  }

  // (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: maxHeight || '34rem' }}
          onScroll={handleScroll} // 🎯 스크롤 이벤트 핸들러 추가
        >
          <UiTable
            className="[&>thead]:sticky [&>thead]:top-0 [&>thead]:z-10"
            style={{ 
              width: getTableWidth(), // 🎯 동적 너비 계산
              minWidth: '100%'
            }}
          >
            <TableHeader>
              {table.getHeaderGroups().map((headerGroup) => (
                <TableRow key={headerGroup.id} className={compactStyles.headerRow}>
                  {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={compactStyles.header}
                        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) => {
                  // ---------------------------------------------------
                  // 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={compactStyles.groupRow}
                        data-state={row.getIsExpanded() && "expanded"}
                      >
                        {/* 그룹 헤더는 한 줄에 합쳐서 보여주고, 토글 버튼 + 그룹 라벨 + 값 표기 */}
                        <TableCell 
                          colSpan={table.getVisibleFlatColumns().length}
                          className={compact ? "py-1 px-2" : ""}
                        >
                          {/* 확장/축소 버튼 (아이콘 중앙 정렬 + 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={compact ? 14 : 16} />
                              ) : (
                                <ChevronRight size={compact ? 14 : 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}
                      className={compactStyles.row}
                      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}
                            className={compactStyles.cell}
                            style={{
                              ...getPinnedStyle(cell.column, false), // 🎯 바디 셀임을 명시
                              width: cell.column.getSize() // 🎯 width 별도 설정
                            }}
                          >
                            {flexRender(
                              cell.column.columnDef.cell,
                              cell.getContext()
                            )}
                          </TableCell>
                        )
                      })}
                    </TableRow>
                  )
                })
              ) : (
                // ---------------------------------------------------
                // 3) 데이터가 없을 때
                // ---------------------------------------------------
                <TableRow>
                  <TableCell
                    colSpan={table.getAllColumns().length}
                    className={compactStyles.emptyRow + " text-center"}
                  >
                    No results.
                  </TableCell>
                </TableRow>
              )}
            </TableBody>
          </UiTable>
        </div>
      </div>

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