"use client";

import * as React from "react";
import dynamic from "next/dynamic";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogDescription } from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { GenericData } from "./export-excel-form";
import * as GC from "@mescius/spread-sheets";
import { toast } from "sonner";
import { updateFormDataInDB } from "@/lib/forms/services";
import { Loader, Save, AlertTriangle } from "lucide-react";
import '@mescius/spread-sheets/styles/gc.spread.sheets.excel2016colorful.css';
import { DataTableColumnJSON, ColumnType } from "./form-data-table-columns";

// SpreadSheets를 동적으로 import (SSR 비활성화)
const SpreadSheets = dynamic(
  () => import("@mescius/spread-sheets-react").then(mod => mod.SpreadSheets),
  { 
    ssr: false,
    loading: () => (
      <div className="flex items-center justify-center h-full">
        <Loader className="mr-2 h-4 w-4 animate-spin" />
        Loading SpreadSheets...
      </div>
    )
  }
);

// 라이센스 키 설정을 클라이언트에서만 실행
if (typeof window !== 'undefined' && process.env.NEXT_PUBLIC_SPREAD_LICENSE) {
  GC.Spread.Sheets.LicenseKey = process.env.NEXT_PUBLIC_SPREAD_LICENSE;
}

interface TemplateItem {
  TMPL_ID: string;
  NAME: string;
  TMPL_TYPE: string;
  SPR_LST_SETUP: {
    ACT_SHEET: string;
    HIDN_SHEETS: Array<string>;
    CONTENT?: string;
    DATA_SHEETS: Array<{
      SHEET_NAME: string;
      REG_TYPE_ID: string;
      MAP_CELL_ATT: Array<{
        ATT_ID: string;
        IN: string;
      }>;
    }>;
  };
  GRD_LST_SETUP: {
    REG_TYPE_ID: string;
    SPR_ITM_IDS: Array<string>;
    ATTS: Array<{}>;
  };
  SPR_ITM_LST_SETUP: {
    ACT_SHEET: string;
    HIDN_SHEETS: Array<string>;
    CONTENT?: string;
    DATA_SHEETS: Array<{
      SHEET_NAME: string;
      REG_TYPE_ID: string;
      MAP_CELL_ATT: Array<{
        ATT_ID: string;
        IN: string;
      }>;
    }>;
  };
}

interface ValidationError {
  cellAddress: string;
  attId: string;
  value: any;
  expectedType: ColumnType;
  message: string;
}

interface TemplateViewDialogProps {
  isOpen: boolean;
  onClose: () => void;
  templateData: TemplateItem[] | any;
  selectedRow?: GenericData; // SPREAD_ITEM용
  tableData?: GenericData[]; // SPREAD_LIST용
  formCode: string;
  columnsJSON: DataTableColumnJSON[]
  contractItemId: number;
  editableFieldsMap?: Map<string, string[]>;
  onUpdateSuccess?: (updatedValues: Record<string, any> | GenericData[]) => void;
}

