"use client";

import React, { useState, useEffect, useCallback, useMemo } from "react";
import { Button } from "@/components/ui/button";
import { Plus, Columns, AlignJustify } from "lucide-react";
import { cn } from "@/lib/utils";
import { apiClient } from "@/lib/api/client";

// 기존 ModalRepeaterTable 컴포넌트 재사용
import { RepeaterTable } from "../modal-repeater-table/RepeaterTable";
import { ItemSelectionModal } from "../modal-repeater-table/ItemSelectionModal";
import { RepeaterColumnConfig, CalculationRule, DynamicDataSourceOption } from "../modal-repeater-table/types";

// 타입 정의
import { 
  TableSectionConfig, 
  TableColumnConfig, 
  ValueMappingConfig,
  TableJoinCondition,
  FormDataState,
} from "./types";

interface TableSectionRendererProps {
  sectionId: string;
  tableConfig: TableSectionConfig;
  formData: FormDataState;
  onFormDataChange: (field: string, value: any) => void;
  onTableDataChange: (data: any[]) => void;
  className?: string;
}

/**
 * TableColumnConfig를 RepeaterColumnConfig로 변환
 * columnModes 또는 lookup이 있으면 dynamicDataSource로 변환
 */
function convertToRepeaterColumn(col: TableColumnConfig): RepeaterColumnConfig {
  const baseColumn: RepeaterColumnConfig = {
    field: col.field,
    label: col.label,
    type: col.type,
    editable: col.editable ?? true,
    calculated: col.calculated ?? false,
    width: col.width || "150px",
    required: col.required,
    defaultValue: col.defaultValue,
    selectOptions: col.selectOptions,
    // valueMapping은 별도로 처리
  };
  
  // lookup 설정을 dynamicDataSource로 변환 (새로운 조회 기능)
  if (col.lookup?.enabled && col.lookup.options && col.lookup.options.length > 0) {
    baseColumn.dynamicDataSource = {
      enabled: true,
      options: col.lookup.options.map((option) => ({
        id: option.id,
        // "컬럼명 - 옵션라벨" 형식으로 헤더에 표시
        label: option.displayLabel || option.label,
        // 헤더에 표시될 전체 라벨 (컬럼명 - 옵션라벨)
        headerLabel: `${col.label} - ${option.displayLabel || option.label}`,
        sourceType: "table" as const,
        tableConfig: {
          tableName: option.tableName,
          valueColumn: option.valueColumn,
          joinConditions: option.conditions.map((cond) => ({
            sourceField: cond.sourceField,
            targetField: cond.targetColumn,
            // sourceType에 따른 데이터 출처 설정
            sourceType: cond.sourceType,  // "currentRow" | "sectionField" | "externalTable"
            fromFormData: cond.sourceType === "sectionField",
            sectionId: cond.sectionId,
            // 외부 테이블 조회 설정 (sourceType이 "externalTable"인 경우)
            externalLookup: cond.externalLookup,
            // 값 변환 설정 전달 (레거시 호환)
            transform: cond.transform?.enabled ? {
              tableName: cond.transform.tableName,
              matchColumn: cond.transform.matchColumn,
              resultColumn: cond.transform.resultColumn,
            } : undefined,
          })),
        },
        // 조회 유형 정보 추가
        lookupType: option.type,
      })),
      defaultOptionId: col.lookup.options.find((o) => o.isDefault)?.id || col.lookup.options[0]?.id,
    };
  }
  // columnModes를 dynamicDataSource로 변환 (기존 로직 유지)
  else if (col.columnModes && col.columnModes.length > 0) {
    baseColumn.dynamicDataSource = {
      enabled: true,
      options: col.columnModes.map((mode) => ({
        id: mode.id,
        label: mode.label,
        sourceType: "table" as const,
        // 실제 조회 로직은 TableSectionRenderer에서 처리
        tableConfig: {
          tableName: mode.valueMapping?.externalRef?.tableName || "",
          valueColumn: mode.valueMapping?.externalRef?.valueColumn || "",
          joinConditions: (mode.valueMapping?.externalRef?.joinConditions || []).map((jc) => ({
            sourceField: jc.sourceField,
            targetField: jc.targetColumn,
          })),
        },
      })),
      defaultOptionId: col.columnModes.find((m) => m.isDefault)?.id || col.columnModes[0]?.id,
    };
  }
  
  return baseColumn;
}

