"use client";

import React from "react";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Checkbox } from "@/components/ui/checkbox";
import { ArrowUp, ArrowDown, ArrowUpDown } from "lucide-react";
import { cn } from "@/lib/utils";
import { ColumnConfig } from "./types";
import { useScreenMultiLang } from "@/contexts/ScreenMultiLangContext";

interface SingleTableWithStickyProps {
  visibleColumns?: ColumnConfig[];
  columns?: ColumnConfig[];
  data: Record<string, any>[];
  columnLabels: Record<string, string>;
  sortColumn: string | null;
  sortDirection: "asc" | "desc";
  tableConfig?: any;
  isDesignMode?: boolean;
  isAllSelected?: boolean;
  handleSort?: (columnName: string) => void;
  onSort?: (columnName: string) => void;
  handleSelectAll?: (checked: boolean) => void;
  handleRowClick?: (row: any, index: number, e: React.MouseEvent) => void;
  renderCheckboxCell?: (row: any, index: number) => React.ReactNode;
  renderCheckboxHeader?: () => React.ReactNode;
  formatCellValue: (value: any, format?: string, columnName?: string, rowData?: Record<string, any>) => React.ReactNode;
  getColumnWidth: (column: ColumnConfig) => number;
  containerWidth?: string; // 컨테이너 너비 설정
  loading?: boolean;
  error?: string | null;
  // 인라인 편집 관련 props
  onCellDoubleClick?: (rowIndex: number, colIndex: number, columnName: string, value: any) => void;
  editingCell?: { rowIndex: number; colIndex: number; columnName: string; originalValue: any } | null;
  editingValue?: string;
  onEditingValueChange?: (value: string) => void;
  onEditKeyDown?: (e: React.KeyboardEvent<HTMLInputElement>) => void;
  onEditSave?: () => void;
  editInputRef?: React.RefObject<HTMLInputElement | HTMLSelectElement>;
  // 인라인 편집 타입별 옵션 (select/category/code, number, date 지원)
  columnMeta?: Record<string, { inputType?: string }>;
  categoryMappings?: Record<string, Record<string, { label: string }>>;
  // 검색 하이라이트 관련 props
  searchHighlights?: Set<string>;
  currentSearchIndex?: number;
  searchTerm?: string;
}

