import { useState, useMemo, useRef } from 'react';
import { SearchInput } from './SearchInput';
import { Pagination } from './Pagination';
import { ExcelExport } from './ExcelExport';
import { PrintButton } from './PrintButton';
import { ArrowUpDown, ArrowUp, ArrowDown } from 'lucide-react';
import { useAuth } from '@/app/auth/AuthContext';

/*
 * SFR-02 공통컴포넌트: 데이터 테이블
 * 검색, 정렬, 페이징, 엑셀 내보내기, 출력 통합
 */

export interface DataColumn<T> {
  key: string;
  label: string;
  /** 선호 최소 너비. 컨텐츠가 더 길면 자동 확장. */
  width?: string;
  /** 명시 최소 너비 (width와 사실상 동일하나 의미 강조용) */
  minWidth?: string;
  /** 최대 너비 (초과 시 ellipsis 트런케이트) */
  maxWidth?: string;
  align?: 'left' | 'center' | 'right';
  sortable?: boolean;
  render?: (value: unknown, row: T, index: number) => React.ReactNode;
}

interface DataTableProps<T extends Record<string, unknown>> {
  data: T[];
  columns: DataColumn<T>[];
  pageSize?: number;
  searchPlaceholder?: string;
  searchKeys?: string[];
  exportFilename?: string;
  title?: string;
  showSearch?: boolean;
  showExport?: boolean;
  showPrint?: boolean;
  showPagination?: boolean;
  onRowClick?: (row: T) => void;
  className?: string;
  /** 이 표가 속한 리소스 코드 (예: "admin:audit-logs"). EXPORT 권한 가드에 사용. */
  exportResource?: string;
}