/**
 * TableCalculationRule을 CalculationRule로 변환
 */
function convertToCalculationRule(calc: { resultField: string; formula: string; dependencies: string[] }): CalculationRule {
  return {
    result: calc.resultField,
    formula: calc.formula,
    dependencies: calc.dependencies,
  };
}

/**
 * 값 변환 함수: 중간 테이블을 통해 값을 변환
 * 예: 거래처 이름 "(무)테스트업체" → 거래처 코드 "CUST-0002"
 */
async function transformValue(
  value: any,
  transform: { tableName: string; matchColumn: string; resultColumn: string }
): Promise<any> {
  if (!value || !transform.tableName || !transform.matchColumn || !transform.resultColumn) {
    return value;
  }

  try {
    // 정확히 일치하는 검색
    const response = await apiClient.post(
      `/table-management/tables/${transform.tableName}/data`,
      { 
        search: { 
          [transform.matchColumn]: { 
            value: value, 
            operator: "equals" 
          } 
        }, 
        size: 1, 
        page: 1 
      }
    );

    if (response.data.success && response.data.data?.data?.length > 0) {
      const transformedValue = response.data.data.data[0][transform.resultColumn];
      return transformedValue;
    }

    console.warn(`변환 실패: ${transform.tableName}.${transform.matchColumn} = "${value}" 인 행을 찾을 수 없습니다.`);
    return undefined;
  } catch (error) {
    console.error("값 변환 오류:", error);
    return undefined;
  }
}

/**
 * 외부 테이블에서 조건 값을 조회하는 함수
 * LookupCondition.sourceType이 "externalTable"인 경우 사용
 */
async function fetchExternalLookupValue(
  externalLookup: {
    tableName: string;
    matchColumn: string;
    matchSourceType: "currentRow" | "sourceTable" | "sectionField";
    matchSourceField: string;
    matchSectionId?: string;
    resultColumn: string;
  },
  rowData: any,
  sourceData: any,
  formData: FormDataState
): Promise<any> {
  // 1. 비교 값 가져오기
  let matchValue: any;
  if (externalLookup.matchSourceType === "currentRow") {
    matchValue = rowData[externalLookup.matchSourceField];
  } else if (externalLookup.matchSourceType === "sourceTable") {
    matchValue = sourceData?.[externalLookup.matchSourceField];
  } else {
    matchValue = formData[externalLookup.matchSourceField];
  }

  if (matchValue === undefined || matchValue === null || matchValue === "") {
    console.warn(`외부 테이블 조회: 비교 값이 없습니다. (${externalLookup.matchSourceType}.${externalLookup.matchSourceField})`);
    return undefined;
  }

  // 2. 외부 테이블에서 값 조회 (정확히 일치하는 검색)
  try {
    const response = await apiClient.post(
      `/table-management/tables/${externalLookup.tableName}/data`,
      { 
        search: { 
          [externalLookup.matchColumn]: { 
            value: matchValue, 
            operator: "equals" 
          } 
        }, 
        size: 1, 
        page: 1 
      }
    );

    if (response.data.success && response.data.data?.data?.length > 0) {
      return response.data.data.data[0][externalLookup.resultColumn];
    }

    console.warn(`외부 테이블 조회: ${externalLookup.tableName}.${externalLookup.matchColumn} = "${matchValue}" 인 행을 찾을 수 없습니다.`);
    return undefined;
  } catch (error) {
    console.error("외부 테이블 조회 오류:", error);
    return undefined;
  }
}

/**
 * 외부 테이블에서 값을 조회하는 함수
 * 
 * @param tableName - 조회할 테이블명
 * @param valueColumn - 가져올 컬럼명
 * @param joinConditions - 조인 조건 목록
 * @param rowData - 현재 행 데이터 (설정된 컬럼 필드)
 * @param sourceData - 원본 소스 데이터 (_sourceData)
 * @param formData - 폼 데이터 (다른 섹션 필드)
 */