export function TemplateViewDialog({
  isOpen,
  onClose,
  templateData,
  selectedRow,
  tableData = [],
  formCode,
  contractItemId,
  columnsJSON,
  editableFieldsMap = new Map(),
  onUpdateSuccess
}: TemplateViewDialogProps) {
  const [hostStyle, setHostStyle] = React.useState({
    width: '100%',
    height: '100%'
  });

  const [isPending, setIsPending] = React.useState(false);
  const [hasChanges, setHasChanges] = React.useState(false);
  const [currentSpread, setCurrentSpread] = React.useState<any>(null);
  const [cellMappings, setCellMappings] = React.useState<Array<{attId: string, cellAddress: string, isEditable: boolean}>>([]);
  const [isClient, setIsClient] = React.useState(false);
  const [templateType, setTemplateType] = React.useState<'SPREAD_LIST' | 'SPREAD_ITEM' | null>(null);
  const [validationErrors, setValidationErrors] = React.useState<ValidationError[]>([]);
  const [selectedTemplateId, setSelectedTemplateId] = React.useState<string>("");
  const [availableTemplates, setAvailableTemplates] = React.useState<TemplateItem[]>([]);

  // 클라이언트 사이드에서만 렌더링되도록 보장
  React.useEffect(() => {
    setIsClient(true);
  }, []);

  // 사용 가능한 템플릿들을 필터링하고 설정
  React.useEffect(() => {
    if (!templateData) return;
    
    let templates: TemplateItem[];
    if (Array.isArray(templateData)) {
      templates = templateData as TemplateItem[];
    } else {
      templates = [templateData as TemplateItem];
    }
    
    // CONTENT가 있는 템플릿들 필터링
    const validTemplates = templates.filter(template => {
      const hasSpreadListContent = template.SPR_LST_SETUP?.CONTENT;
      const hasSpreadItemContent = template.SPR_ITM_LST_SETUP?.CONTENT;
      const isValidType = template.TMPL_TYPE === "SPREAD_LIST" || template.TMPL_TYPE === "SPREAD_ITEM";
      
      return isValidType && (hasSpreadListContent || hasSpreadItemContent);
    });
    
    setAvailableTemplates(validTemplates);
    
    // 첫 번째 유효한 템플릿을 기본으로 선택
    if (validTemplates.length > 0 && !selectedTemplateId) {
      setSelectedTemplateId(validTemplates[0].TMPL_ID);
      setTemplateType(validTemplates[0].TMPL_TYPE as 'SPREAD_LIST' | 'SPREAD_ITEM');
    }
  }, [templateData, selectedTemplateId]);

  // 선택된 템플릿 변경 처리
  const handleTemplateChange = (templateId: string) => {
    const template = availableTemplates.find(t => t.TMPL_ID === templateId);
    if (template) {
      setSelectedTemplateId(templateId);
      setTemplateType(template.TMPL_TYPE as 'SPREAD_LIST' | 'SPREAD_ITEM');
      setHasChanges(false);
      setValidationErrors([]);
      
      // SpreadSheets 재초기화
      if (currentSpread) {
        const template = availableTemplates.find(t => t.TMPL_ID === templateId);
        if (template) {
          initSpread(currentSpread, template);
        }
      }
    }
  };

  // 현재 선택된 템플릿 가져오기
  const selectedTemplate = React.useMemo(() => {
    return availableTemplates.find(t => t.TMPL_ID === selectedTemplateId);
  }, [availableTemplates, selectedTemplateId]);

  const editableFields = React.useMemo(() => {
    if (!selectedRow?.TAG_NO || !editableFieldsMap.has(selectedRow.TAG_NO)) {
      return [];
    }
    return editableFieldsMap.get(selectedRow.TAG_NO) || [];
  }, [selectedRow?.TAG_NO, editableFieldsMap]);

  // 필드가 편집 가능한지 판별하는 함수
  const isFieldEditable = React.useCallback((attId: string, rowData?: GenericData) => {
    // columnsJSON에서 해당 attId의 shi 값 확인
    const columnConfig = columnsJSON.find(col => col.key === attId);
    if (columnConfig?.shi === true) {
      return false; // columnsJSON에서 shi가 true이면 편집 불가
    }
    
    // TAG_NO와 TAG_DESC는 기본적으로 편집 가능 (columnsJSON의 shi가 false인 경우)
    if (attId === "TAG_NO" || attId === "TAG_DESC") {
      return true;
    }
    
    // SPREAD_LIST인 경우는 기본적으로 편집 가능 (개별 행의 shi 상태는 저장시 확인)
    return true;
  }, [templateType, selectedRow, columnsJSON, editableFieldsMap]);

  // 편집 가능한 필드 개수 계산
  const editableFieldsCount = React.useMemo(() => {
    return cellMappings.filter(m => m.isEditable).length;
  }, [cellMappings]);

  // 셀 주소를 행과 열로 변환하는 함수
  const parseCellAddress = (address: string): {row: number, col: number} | null => {
    if (!address || address.trim() === "") return null;
    
    const match = address.match(/^([A-Z]+)(\d+)$/);
    if (!match) return null;
    
    const [, colStr, rowStr] = match;
    
    let col = 0;
    for (let i = 0; i < colStr.length; i++) {
      col = col * 26 + (colStr.charCodeAt(i) - 65 + 1);
    }
    col -= 1;
    
    const row = parseInt(rowStr) - 1;
    
    return { row, col };
  };

  // 데이터 타입 검증 함수
  const validateCellValue = (value: any, columnType: ColumnType, options?: string[]): string | null => {
    if (value === undefined || value === null || value === "") {
      return null; // 빈 값은 별도 required 검증에서 처리
    }

    switch (columnType) {
      case "NUMBER":
        if (isNaN(Number(value))) {
          return "Value must be a valid number";
        }
        break;
      case "LIST":
        if (options && !options.includes(String(value))) {
          return `Value must be one of: ${options.join(", ")}`;
        }
        break;
      case "STRING":
        // STRING 타입은 대부분의 값을 허용
        break;
      default:
        // 커스텀 타입의 경우 추가 검증 로직이 필요할 수 있음
        break;
    }
    
    return null;
  };

  // 전체 데이터 검증 함수
  const validateAllData = React.useCallback(() => {
    if (!currentSpread || !selectedTemplate) return [];

    const activeSheet = currentSpread.getActiveSheet();
    const errors: ValidationError[] = [];

    cellMappings.forEach(mapping => {
      const columnConfig = columnsJSON.find(col => col.key === mapping.attId);
      if (!columnConfig) return;

      const cellPos = parseCellAddress(mapping.cellAddress);
      if (!cellPos) return;

      if (templateType === 'SPREAD_ITEM') {
        // 단일 행 검증
        const cellValue = activeSheet.getValue(cellPos.row, cellPos.col);
        const errorMessage = validateCellValue(cellValue, columnConfig.type, columnConfig.options);
        
        if (errorMessage) {
          errors.push({
            cellAddress: mapping.cellAddress,
            attId: mapping.attId,
            value: cellValue,
            expectedType: columnConfig.type,
            message: errorMessage
          });
        }
      } else if (templateType === 'SPREAD_LIST') {
        // 복수 행 검증
        for (let i = 0; i < tableData.length; i++) {
          const targetRow = cellPos.row + i;
          const cellValue = activeSheet.getValue(targetRow, cellPos.col);
          const errorMessage = validateCellValue(cellValue, columnConfig.type, columnConfig.options);
          
          if (errorMessage) {
            errors.push({
              cellAddress: `${String.fromCharCode(65 + cellPos.col)}${targetRow + 1}`,
              attId: mapping.attId,
              value: cellValue,
              expectedType: columnConfig.type,
              message: errorMessage
            });
          }
        }
      }
    });

    setValidationErrors(errors);
    return errors;
  }, [currentSpread, selectedTemplate, cellMappings, columnsJSON, templateType, tableData]);

  // LIST 타입 컬럼에 드롭다운 설정
  const setupListValidation = React.useCallback((activeSheet: any, cellPos: {row: number, col: number}, options: string[], rowCount: number = 1) => {
    // ComboBox 셀 타입 생성
    const comboBoxCellType = new GC.Spread.Sheets.CellTypes.ComboBox();
    comboBoxCellType.items(options);
    comboBoxCellType.editorValueType(GC.Spread.Sheets.CellTypes.EditorValueType.text);

    // 단일 셀 또는 범위에 적용
    for (let i = 0; i < rowCount; i++) {
      const targetRow = cellPos.row + i;
      activeSheet.setCellType(targetRow, cellPos.col, comboBoxCellType);
      
      // 추가로 데이터 검증도 설정
      const validator = GC.Spread.Sheets.DataValidation.createListValidator(options);
      activeSheet.setDataValidator(targetRow, cellPos.col, validator);
    }
  }, []);

  const initSpread = React.useCallback((spread: any, template?: TemplateItem) => {
    const workingTemplate = template || selectedTemplate;
    if (!spread || !workingTemplate) return;

    try {
      setCurrentSpread(spread);
      setHasChanges(false);
      setValidationErrors([]);

      // SPR_LST_SETUP.CONTENT와 SPR_ITM_LST_SETUP.CONTENT 중에서 값이 있는 것을 찾아서 사용
      let contentJson = null;
      let dataSheets = null;
      
      // SPR_LST_SETUP.CONTENT가 있으면 우선 사용
      if (workingTemplate.SPR_LST_SETUP?.CONTENT) {
        contentJson = workingTemplate.SPR_LST_SETUP.CONTENT;
        dataSheets = workingTemplate.SPR_LST_SETUP.DATA_SHEETS;
        console.log('Using SPR_LST_SETUP.CONTENT for template:', workingTemplate.NAME, '(TMPL_TYPE:', workingTemplate.TMPL_TYPE, ')');
      } 
      // SPR_ITM_LST_SETUP.CONTENT가 있으면 사용
      else if (workingTemplate.SPR_ITM_LST_SETUP?.CONTENT) {
        contentJson = workingTemplate.SPR_ITM_LST_SETUP.CONTENT;
        dataSheets = workingTemplate.SPR_ITM_LST_SETUP.DATA_SHEETS;
        console.log('Using SPR_ITM_LST_SETUP.CONTENT for template:', workingTemplate.NAME, '(TMPL_TYPE:', workingTemplate.TMPL_TYPE, ')');
      }

      if (!contentJson) {
        console.warn('No CONTENT found in template:', workingTemplate.NAME);
        return;
      }

      console.log(`Loading template content for: ${workingTemplate.NAME} (Type: ${workingTemplate.TMPL_TYPE})`);
      
      const jsonData = typeof contentJson === 'string' 
        ? JSON.parse(contentJson) 
        : contentJson;

      // 렌더링 일시 중단
      spread.suspendPaint();

      try {
        // fromJSON으로 템플릿 구조 로드
        spread.fromJSON(jsonData);

        // 활성 시트 가져오기
        const activeSheet = spread.getActiveSheet();
        
        // 시트 보호 먼저 해제
        activeSheet.options.isProtected = false;

        // MAP_CELL_ATT 정보를 사용해서 데이터 매핑
        if (dataSheets && dataSheets.length > 0) {
          const mappings: Array<{attId: string, cellAddress: string, isEditable: boolean}> = [];
          
          dataSheets.forEach(dataSheet => {
            if (dataSheet.MAP_CELL_ATT) {
              dataSheet.MAP_CELL_ATT.forEach(mapping => {
                const { ATT_ID, IN } = mapping;
                
                if (IN && IN.trim() !== "") {
                  const cellPos = parseCellAddress(IN);
                  if (cellPos) {
                    const isEditable = isFieldEditable(ATT_ID);
                    const columnConfig = columnsJSON.find(col => col.key === ATT_ID);
                    
                    mappings.push({
                      attId: ATT_ID,
                      cellAddress: IN,
                      isEditable: isEditable
                    });
                    
                    // 템플릿 타입에 따라 다른 데이터 처리
                    if (templateType === 'SPREAD_ITEM' && selectedRow) {
                      // 단일 행 처리 (기존 로직)
                      const cell = activeSheet.getCell(cellPos.row, cellPos.col);
                      const value = selectedRow[ATT_ID];
                      if (value !== undefined && value !== null) {
                        cell.value(value);
                      }
                      
                      if (value === undefined || value === null) {
                        cell.value(null);
                      }

                      // LIST 타입 컬럼에 드롭다운 설정
                      if (columnConfig?.type === "LIST" && columnConfig.options && isEditable) {
                        setupListValidation(activeSheet, cellPos, columnConfig.options, 1);
                      }

                      // 스타일 적용
                      cell.locked(!isEditable);
                      const existingStyle = activeSheet.getStyle(cellPos.row, cellPos.col);
                      const newStyle = existingStyle ? Object.assign(new GC.Spread.Sheets.Style(), existingStyle) : new GC.Spread.Sheets.Style();
                      
                      if (isEditable) {
                        newStyle.backColor = "#f0fdf4";
                      } else {
                        newStyle.backColor = "#f9fafb";
                        newStyle.foreColor = "#6b7280";
                      }
                      
                      activeSheet.setStyle(cellPos.row, cellPos.col, newStyle);
                      
                    } else if (templateType === 'SPREAD_LIST' && tableData.length > 0) {
                      // 복수 행 처리 - 첫 번째 행부터 시작해서 아래로 채움
                      
                      // LIST 타입 컬럼에 드롭다운 설정 (모든 행에 대해)
                      if (columnConfig?.type === "LIST" && columnConfig.options && isEditable) {
                        setupListValidation(activeSheet, cellPos, columnConfig.options, tableData.length);
                      }

                      // 필요한 경우 행 추가 (tableData 길이만큼 충분히 확보)
                      const currentRowCount = activeSheet.getRowCount();
                      const requiredRowCount = cellPos.row + tableData.length;
                      if (requiredRowCount > currentRowCount) {
                        activeSheet.setRowCount(requiredRowCount + 10); // 여유분 추가
                      }

                      tableData.forEach((rowData, index) => {
                        const targetRow = cellPos.row + index;
                        const cell = activeSheet.getCell(targetRow, cellPos.col);
                        const value = rowData[ATT_ID];
                        
                        if (value !== undefined && value !== null) {
                          cell.value(value);
                        }

                        if (value === undefined || value === null) {
                          cell.value(null);
                        }
                        
                        const cellEditable = isFieldEditable(ATT_ID, rowData);
                        cell.locked(!cellEditable);
                        
                        // 스타일 적용
                        const existingStyle = activeSheet.getStyle(targetRow, cellPos.col);
                        const newStyle = existingStyle ? Object.assign(new GC.Spread.Sheets.Style(), existingStyle) : new GC.Spread.Sheets.Style();
                        
                        if (cellEditable) {
                          newStyle.backColor = "#f0fdf4";
                        } else {
                          newStyle.backColor = "#f9fafb";
                          newStyle.foreColor = "#6b7280";
                        }
                        
                        activeSheet.setStyle(targetRow, cellPos.col, newStyle);
                      });
                    }
                    
                    console.log(`Mapped ${ATT_ID} to cell ${IN} - ${isEditable ? 'Editable' : 'Read-only'}`);
                  }
                }
              });
            }
          });
          
          setCellMappings(mappings);
          
          // 시트 보호 설정
          activeSheet.options.isProtected = true;
          activeSheet.options.protectionOptions = {
            allowSelectLockedCells: true,
            allowSelectUnlockedCells: true,
            allowSort: false,
            allowFilter: false,
            allowEditObjects: false,
            allowResizeRows: false,
            allowResizeColumns: false
          };

          // 이벤트 리스너 추가
          activeSheet.bind(GC.Spread.Sheets.Events.CellChanged, (event: any, info: any) => {
            console.log('Cell changed:', info);
            setHasChanges(true);
          });

          activeSheet.bind(GC.Spread.Sheets.Events.ValueChanged, (event: any, info: any) => {
            console.log('Value changed:', info);
            setHasChanges(true);
          });

          // 복사 붙여넣기 이벤트 추가
          activeSheet.bind(GC.Spread.Sheets.Events.ClipboardPasted, (event: any, info: any) => {
            console.log('Clipboard pasted:', info);
            setHasChanges(true);
          });

          // 편집 시작 시 읽기 전용 셀 확인
          activeSheet.bind(GC.Spread.Sheets.Events.EditStarting, (event: any, info: any) => {
            const mapping = mappings.find(m => {
              const cellPos = parseCellAddress(m.cellAddress);
              return cellPos && cellPos.row <= info.row && cellPos.col === info.col;
            });
            
            if (mapping) {
              // columnsJSON에서 해당 필드의 shi 확인
              const columnConfig = columnsJSON.find(col => col.key === mapping.attId);
              if (columnConfig?.shi === true) {
                toast.warning(`${mapping.attId} field is read-only (Column configuration)`);
                info.cancel = true;
                return;
              }
              
              // SPREAD_LIST인 경우 해당 행의 데이터에서 shi 확인
              if (templateType === 'SPREAD_LIST') {
                const dataRowIndex = info.row - parseCellAddress(mapping.cellAddress)!.row;
                const rowData = tableData[dataRowIndex];
                if (rowData && rowData.shi === true) {
                  toast.warning(`Row ${dataRowIndex + 1}: ${mapping.attId} field is read-only (SHI mode)`);
                  info.cancel = true;
                  return;
                }
              }
              
              if (!mapping.isEditable) {
                toast.warning(`${mapping.attId} field is read-only`);
                info.cancel = true;
              }
            }
          });

          // 편집 종료 시 데이터 검증
          activeSheet.bind(GC.Spread.Sheets.Events.EditEnded, (event: any, info: any) => {
            const mapping = mappings.find(m => {
              const cellPos = parseCellAddress(m.cellAddress);
              return cellPos && cellPos.row <= info.row && cellPos.col === info.col;
            });
            
            if (mapping) {
              const columnConfig = columnsJSON.find(col => col.key === mapping.attId);
              if (columnConfig) {
                const cellValue = activeSheet.getValue(info.row, info.col);
                const errorMessage = validateCellValue(cellValue, columnConfig.type, columnConfig.options);
                
                if (errorMessage) {
                  toast.warning(`Invalid value in ${mapping.attId}: ${errorMessage}`);
                  // 스타일을 오류 상태로 변경
                  const errorStyle = new GC.Spread.Sheets.Style();
                  errorStyle.backColor = "#fef2f2";
                  errorStyle.foreColor = "#dc2626";
                  activeSheet.setStyle(info.row, info.col, errorStyle);
                } else {
                  // 정상 스타일로 복원
                  const cellEditable = isFieldEditable(mapping.attId);
                  const normalStyle = new GC.Spread.Sheets.Style();
                  normalStyle.backColor = cellEditable ? "#f0fdf4" : "#f9fafb";
                  normalStyle.foreColor = cellEditable ? "#000000" : "#6b7280";
                  activeSheet.setStyle(info.row, info.col, normalStyle);
                }
              }
            }
          });
        }
      } finally {
        spread.resumePaint();
      }

    } catch (error) {
      console.error('Error initializing spread:', error);
      toast.error('Failed to load template');
      if (spread && spread.resumePaint) {
        spread.resumePaint();
      }
    }
  }, [selectedTemplate, templateType, selectedRow, tableData, isFieldEditable, columnsJSON, setupListValidation, validateCellValue]);

  // 변경사항 저장 함수
  const handleSaveChanges = React.useCallback(async () => {
    if (!currentSpread || !hasChanges) {
      toast.info("No changes to save");
      return;
    }

    // 저장 전 데이터 검증
    const errors = validateAllData();
    if (errors.length > 0) {
      toast.error(`Cannot save: ${errors.length} validation errors found. Please fix them first.`);
      return;
    }

    try {
      setIsPending(true);

      const activeSheet = currentSpread.getActiveSheet();

      if (templateType === 'SPREAD_ITEM' && selectedRow) {
        // 단일 행 저장 (기존 로직)
        const dataToSave = { ...selectedRow };

        cellMappings.forEach(mapping => {
          if (mapping.isEditable) {
            const cellPos = parseCellAddress(mapping.cellAddress);
            if (cellPos) {
              const cellValue = activeSheet.getValue(cellPos.row, cellPos.col);
              dataToSave[mapping.attId] = cellValue;
            }
          }
        });

        dataToSave.TAG_NO = selectedRow.TAG_NO;

        const { success, message } = await updateFormDataInDB(
          formCode,
          contractItemId,
          dataToSave
        );

        if (!success) {
          toast.error(message);
          return;
        }

        toast.success("Changes saved successfully!");
        onUpdateSuccess?.(dataToSave);

      } else if (templateType === 'SPREAD_LIST' && tableData.length > 0) {
        // 복수 행 저장
        const updatedRows: GenericData[] = [];
        let saveCount = 0;

        for (let i = 0; i < tableData.length; i++) {
          const originalRow = tableData[i];
          const dataToSave = { ...originalRow };
          let hasRowChanges = false;

          // 각 매핑에 대해 해당 행의 값 확인
          cellMappings.forEach(mapping => {
            // columnsJSON에서 해당 필드의 shi 확인
            const columnConfig = columnsJSON.find(col => col.key === mapping.attId);
            const isColumnEditable = columnConfig?.shi !== true;
            const isRowEditable = originalRow.shi !== true;
            
            if (mapping.isEditable && isColumnEditable && isRowEditable) {
              const cellPos = parseCellAddress(mapping.cellAddress);
              if (cellPos) {
                const targetRow = cellPos.row + i;
                const cellValue = activeSheet.getValue(targetRow, cellPos.col);
                
                // 값이 변경되었는지 확인
                if (cellValue !== originalRow[mapping.attId]) {
                  dataToSave[mapping.attId] = cellValue;
                  hasRowChanges = true;
                }
              }
            }
          });

          // 변경사항이 있는 행만 저장
          if (hasRowChanges) {
            dataToSave.TAG_NO = originalRow.TAG_NO; // TAG_NO는 절대 변경되지 않도록

            const { success } = await updateFormDataInDB(
              formCode,
              contractItemId,
              dataToSave
            );

            if (success) {
              updatedRows.push(dataToSave);
              saveCount++;
            }
          } else {
            updatedRows.push(originalRow); // 변경사항이 없으면 원본 유지
          }
        }

        if (saveCount > 0) {
          toast.success(`${saveCount} rows saved successfully!`);
          onUpdateSuccess?.(updatedRows);
        } else {
          toast.info("No changes to save");
        }
      }

      setHasChanges(false);
      setValidationErrors([]);

    } catch (error) {
      console.error("Error saving changes:", error);
      toast.error("An unexpected error occurred while saving");
    } finally {
      setIsPending(false);
    }
  }, [currentSpread, hasChanges, templateType, selectedRow, tableData, formCode, contractItemId, onUpdateSuccess, cellMappings, columnsJSON, validateAllData]);

  if (!isOpen) return null;

  // 데이터 유효성 검사
  const isDataValid = templateType === 'SPREAD_ITEM' ? !!selectedRow : tableData.length > 0;
  const dataCount = templateType === 'SPREAD_ITEM' ? 1 : tableData.length;

  return (
    <Dialog open={isOpen} onOpenChange={onClose}>
      <DialogContent 
        className="w-[80%] max-w-none h-[80vh] flex flex-col" 
        style={{maxWidth:"80vw"}}
      >
        <DialogHeader className="flex-shrink-0">
          <DialogTitle>SEDP Template - {formCode}</DialogTitle>
          <DialogDescription>
            <div className="space-y-3">
              {/* 템플릿 선택 */}
              {availableTemplates.length > 1 && (
                <div className="flex items-center gap-4">
                  <span className="text-sm font-medium">Template:</span>
                  <Select value={selectedTemplateId} onValueChange={handleTemplateChange}>
                    <SelectTrigger className="w-64">
                      <SelectValue placeholder="Select a template" />
                    </SelectTrigger>
                    <SelectContent>
                      {availableTemplates.map(template => (
                        <SelectItem key={template.TMPL_ID} value={template.TMPL_ID}>
                          {template.NAME} ({template.TMPL_TYPE})
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
              )}

              {/* 템플릿 정보 */}
              {selectedTemplate && (
                <div className="flex items-center gap-4 text-sm">
                  <span className="font-medium text-blue-600">
                    Template Type: {selectedTemplate.TMPL_TYPE === 'SPREAD_LIST' ? 'List View (SPREAD_LIST)' : 'Item View (SPREAD_ITEM)'}
                  </span>
                  {templateType === 'SPREAD_ITEM' && selectedRow && (
                    <span>• Selected TAG_NO: {selectedRow.TAG_NO || 'N/A'}</span>
                  )}
                  {templateType === 'SPREAD_LIST' && (
                    <span>• {dataCount} rows</span>
                  )}
                  {hasChanges && (
                    <span className="text-orange-600 font-medium">
                      • Unsaved changes
                    </span>
                  )}
                  {validationErrors.length > 0 && (
                    <span className="text-red-600 font-medium flex items-center">
                      <AlertTriangle className="w-4 h-4 mr-1" />
                      {validationErrors.length} validation errors
                    </span>
                  )}
                </div>
              )}

              {/* 범례 */}
              <div className="flex items-center gap-4 text-xs">
                <span className="text-muted-foreground">
                  <span className="inline-block w-3 h-3 bg-green-100 border border-green-400 mr-1"></span>
                  Editable fields
                </span>
                <span className="text-muted-foreground">
                  <span className="inline-block w-3 h-3 bg-gray-100 border border-gray-300 mr-1"></span>
                  Read-only fields
                </span>
                <span className="text-muted-foreground">
                  <span className="inline-block w-3 h-3 bg-red-100 border border-red-300 mr-1"></span>
                  Validation errors
                </span>
                {cellMappings.length > 0 && (
                  <span className="text-blue-600">
                    {editableFieldsCount} of {cellMappings.length} fields editable
                  </span>
                )}
              </div>
            </div>
          </DialogDescription>
        </DialogHeader>
        
        {/* SpreadSheets 컴포넌트 영역 */}
        <div className="flex-1 overflow-hidden">
          {selectedTemplate && isClient && isDataValid ? (
            <SpreadSheets 
              key={`${selectedTemplate.TMPL_TYPE}-${selectedTemplate.TMPL_ID}-${selectedTemplateId}`}
              workbookInitialized={initSpread}
              hostStyle={hostStyle}
            />
          ) : (
            <div className="flex items-center justify-center h-full text-muted-foreground">
              {!isClient ? (
                <>
                  <Loader className="mr-2 h-4 w-4 animate-spin" />
                  Loading...
                </>
              ) : !selectedTemplate ? (
                "No template available"
              ) : !isDataValid ? (
                `No ${templateType === 'SPREAD_ITEM' ? 'selected row' : 'data'} available`
              ) : (
                "Template not ready"
              )}
            </div>
          )}
        </div>

        <DialogFooter className="flex-shrink-0">
          <div className="flex items-center gap-2">
            <Button variant="outline" onClick={onClose}>
              Close
            </Button>
            
            {hasChanges && (
              <Button 
                variant="default" 
                onClick={handleSaveChanges}
                disabled={isPending || validationErrors.length > 0}
              >
                {isPending ? (
                  <>
                    <Loader className="mr-2 h-4 w-4 animate-spin" />
                    Saving...
                  </>
                ) : (
                  <>
                    <Save className="mr-2 h-4 w-4" />
                    Save Changes
                  </>
                )}
              </Button>
            )}

            {validationErrors.length > 0 && (
              <Button 
                variant="outline" 
                onClick={validateAllData}
                className="text-red-600 border-red-300 hover:bg-red-50"
              >
                <AlertTriangle className="mr-2 h-4 w-4" />
                Check Errors ({validationErrors.length})
              </Button>
            )}
          </div>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}