export const SingleTableWithSticky: React.FC<SingleTableWithStickyProps> = ({
  visibleColumns,
  columns,
  data,
  columnLabels,
  sortColumn,
  sortDirection,
  tableConfig,
  isDesignMode = false,
  isAllSelected = false,
  handleSort,
  onSort,
  handleSelectAll,
  handleRowClick,
  renderCheckboxCell,
  renderCheckboxHeader,
  formatCellValue,
  getColumnWidth,
  containerWidth,
  loading = false,
  error = null,
  // 인라인 편집 관련 props
  onCellDoubleClick,
  editingCell,
  editingValue,
  onEditingValueChange,
  onEditKeyDown,
  onEditSave,
  editInputRef,
  columnMeta,
  categoryMappings,
  // 검색 하이라이트 관련 props
  searchHighlights,
  currentSearchIndex = 0,
  searchTerm = "",
}) => {
  const { getTranslatedText } = useScreenMultiLang();
  const checkboxConfig = tableConfig?.checkbox || {};
  const actualColumns = visibleColumns || columns || [];
  const sortHandler = onSort || handleSort || (() => {});
  const actualData = data || [];

  return (
    <div
      className="bg-background relative flex flex-1 flex-col overflow-hidden shadow-sm"
      style={{
        width: "100%",
        height: "100%",
        boxSizing: "border-box",
      }}
    >
      <div className="relative flex-1 overflow-auto" style={{ WebkitOverflowScrolling: "touch" }}>
        <Table
          noWrapper
          className="w-full"
          style={{
            width: "100%",
            tableLayout: "auto",
            boxSizing: "border-box",
            minWidth: `${Math.max(actualColumns.length * 80, 400)}px`,
          }}
        >
          <TableHeader
            className={cn("border-b border-border/60", tableConfig?.stickyHeader && "sticky top-0 z-30 shadow-sm")}
            style={{ backgroundColor: "hsl(var(--muted) / 0.4)" }}
          >
            <TableRow className="border-b border-border/60">
              {actualColumns.map((column, colIndex) => {
                // 왼쪽 고정 컬럼들의 누적 너비 계산
                const leftFixedWidth = actualColumns
                  .slice(0, colIndex)
                  .filter((col) => col.fixed === "left")
                  .reduce((sum, col) => sum + getColumnWidth(col), 0);

                // 오른쪽 고정 컬럼들의 누적 너비 계산
                const rightFixedColumns = actualColumns.filter((col) => col.fixed === "right");
                const rightFixedIndex = rightFixedColumns.findIndex((col) => col.columnName === column.columnName);
                const rightFixedWidth =
                  rightFixedIndex >= 0
                    ? rightFixedColumns.slice(rightFixedIndex + 1).reduce((sum, col) => sum + getColumnWidth(col), 0)
                    : 0;

                return (
                  <TableHead
                    key={column.columnName}
                    className={cn(
                      column.columnName === "__checkbox__"
                        ? "h-9 border-0 px-3 py-1.5 text-center align-middle sm:px-4 sm:py-2"
                        : "text-muted-foreground hover:text-foreground h-9 cursor-pointer border-0 px-3 py-1.5 text-left align-middle text-[10px] font-bold uppercase tracking-[0.04em] whitespace-nowrap transition-all duration-200 select-none sm:px-4 sm:py-2 sm:text-xs",
                      `text-${column.align}`,
                      column.sortable && "hover:bg-muted/50",
                      // 고정 컬럼 스타일
                      column.fixed === "left" && "border-border bg-background sticky z-40 border-r shadow-sm",
                      column.fixed === "right" && "border-border bg-background sticky z-40 border-l shadow-sm",
                      // 숨김 컬럼 스타일 (디자인 모드에서만)
                      isDesignMode && column.hidden && "bg-muted/50 opacity-40",
                    )}
                    style={{
                      width: column.columnName === "__checkbox__" ? 48 : getColumnWidth(column),
                      minWidth: column.columnName === "__checkbox__" ? "48px" : "100px",
                      maxWidth: column.columnName === "__checkbox__" ? "48px" : "300px",
                      boxSizing: "border-box",
                      overflow: "hidden",
                      textOverflow: "ellipsis",
                      whiteSpace: "nowrap",
                      backgroundColor: "hsl(var(--muted) / 0.4)",
                      ...(column.fixed === "left" && { left: leftFixedWidth }),
                      ...(column.fixed === "right" && { right: rightFixedWidth }),
                    }}
                    onClick={() => column.sortable && sortHandler(column.columnName)}
                  >
                    <div className={cn("flex items-center", column.columnName === "__checkbox__" ? "justify-center" : "gap-2")}>
                      {column.columnName === "__checkbox__" ? (
                        checkboxConfig.selectAll && (
                          <Checkbox
                            checked={isAllSelected}
                            onCheckedChange={handleSelectAll}
                            aria-label="전체 선택"
                            style={{
                              width: 16,
                              height: 16,
                              borderWidth: 1.5,
                              borderColor: isAllSelected ? "hsl(var(--primary))" : "hsl(var(--muted-foreground) / 0.5)",
                              zIndex: 1,
                            }}
                          />
                        )
                      ) : (
                        <>
                          <span className="flex-1 truncate">
                            {/* langKey가 있으면 다국어 번역 사용, 없으면 기존 라벨 */}
                            {(column as any).langKey
                              ? getTranslatedText(
                                  (column as any).langKey,
                                  columnLabels[column.columnName] || column.displayName || column.columnName,
                                )
                              : columnLabels[column.columnName] || column.displayName || column.columnName}
                          </span>
                          {column.sortable && sortColumn === column.columnName && (
                            <span className="bg-background/50 ml-1 flex h-4 w-4 items-center justify-center rounded-md shadow-sm sm:ml-2 sm:h-5 sm:w-5">
                              {sortDirection === "asc" ? (
                                <ArrowUp className="text-primary h-2.5 w-2.5 sm:h-3.5 sm:w-3.5" />
                              ) : (
                                <ArrowDown className="text-primary h-2.5 w-2.5 sm:h-3.5 sm:w-3.5" />
                              )}
                            </span>
                          )}
                        </>
                      )}
                    </div>
                  </TableHead>
                );
              })}
            </TableRow>
          </TableHeader>

          <TableBody>
            {actualData.length === 0 ? (
              <TableRow>
                <TableCell colSpan={actualColumns.length || 1} className="py-12 text-center">
                  <div className="flex flex-col items-center justify-center space-y-3">
                    <div className="bg-muted flex h-12 w-12 items-center justify-center rounded-full">
                      <svg
                        className="text-muted-foreground h-6 w-6"
                        fill="none"
                        stroke="currentColor"
                        viewBox="0 0 24 24"
                      >
                        <path
                          strokeLinecap="round"
                          strokeLinejoin="round"
                          strokeWidth={2}
                          d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
                        />
                      </svg>
                    </div>
                    <span className="text-muted-foreground text-sm font-medium">데이터가 없습니다</span>
                    <span className="bg-muted text-muted-foreground rounded-full px-3 py-1 text-xs">
                      조건을 변경하여 다시 검색해보세요
                    </span>
                  </div>
                </TableCell>
              </TableRow>
            ) : (
              actualData.map((row, index) => (
                <TableRow
                  key={`row-${index}`}
                  className={cn(
                    "cursor-pointer border-b border-border/50 transition-[background] duration-75",
                    index % 2 === 0 ? "bg-background" : "bg-muted/20",
                    tableConfig.tableStyle?.hoverEffect !== false && "hover:bg-accent",
                  )}
                  onClick={(e) => handleRowClick?.(row, index, e)}
                >
                  {actualColumns.map((column, colIndex) => {
                    // 왼쪽 고정 컬럼들의 누적 너비 계산
                    const leftFixedWidth = actualColumns
                      .slice(0, colIndex)
                      .filter((col) => col.fixed === "left")
                      .reduce((sum, col) => sum + getColumnWidth(col), 0);

                    // 오른쪽 고정 컬럼들의 누적 너비 계산
                    const rightFixedColumns = actualColumns.filter((col) => col.fixed === "right");
                    const rightFixedIndex = rightFixedColumns.findIndex((col) => col.columnName === column.columnName);
                    const rightFixedWidth =
                      rightFixedIndex >= 0
                        ? rightFixedColumns
                            .slice(rightFixedIndex + 1)
                            .reduce((sum, col) => sum + getColumnWidth(col), 0)
                        : 0;

                    // 현재 셀이 편집 중인지 확인
                    const isEditing = editingCell?.rowIndex === index && editingCell?.colIndex === colIndex;

                    // 검색 하이라이트 확인 - 실제 셀 값에 검색어가 포함되어 있는지도 확인
                    const cellKey = `${index}-${colIndex}`;
                    const cellValue = String(row[column.columnName] ?? "").toLowerCase();
                    const hasSearchTerm = searchTerm ? cellValue.includes(searchTerm.toLowerCase()) : false;

                    // 인덱스 기반 하이라이트 + 실제 값 검증
                    const isHighlighted =
                      column.columnName !== "__checkbox__" &&
                      hasSearchTerm &&
                      (searchHighlights?.has(cellKey) ?? false);

                    // 현재 검색 결과인지 확인 (currentSearchIndex가 -1이면 현재 페이지에 없음)
                    const highlightArray = searchHighlights ? Array.from(searchHighlights) : [];
                    const isCurrentSearchResult =
                      isHighlighted &&
                      currentSearchIndex >= 0 &&
                      currentSearchIndex < highlightArray.length &&
                      highlightArray[currentSearchIndex] === cellKey;

                    // formatCellValue 결과 (이미지 등 JSX 반환 가능)
                    const formattedValue = formatCellValue(row[column.columnName], column.format, column.columnName, row);
                    const rawCellValue = (formattedValue === null || formattedValue === undefined || formattedValue === "")
                      ? <span className="text-muted-foreground/50">-</span>
                      : formattedValue;
                    const isReactElement = typeof rawCellValue === "object" && React.isValidElement(rawCellValue);

                    // 셀 값에서 검색어 하이라이트 렌더링
                    const renderCellContent = () => {
                      // ReactNode(JSX)가 반환된 경우 (이미지 등) 그대로 렌더링
                      if (isReactElement) {
                        return rawCellValue;
                      }

                      if (!isHighlighted || !searchTerm || column.columnName === "__checkbox__") {
                        return rawCellValue;
                      }

                      // 검색어 하이라이트 처리 (문자열만)
                      const strValue = String(rawCellValue);
                      const lowerValue = strValue.toLowerCase();
                      const lowerTerm = searchTerm.toLowerCase();
                      const startIndex = lowerValue.indexOf(lowerTerm);

                      if (startIndex === -1) return rawCellValue;

                      const before = strValue.slice(0, startIndex);
                      const match = strValue.slice(startIndex, startIndex + searchTerm.length);
                      const after = strValue.slice(startIndex + searchTerm.length);

                      return (
                        <>
                          {before}
                          <mark
                            className={cn(
                              "rounded px-0.5",
                              isCurrentSearchResult
                                ? "bg-orange-400 font-semibold text-white"
                                : "bg-yellow-200 text-yellow-900",
                            )}
                          >
                            {match}
                          </mark>
                          {after}
                        </>
                      );
                    };

                    return (
                      <TableCell
                        key={`cell-${column.columnName}`}
                        id={isCurrentSearchResult ? "current-search-result" : undefined}
                        className={cn(
                          "text-foreground h-10 align-middle text-[11px] transition-colors",
                          column.columnName === "__checkbox__" ? "px-0 py-[7px] text-center" : "px-3 py-[7px]",
                          !isReactElement && "whitespace-nowrap",
                          column.columnName !== "__checkbox__" && `text-${column.align}`,
                          column.fixed === "left" &&
                            "border-border bg-background/90 sticky z-10 border-r backdrop-blur-sm",
                          column.fixed === "right" &&
                            "border-border bg-background/90 sticky z-10 border-l backdrop-blur-sm",
                          onCellDoubleClick && column.columnName !== "__checkbox__" && "cursor-text",
                        )}
                        style={{
                          width: column.columnName === "__checkbox__" ? 48 : getColumnWidth(column),
                          minWidth: column.columnName === "__checkbox__" ? "48px" : "100px",
                          maxWidth: column.columnName === "__checkbox__" ? "48px" : "300px",
                          boxSizing: "border-box",
                          ...(isReactElement ? {} : { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }),
                          ...(column.fixed === "left" && { left: leftFixedWidth }),
                          ...(column.fixed === "right" && { right: rightFixedWidth }),
                        }}
                        onDoubleClick={(e) => {
                          if (onCellDoubleClick && column.columnName !== "__checkbox__") {
                            e.stopPropagation();
                            onCellDoubleClick(index, colIndex, column.columnName, row[column.columnName]);
                          }
                        }}
                      >
                        {column.columnName === "__checkbox__" ? (
                          renderCheckboxCell?.(row, index)
                        ) : isEditing ? (
                          // 인라인 편집: inputType에 따라 select(category/code), number, date, text
                          (() => {
                            const meta = columnMeta?.[column.columnName];
                            const inputType = meta?.inputType ?? (column as { inputType?: string }).inputType;
                            const isNumeric = inputType === "number" || inputType === "decimal";
                            const isCategoryType = inputType === "category" || inputType === "code";
                            const categoryOptions = categoryMappings?.[column.columnName];
                            const hasCategoryOptions =
                              isCategoryType && categoryOptions && Object.keys(categoryOptions).length > 0;

                            // 인라인 편집: 행 높이 유지를 위해 select/input 모두 h-8(32px) 고정
                            const commonInputClass =
                              "border-primary bg-background focus:ring-primary h-8 w-full shrink-0 rounded border px-2 text-xs focus:ring-2 focus:outline-none sm:text-sm";
                            const handleBlurSave = () => {
                              if (onEditKeyDown) {
                                const fakeEvent = {
                                  key: "Enter",
                                  preventDefault: () => {},
                                } as React.KeyboardEvent<HTMLInputElement>;
                                onEditKeyDown(fakeEvent);
                              }
                              onEditSave?.();
                            };

                            // category/code 타입: select는 반드시 h-8(32px)로 행 높이 유지
                            if (hasCategoryOptions) {
                              const selectOptions = Object.entries(categoryOptions).map(([value, info]) => ({
                                value,
                                label: info.label,
                              }));
                              return (
                                <select
                                  ref={editInputRef as React.RefObject<HTMLSelectElement>}
                                  value={editingValue ?? ""}
                                  onChange={(e) => onEditingValueChange?.(e.target.value)}
                                  onKeyDown={onEditKeyDown}
                                  onBlur={handleBlurSave}
                                  className={cn(commonInputClass, "h-8")}
                                  onClick={(e) => e.stopPropagation()}
                                >
                                  <option value="">선택하세요</option>
                                  {selectOptions.map((opt) => (
                                    <option key={opt.value} value={opt.value}>
                                      {opt.label}
                                    </option>
                                  ))}
                                </select>
                              );
                            }

                            if (inputType === "date" || inputType === "datetime") {
                              try {
                                const { InlineCellDatePicker } = require("@/components/screen/filters/InlineCellDatePicker");
                                return (
                                  <InlineCellDatePicker
                                    value={editingValue ?? ""}
                                    onChange={(v) => onEditingValueChange?.(v)}
                                    onSave={() => {
                                      handleBlurSave();
                                    }}
                                    onKeyDown={onEditKeyDown}
                                    inputRef={editInputRef as React.RefObject<HTMLInputElement>}
                                  />
                                );
                              } catch {
                                return (
                                  <input
                                    ref={editInputRef as React.RefObject<HTMLInputElement>}
                                    type="text"
                                    value={editingValue ?? ""}
                                    onChange={(e) => onEditingValueChange?.(e.target.value)}
                                    onKeyDown={onEditKeyDown}
                                    onBlur={handleBlurSave}
                                    className={commonInputClass}
                                    onClick={(e) => e.stopPropagation()}
                                  />
                                );
                              }
                            }

                            return (
                              <input
                                ref={editInputRef as React.RefObject<HTMLInputElement>}
                                type={isNumeric ? "number" : "text"}
                                value={editingValue ?? ""}
                                onChange={(e) => onEditingValueChange?.(e.target.value)}
                                onKeyDown={onEditKeyDown}
                                onBlur={handleBlurSave}
                                className={commonInputClass}
                                style={isNumeric ? { textAlign: "right" } : undefined}
                                onClick={(e) => e.stopPropagation()}
                              />
                            );
                          })()
                        ) : (
                          renderCellContent()
                        )}
                      </TableCell>
                    );
                  })}
                </TableRow>
              ))
            )}
          </TableBody>
        </Table>
      </div>
    </div>
  );
};
