import { useEffect, useMemo, useRef } from 'react';
import { Skeleton } from 'antd';
import { AgGridReact } from '@ag-grid-community/react';
import { ModuleRegistry } from '@ag-grid-community/core';
import { ClientSideRowModelModule } from '@ag-grid-community/client-side-row-model';
import type { ColDef, GridReadyEvent, GridApi, RowClassParams, RowStyle, SelectionChangedEvent } from '@ag-grid-community/core';
import '@ag-grid-community/styles/ag-grid.css';
import '@ag-grid-community/styles/ag-theme-quartz.css';
import { GRAY } from '@/theme/tokens';

ModuleRegistry.registerModules([ClientSideRowModelModule]);

const AG_GRID_LOCALE_KO: Record<string, string> = {
  page: '페이지', more: '더보기', to: '~', of: '/', next: '다음', last: '마지막',
  first: '처음', previous: '이전', loadingOoo: '불러오는 중...',
  selectAll: '전체 선택', searchOoo: '검색...', blanks: '(빈값)',
  filterOoo: '필터...', equals: '같음', notEqual: '같지않음',
  contains: '포함', notContains: '포함하지않음', startsWith: '시작',
  endsWith: '끝', noRowsToShow: '데이터가 없습니다', resetColumns: '컬럼 초기화',
  pinColumn: '컬럼 고정', valueAggregation: '집계',
  sum: '합계', min: '최소', max: '최대', count: '건수',
};

interface Props<T> {
  rows: T[] | undefined;
  columns: ColDef<T>[];
  loading?: boolean;
  height?: number | string;
  /** 합계행 데이터 */
  pinnedBottomRow?: Partial<T>;
  /** 셀 편집 가능 시 콜백 */
  onCellChanged?: (row: T, field: string, newValue: unknown) => void;
  rowKey?: keyof T;
  /** 행별 스타일 콜백 (만료 임박 강조 등) */
  getRowStyle?: (params: RowClassParams<T>) => RowStyle | undefined;
  rowSelection?: 'single' | 'multiple';
  onSelectionChanged?: (e: SelectionChangedEvent<T>) => void;
}

/**
 * AG Grid Community 클라이언트사이드 래퍼.
 * - ag-theme-quartz 적용
 * - 헤더 폰트/높이 tokens 와 동기화
 * - 로딩 시 Skeleton 표시
 */
export default function DataGrid<T extends Record<string, unknown>>({
  rows,
  columns,
  loading,
  height = 600,
  pinnedBottomRow,
  onCellChanged,
  rowKey,
  getRowStyle: getRowStyleProp,
  rowSelection: rowSelectionProp = 'single',
  onSelectionChanged,
}: Props<T>) {
  const apiRef = useRef<GridApi<T> | null>(null);

  const defaultColDef = useMemo<ColDef>(
    () => ({
      sortable:       true,
      filter:         true,
      resizable:      true,
      suppressMovable: false,
      cellStyle:       { display: 'flex', alignItems: 'center' },
    }),
    [],
  );

  const onGridReady = (e: GridReadyEvent<T>) => {
    apiRef.current = e.api;
  };

  useEffect(() => {
    if (apiRef.current) {
      if (loading) apiRef.current.showLoadingOverlay();
      else         apiRef.current.hideOverlay();
    }
  }, [loading]);

  if (loading && !rows?.length) {
    return (
      <div style={{ padding: 24, background: '#fff', borderRadius: 16, border: `1px solid ${GRAY[100]}` }}>
        <Skeleton active paragraph={{ rows: 8 }} />
      </div>
    );
  }

  return (
    <div className="ag-theme-quartz" style={{ height, width: '100%' }}>
      <AgGridReact<T>
        rowData={rows}
        columnDefs={columns}
        defaultColDef={defaultColDef}
        animateRows
        rowHeight={56}
        headerHeight={44}
        localeText={AG_GRID_LOCALE_KO}
        rowSelection={rowSelectionProp}
        onSelectionChanged={onSelectionChanged}
        getRowId={rowKey ? (p) => String(p.data[rowKey]) : undefined}
        pinnedBottomRowData={pinnedBottomRow ? [pinnedBottomRow as T] : undefined}
        getRowStyle={(params) => {
          if (params.node.rowPinned) {
            return { background: '#f0f4ff', fontWeight: 600 };
          }
          if (getRowStyleProp) {
            return getRowStyleProp(params as RowClassParams<T>);
          }
          return undefined;
        }}
        onCellValueChanged={(e) => {
          if (onCellChanged && e.data) {
            onCellChanged(e.data, String(e.colDef.field), e.newValue);
          }
        }}
        onGridReady={onGridReady}
        loadingOverlayComponent={() => (
          <div style={{ padding: 24, color: GRAY[500], fontSize: 13 }}>불러오는 중...</div>
        )}
        noRowsOverlayComponent={() => (
          <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', padding: 40, color: GRAY[400] }}>
            <div style={{ fontSize: 32, marginBottom: 8 }}>📭</div>
            <div style={{ fontSize: 13 }}>데이터가 없습니다</div>
          </div>
        )}
      />
    </div>
  );
}