async function fetchExternalValue(
  tableName: string,
  valueColumn: string,
  joinConditions: TableJoinCondition[],
  rowData: any,
  sourceData: any,
  formData: FormDataState
): Promise<any> {
  if (joinConditions.length === 0) {
    return undefined;
  }

  try {
    const whereConditions: Record<string, any> = {};

    for (const condition of joinConditions) {
      let value: any;

      // 값 출처에 따라 가져오기 (4가지 소스 타입 지원)
      if (condition.sourceType === "row") {
        // 현재 행 데이터 (설정된 컬럼 필드)
        value = rowData[condition.sourceField];
      } else if (condition.sourceType === "sourceData") {
        // 원본 소스 테이블 데이터 (_sourceData)
        value = sourceData?.[condition.sourceField];
      } else if (condition.sourceType === "formData") {
        // formData에서 가져오기 (다른 섹션)
        value = formData[condition.sourceField];
      } else if (condition.sourceType === "externalTable" && condition.externalLookup) {
        // 외부 테이블에서 조회하여 가져오기
        value = await fetchExternalLookupValue(condition.externalLookup, rowData, sourceData, formData);
      }

      if (value === undefined || value === null || value === "") {
        return undefined;
      }

      // 값 변환이 필요한 경우 (예: 이름 → 코드) - 레거시 호환
      if (condition.transform) {
        value = await transformValue(value, condition.transform);
        if (value === undefined) {
          return undefined;
        }
      }

      // 숫자형 ID 변환
      let convertedValue = value;
      if (condition.targetColumn.endsWith("_id") || condition.targetColumn === "id") {
        const numValue = Number(value);
        if (!isNaN(numValue)) {
          convertedValue = numValue;
        }
      }

      // 정확히 일치하는 검색을 위해 operator: "equals" 사용
      whereConditions[condition.targetColumn] = {
        value: convertedValue,
        operator: "equals"
      };
    }

    // API 호출
    const response = await apiClient.post(
      `/table-management/tables/${tableName}/data`,
      { search: whereConditions, size: 1, page: 1 }
    );

    if (response.data.success && response.data.data?.data?.length > 0) {
      return response.data.data.data[0][valueColumn];
    }

    return undefined;
  } catch (error) {
    console.error("외부 테이블 조회 오류:", error);
    return undefined;
  }
}

/**
 * 테이블 섹션 렌더러
 * UniversalFormModal 내에서 테이블 형식의 데이터를 표시하고 편집
 */