export function DataTable<T extends Record<string, unknown>>({
  data,
  columns,
  pageSize = 20,
  searchPlaceholder = '검색...',
  searchKeys,
  exportFilename = 'data',
  title,
  showSearch = true,
  showExport = true,
  showPrint = true,
  showPagination = true,
  onRowClick,
  className = '',
  exportResource,
}: DataTableProps<T>) {
  // EXPORT 권한 체크: exportResource가 지정되면 hasPermission으로 가드
  // 미지정 시 항상 표시 (하위 호환)
  const { hasPermission } = useAuth();
  const canExport = exportResource ? hasPermission(exportResource, 'EXPORT') : true;
  const [query, setQuery] = useState('');
  const [page, setPage] = useState(0);
  const [sortKey, setSortKey] = useState<string | null>(null);
  const [sortDir, setSortDir] = useState<'asc' | 'desc'>('asc');
  const tableRef = useRef<HTMLDivElement>(null);

  // 검색 필터
  const keys = searchKeys || columns.map((c) => c.key);
  const filtered = useMemo(() => {
    if (!query) return data;
    const q = query.toLowerCase();
    return data.filter((row) =>
      keys.some((k) => {
        const v = row[k];
        return v != null && String(v).toLowerCase().includes(q);
      })
    );
  }, [data, query, keys]);

  // 정렬
  const sorted = useMemo(() => {
    if (!sortKey) return filtered;
    return [...filtered].sort((a, b) => {
      const va = a[sortKey] ?? '';
      const vb = b[sortKey] ?? '';
      const cmp = String(va).localeCompare(String(vb), 'ko', { numeric: true });
      return sortDir === 'asc' ? cmp : -cmp;
    });
  }, [filtered, sortKey, sortDir]);

  // 페이징
  const totalPages = Math.ceil(sorted.length / pageSize);
  const paged = sorted.slice(page * pageSize, (page + 1) * pageSize);

  const handleSort = (key: string) => {
    if (sortKey === key) {
      setSortDir(sortDir === 'asc' ? 'desc' : 'asc');
    } else {
      setSortKey(key);
      setSortDir('asc');
    }
    setPage(0);
  };

  const handleSearch = (v: string) => {
    setQuery(v);
    setPage(0);
  };

  return (
    <div className={className}>
      {/* 상단 툴바 */}
      <div className="flex items-center gap-2 mb-3">
        {title && <span className="text-[12px] text-label font-bold mr-auto">{title}</span>}
        {showSearch && (
          <SearchInput
            value={query}
            onChange={handleSearch}
            placeholder={searchPlaceholder}
            className="w-64"
          />
        )}
        <div className="flex items-center gap-1.5 ml-auto">
          {showExport && canExport && (
            <ExcelExport
              data={sorted as Record<string, unknown>[]}
              columns={columns.map((c) => ({ key: c.key, label: c.label }))}
              filename={exportFilename}
            />
          )}
          {showPrint && <PrintButton targetRef={tableRef} />}
        </div>
      </div>

      {/* 테이블 */}
      <div ref={tableRef} className="rounded-xl border border-border bg-card overflow-x-auto">
        <table className="w-full text-[11px]" style={{ tableLayout: 'auto' }}>
          <thead>
            <tr className="border-b border-border">
              {columns.map((col) => {
                const cellStyle: React.CSSProperties = {};
                // width = 선호 최소 너비. 컨텐츠가 더 길면 자동 확장.
                if (col.width) cellStyle.minWidth = col.width;
                if (col.minWidth) cellStyle.minWidth = col.minWidth;
                if (col.maxWidth) cellStyle.maxWidth = col.maxWidth;
                return (
                  <th
                    key={col.key}
                    className={`px-4 py-2.5 font-medium text-hint whitespace-nowrap overflow-hidden text-ellipsis ${
                      col.align === 'center' ? 'text-center' : col.align === 'right' ? 'text-right' : 'text-left'
                    } ${col.sortable !== false ? 'cursor-pointer hover:text-label select-none' : ''}`}
                    style={cellStyle}
                    onClick={() => col.sortable !== false && handleSort(col.key)}
                  >
                    <span className="inline-flex items-center gap-1 whitespace-nowrap">
                      {col.label}
                      {col.sortable !== false && (
                        sortKey === col.key
                          ? sortDir === 'asc'
                            ? <ArrowUp className="w-3 h-3 shrink-0 text-blue-400" />
                            : <ArrowDown className="w-3 h-3 shrink-0 text-blue-400" />
                          : <ArrowUpDown className="w-3 h-3 shrink-0 opacity-30" />
                      )}
                    </span>
                  </th>
                );
              })}
            </tr>
          </thead>
          <tbody>
            {paged.length === 0 ? (
              <tr>
                <td colSpan={columns.length} className="px-4 py-8 text-center text-hint text-[11px]">
                  {query ? `"${query}"에 대한 검색 결과가 없습니다.` : '데이터가 없습니다.'}
                </td>
              </tr>
            ) : (
              paged.map((row, i) => (
                <tr
                  key={i}
                  onClick={() => onRowClick?.(row)}
                  className={`border-b border-border hover:bg-surface-overlay ${
                    onRowClick ? 'cursor-pointer' : ''
                  }`}
                >
                  {columns.map((col) => {
                    const cellStyle: React.CSSProperties = {};
                    if (col.width) cellStyle.minWidth = col.width;
                    if (col.minWidth) cellStyle.minWidth = col.minWidth;
                    if (col.maxWidth) cellStyle.maxWidth = col.maxWidth;
                    const rawValue = row[col.key];
                    const titleText = rawValue != null ? String(rawValue) : '';
                    return (
                      <td
                        key={col.key}
                        className={`px-4 py-2 whitespace-nowrap overflow-hidden text-ellipsis ${
                          col.align === 'center' ? 'text-center' : col.align === 'right' ? 'text-right' : 'text-left'
                        }`}
                        style={cellStyle}
                        title={titleText}
                      >
                        {col.render
                          ? col.render(rawValue, row, page * pageSize + i)
                          : <span className="text-label">{titleText}</span>
                        }
                      </td>
                    );
                  })}
                </tr>
              ))
            )}
          </tbody>
        </table>
      </div>

      {/* 페이지네이션 */}
      {showPagination && (
        <Pagination
          page={page}
          totalPages={totalPages}
          totalItems={sorted.length}
          pageSize={pageSize}
          onPageChange={setPage}
        />
      )}
    </div>
  );
}