export function TableSectionRenderer({
  sectionId,
  tableConfig,
  formData,
  onFormDataChange,
  onTableDataChange,
  className,
}: TableSectionRendererProps) {
  // 테이블 데이터 상태
  const [tableData, setTableData] = useState<any[]>([]);
  
  // 모달 상태
  const [modalOpen, setModalOpen] = useState(false);
  
  // 체크박스 선택 상태
  const [selectedRows, setSelectedRows] = useState<Set<number>>(new Set());
  
  // 너비 조정 트리거 (홀수: 자동맞춤, 짝수: 균등분배)
  const [widthTrigger, setWidthTrigger] = useState(0);
  
  // 동적 데이터 소스 활성화 상태
  const [activeDataSources, setActiveDataSources] = useState<Record<string, string>>({});
  
  // 날짜 일괄 적용 완료 플래그 (컬럼별로 한 번만 적용)
  const [batchAppliedFields, setBatchAppliedFields] = useState<Set<string>>(new Set());

  // 초기 데이터 로드 완료 플래그 (무한 루프 방지)
  const initialDataLoadedRef = React.useRef(false);

  // formData에서 초기 테이블 데이터 로드 (수정 모드에서 _groupedData 표시)
  useEffect(() => {
    // 이미 초기화되었으면 스킵
    if (initialDataLoadedRef.current) return;

    const tableSectionKey = `_tableSection_${sectionId}`;
    const initialData = formData[tableSectionKey];

    if (Array.isArray(initialData) && initialData.length > 0) {
      console.log("[TableSectionRenderer] 초기 데이터 로드:", {
        sectionId,
        itemCount: initialData.length,
      });
      setTableData(initialData);
      initialDataLoadedRef.current = true;
    }
  }, [sectionId, formData]);

  // RepeaterColumnConfig로 변환
  const columns: RepeaterColumnConfig[] = (tableConfig.columns || []).map(convertToRepeaterColumn);

  // 계산 규칙 변환
  const calculationRules: CalculationRule[] = (tableConfig.calculations || []).map(convertToCalculationRule);

  // 계산 로직
  const calculateRow = useCallback(
    (row: any): any => {
      if (calculationRules.length === 0) return row;

      const updatedRow = { ...row };

      for (const rule of calculationRules) {
        try {
          let formula = rule.formula;
          const fieldMatches = formula.match(/[a-zA-Z_][a-zA-Z0-9_]*/g) || [];
          const dependencies = rule.dependencies.length > 0 ? rule.dependencies : fieldMatches;

          for (const dep of dependencies) {
            if (dep === rule.result) continue;
            const value = parseFloat(row[dep]) || 0;
            formula = formula.replace(new RegExp(`\\b${dep}\\b`, "g"), value.toString());
          }

          const result = new Function(`return ${formula}`)();
          updatedRow[rule.result] = result;
        } catch (error) {
          console.error(`계산 오류 (${rule.formula}):`, error);
          updatedRow[rule.result] = 0;
        }
      }

      return updatedRow;
    },
    [calculationRules]
  );

  const calculateAll = useCallback(
    (data: any[]): any[] => {
      return data.map((row) => calculateRow(row));
    },
    [calculateRow]
  );

  // 데이터 변경 핸들러 (날짜 일괄 적용 로직 포함)
  const handleDataChange = useCallback(
    (newData: any[]) => {
      let processedData = newData;
      
      // 날짜 일괄 적용 로직: batchApply가 활성화된 날짜 컬럼 처리
      const batchApplyColumns = tableConfig.columns.filter(
        (col) => col.type === "date" && col.batchApply === true
      );
      
      for (const dateCol of batchApplyColumns) {
        // 이미 일괄 적용된 컬럼은 건너뜀
        if (batchAppliedFields.has(dateCol.field)) continue;
        
        // 해당 컬럼에 값이 있는 행과 없는 행 분류
        const itemsWithDate = processedData.filter((item) => item[dateCol.field]);
        const itemsWithoutDate = processedData.filter((item) => !item[dateCol.field]);
        
        // 조건: 정확히 1개만 날짜가 있고, 나머지는 모두 비어있을 때
        if (itemsWithDate.length === 1 && itemsWithoutDate.length > 0) {
          const selectedDate = itemsWithDate[0][dateCol.field];
          
          // 모든 행에 동일한 날짜 적용
          processedData = processedData.map((item) => ({
            ...item,
            [dateCol.field]: selectedDate,
          }));
          
          // 플래그 활성화 (이후 개별 수정 가능)
          setBatchAppliedFields((prev) => new Set([...prev, dateCol.field]));
        }
      }
      
      setTableData(processedData);
      onTableDataChange(processedData);
    },
    [onTableDataChange, tableConfig.columns, batchAppliedFields]
  );

  // 행 변경 핸들러
  const handleRowChange = useCallback(
    (index: number, newRow: any) => {
      const calculatedRow = calculateRow(newRow);
      const newData = [...tableData];
      newData[index] = calculatedRow;
      handleDataChange(newData);
    },
    [tableData, calculateRow, handleDataChange]
  );

  // 행 삭제 핸들러
  const handleRowDelete = useCallback(
    (index: number) => {
      const newData = tableData.filter((_, i) => i !== index);
      handleDataChange(newData);
    },
    [tableData, handleDataChange]
  );

  // 선택된 항목 일괄 삭제
  const handleBulkDelete = useCallback(() => {
    if (selectedRows.size === 0) return;
    const newData = tableData.filter((_, index) => !selectedRows.has(index));
    handleDataChange(newData);
    setSelectedRows(new Set());
    
    // 데이터가 모두 삭제되면 일괄 적용 플래그도 리셋
    if (newData.length === 0) {
      setBatchAppliedFields(new Set());
    }
  }, [tableData, selectedRows, handleDataChange]);

  // 아이템 추가 핸들러 (모달에서 선택)
  const handleAddItems = useCallback(
    async (items: any[]) => {
      // 각 아이템에 대해 valueMapping 적용
      const mappedItems = await Promise.all(
        items.map(async (sourceItem) => {
          const newItem: any = {};

          for (const col of tableConfig.columns) {
            const mapping = col.valueMapping;

            // 0. lookup 설정이 있는 경우 (동적 조회)
            if (col.lookup?.enabled && col.lookup.options && col.lookup.options.length > 0) {
              // 현재 활성화된 옵션 또는 기본 옵션 사용
              const activeOptionId = activeDataSources[col.field];
              const defaultOption = col.lookup.options.find((o) => o.isDefault) || col.lookup.options[0];
              const selectedOption = activeOptionId 
                ? col.lookup.options.find((o) => o.id === activeOptionId) || defaultOption
                : defaultOption;

              if (selectedOption) {
                // sameTable 타입: 소스 데이터에서 직접 값 복사
                if (selectedOption.type === "sameTable") {
                  const value = sourceItem[selectedOption.valueColumn];
                  if (value !== undefined) {
                    newItem[col.field] = value;
                  }
                  // _sourceData에 원본 저장 (나중에 다른 옵션으로 전환 시 사용)
                  newItem._sourceData = sourceItem;
                  continue;
                }

                // relatedTable, combinedLookup: 외부 테이블 조회
                // 조인 조건 구성 (4가지 소스 타입 지원)
                const joinConditions: TableJoinCondition[] = selectedOption.conditions.map((cond) => {
                  // sourceType 매핑
                  let sourceType: "row" | "sourceData" | "formData" | "externalTable";
                  if (cond.sourceType === "currentRow") {
                    sourceType = "row";
                  } else if (cond.sourceType === "sourceTable") {
                    sourceType = "sourceData";
                  } else if (cond.sourceType === "externalTable") {
                    sourceType = "externalTable";
                  } else {
                    sourceType = "formData";
                  }

                  return {
                    sourceType,
                    sourceField: cond.sourceField,
                    targetColumn: cond.targetColumn,
                    // 외부 테이블 조회 설정
                    externalLookup: cond.externalLookup,
                    // 값 변환 설정 전달 (레거시 호환)
                    transform: cond.transform?.enabled ? {
                      tableName: cond.transform.tableName,
                      matchColumn: cond.transform.matchColumn,
                      resultColumn: cond.transform.resultColumn,
                    } : undefined,
                  };
                });

                // 외부 테이블에서 값 조회 (sourceItem이 _sourceData 역할)
                const value = await fetchExternalValue(
                  selectedOption.tableName,
                  selectedOption.valueColumn,
                  joinConditions,
                  { ...sourceItem, ...newItem },  // rowData (현재 행)
                  sourceItem,                      // sourceData (소스 테이블 원본)
                  formData
                );
                
                if (value !== undefined) {
                  newItem[col.field] = value;
                }
                
                // _sourceData에 원본 저장
                newItem._sourceData = sourceItem;
              }
              continue;
            }

            // 1. 먼저 col.sourceField 확인 (간단 매핑)
            if (!mapping && col.sourceField) {
              // sourceField가 명시적으로 설정된 경우
              if (sourceItem[col.sourceField] !== undefined) {
                newItem[col.field] = sourceItem[col.sourceField];
              }
              continue;
            }

            if (!mapping) {
              // 매핑 없으면 소스에서 동일 필드명으로 복사
              if (sourceItem[col.field] !== undefined) {
                newItem[col.field] = sourceItem[col.field];
              }
              continue;
            }

            // 2. valueMapping이 있는 경우 (고급 매핑)
            switch (mapping.type) {
              case "source":
                // 소스 테이블에서 복사
                const srcField = mapping.sourceField || col.sourceField || col.field;
                if (sourceItem[srcField] !== undefined) {
                  newItem[col.field] = sourceItem[srcField];
                }
                break;

              case "manual":
                // 사용자 입력 (빈 값 또는 기본값)
                newItem[col.field] = col.defaultValue ?? undefined;
                break;

              case "internal":
                // formData에서 값 가져오기
                if (mapping.internalField) {
                  newItem[col.field] = formData[mapping.internalField];
                }
                break;

              case "external":
                // 외부 테이블에서 조회
                if (mapping.externalRef) {
                  const { tableName, valueColumn, joinConditions } = mapping.externalRef;
                  const value = await fetchExternalValue(
                    tableName,
                    valueColumn,
                    joinConditions,
                    { ...sourceItem, ...newItem }, // rowData
                    sourceItem,                      // sourceData
                    formData
                  );
                  if (value !== undefined) {
                    newItem[col.field] = value;
                  }
                }
                break;
            }

            // 기본값 적용
            if (col.defaultValue !== undefined && newItem[col.field] === undefined) {
              newItem[col.field] = col.defaultValue;
            }
          }

          return newItem;
        })
      );

      // 계산 필드 업데이트
      const calculatedItems = calculateAll(mappedItems);

      // 기존 데이터에 추가
      const newData = [...tableData, ...calculatedItems];
      handleDataChange(newData);
    },
    [tableConfig.columns, formData, tableData, calculateAll, handleDataChange, activeDataSources]
  );

  // 컬럼 모드/조회 옵션 변경 핸들러
  const handleDataSourceChange = useCallback(
    async (columnField: string, optionId: string) => {
      setActiveDataSources((prev) => ({
        ...prev,
        [columnField]: optionId,
      }));

      // 해당 컬럼의 모든 행 데이터 재조회
      const column = tableConfig.columns.find((col) => col.field === columnField);
      
      // lookup 설정이 있는 경우 (새로운 조회 기능)
      if (column?.lookup?.enabled && column.lookup.options) {
        const selectedOption = column.lookup.options.find((opt) => opt.id === optionId);
        if (!selectedOption) return;

        // sameTable 타입: 현재 행의 소스 데이터에서 값 복사 (외부 조회 필요 없음)
        if (selectedOption.type === "sameTable") {
          const updatedData = tableData.map((row) => {
            // sourceField에서 값을 가져와 해당 컬럼에 복사
            // row에 _sourceData가 있으면 거기서, 없으면 row 자체에서 가져옴
            const sourceData = row._sourceData || row;
            const newValue = sourceData[selectedOption.valueColumn] ?? row[columnField];
            return { ...row, [columnField]: newValue };
          });

          const calculatedData = calculateAll(updatedData);
          handleDataChange(calculatedData);
          return;
        }

        // 모든 행에 대해 새 값 조회
        const updatedData = await Promise.all(
          tableData.map(async (row) => {
            let newValue: any = row[columnField];

            // 조인 조건 구성 (4가지 소스 타입 지원)
            const joinConditions: TableJoinCondition[] = selectedOption.conditions.map((cond) => {
              // sourceType 매핑
              let sourceType: "row" | "sourceData" | "formData" | "externalTable";
              if (cond.sourceType === "currentRow") {
                sourceType = "row";
              } else if (cond.sourceType === "sourceTable") {
                sourceType = "sourceData";
              } else if (cond.sourceType === "externalTable") {
                sourceType = "externalTable";
              } else {
                sourceType = "formData";
              }

              return {
                sourceType,
                sourceField: cond.sourceField,
                targetColumn: cond.targetColumn,
                // 외부 테이블 조회 설정
                externalLookup: cond.externalLookup,
                // 값 변환 설정 전달 (레거시 호환)
                transform: cond.transform?.enabled ? {
                  tableName: cond.transform.tableName,
                  matchColumn: cond.transform.matchColumn,
                  resultColumn: cond.transform.resultColumn,
                } : undefined,
              };
            });

            // 외부 테이블에서 값 조회 (_sourceData 전달)
            const sourceData = row._sourceData || row;
            const value = await fetchExternalValue(
              selectedOption.tableName,
              selectedOption.valueColumn,
              joinConditions,
              row,
              sourceData,
              formData
            );
            
            if (value !== undefined) {
              newValue = value;
            }

            return { ...row, [columnField]: newValue };
          })
        );

        // 계산 필드 업데이트
        const calculatedData = calculateAll(updatedData);
        handleDataChange(calculatedData);
        return;
      }

      // 기존 columnModes 처리 (레거시 호환)
      if (!column?.columnModes) return;

      const selectedMode = column.columnModes.find((mode) => mode.id === optionId);
      if (!selectedMode) return;

      // 모든 행에 대해 새 값 조회
      const updatedData = await Promise.all(
        tableData.map(async (row) => {
          const mapping = selectedMode.valueMapping;
          let newValue: any = row[columnField];
          const sourceData = row._sourceData || row;

          if (mapping.type === "external" && mapping.externalRef) {
            const { tableName, valueColumn, joinConditions } = mapping.externalRef;
            const value = await fetchExternalValue(tableName, valueColumn, joinConditions, row, sourceData, formData);
            if (value !== undefined) {
              newValue = value;
            }
          } else if (mapping.type === "source" && mapping.sourceField) {
            newValue = row[mapping.sourceField];
          } else if (mapping.type === "internal" && mapping.internalField) {
            newValue = formData[mapping.internalField];
          }

          return { ...row, [columnField]: newValue };
        })
      );

      // 계산 필드 업데이트
      const calculatedData = calculateAll(updatedData);
      handleDataChange(calculatedData);
    },
    [tableConfig.columns, tableData, formData, calculateAll, handleDataChange]
  );

  // 소스 테이블 정보
  const { source, filters, uiConfig } = tableConfig;
  const sourceTable = source.tableName;
  const sourceColumns = source.displayColumns;
  const sourceSearchFields = source.searchColumns;
  const columnLabels = source.columnLabels || {};
  const modalTitle = uiConfig?.modalTitle || "항목 검색 및 선택";
  const addButtonText = uiConfig?.addButtonText || "항목 검색";
  const multiSelect = uiConfig?.multiSelect ?? true;

  // 기본 필터 조건 생성 (사전 필터만 - 모달 필터는 ItemSelectionModal에서 처리)
  const baseFilterCondition: Record<string, any> = {};
  if (filters?.preFilters) {
    for (const filter of filters.preFilters) {
      // 간단한 "=" 연산자만 처리 (확장 가능)
      if (filter.operator === "=") {
        baseFilterCondition[filter.column] = filter.value;
      }
    }
  }
  
  // 모달 필터 설정을 ItemSelectionModal에 전달할 형식으로 변환
  const modalFiltersForModal = useMemo(() => {
    if (!filters?.modalFilters) return [];
    return filters.modalFilters.map((filter) => ({
      column: filter.column,
      label: filter.label || filter.column,
      // category 타입을 select로 변환 (ModalFilterConfig 호환)
      type: filter.type === "category" ? "select" as const : filter.type as "text" | "select",
      options: filter.options,
      categoryRef: filter.categoryRef,
      defaultValue: filter.defaultValue,
    }));
  }, [filters?.modalFilters]);

  return (
    <div className={cn("space-y-4", className)}>
      {/* 추가 버튼 영역 */}
      <div className="flex justify-between items-center">
        <div className="flex items-center gap-2">
          <span className="text-sm text-muted-foreground">
            {tableData.length > 0 && `${tableData.length}개 항목`}
            {selectedRows.size > 0 && ` (${selectedRows.size}개 선택됨)`}
          </span>
          {columns.length > 0 && (
            <Button
              variant="outline"
              size="sm"
              onClick={() => setWidthTrigger((prev) => prev + 1)}
              className="h-7 text-xs px-2"
              title={widthTrigger % 2 === 0 ? "내용에 맞게 자동 조정" : "균등 분배"}
            >
              {widthTrigger % 2 === 0 ? (
                <>
                  <AlignJustify className="h-3.5 w-3.5 mr-1" />
                  자동 맞춤
                </>
              ) : (
                <>
                  <Columns className="h-3.5 w-3.5 mr-1" />
                  균등 분배
                </>
              )}
            </Button>
          )}
        </div>
        <div className="flex gap-2">
          {selectedRows.size > 0 && (
            <Button
              variant="destructive"
              onClick={handleBulkDelete}
              className="h-8 text-xs sm:h-10 sm:text-sm"
            >
              선택 삭제 ({selectedRows.size})
            </Button>
          )}
          <Button
            onClick={() => setModalOpen(true)}
            className="h-8 text-xs sm:h-10 sm:text-sm"
          >
            <Plus className="h-4 w-4 mr-2" />
            {addButtonText}
          </Button>
        </div>
      </div>

      {/* Repeater 테이블 */}
      <RepeaterTable
        columns={columns}
        data={tableData}
        onDataChange={handleDataChange}
        onRowChange={handleRowChange}
        onRowDelete={handleRowDelete}
        activeDataSources={activeDataSources}
        onDataSourceChange={handleDataSourceChange}
        selectedRows={selectedRows}
        onSelectionChange={setSelectedRows}
        equalizeWidthsTrigger={widthTrigger}
      />

      {/* 항목 선택 모달 */}
      <ItemSelectionModal
        open={modalOpen}
        onOpenChange={setModalOpen}
        sourceTable={sourceTable}
        sourceColumns={sourceColumns}
        sourceSearchFields={sourceSearchFields}
        multiSelect={multiSelect}
        filterCondition={baseFilterCondition}
        modalTitle={modalTitle}
        alreadySelected={tableData}
        uniqueField={tableConfig.saveConfig?.uniqueField}
        onSelect={handleAddItems}
        columnLabels={columnLabels}
        modalFilters={modalFiltersForModal}
      />
    </div>
  );
}
