import React, { useState, useRef, useCallback, useEffect } from "react";
import { Card, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { toast } from "sonner";
import { showErrorToast } from "@/lib/utils/toastUtils";
import { uploadFiles, downloadFile, deleteFile, getComponentFiles } from "@/lib/api/file";
import { GlobalFileManager } from "@/lib/api/globalFile";
import { formatFileSize } from "@/lib/utils";
import { apiClient } from "@/lib/api/client";
import { FileViewerModal } from "./FileViewerModal";
import { FileManagerModal } from "./FileManagerModal";
import { FileUploadConfig, FileInfo, FileUploadStatus, FileUploadResponse } from "./types";
import { useAuth } from "@/hooks/useAuth";
import {
  Upload,
  File,
  FileText,
  Image,
  Video,
  Music,
  Archive,
  Download,
  Eye,
  Trash2,
  AlertCircle,
  FileImage,
  FileVideo,
  FileAudio,
  Presentation,
} from "lucide-react";

// 파일 아이콘 매핑
const getFileIcon = (extension: string) => {
  const ext = extension.toLowerCase().replace(".", "");

  if (["jpg", "jpeg", "png", "gif", "bmp", "webp", "svg"].includes(ext)) {
    return <FileImage className="h-6 w-6 text-primary" />;
  }
  if (["mp4", "avi", "mov", "wmv", "flv", "webm"].includes(ext)) {
    return <FileVideo className="h-6 w-6 text-purple-500" />;
  }
  if (["mp3", "wav", "flac", "aac", "ogg"].includes(ext)) {
    return <FileAudio className="h-6 w-6 text-emerald-500" />;
  }
  if (["pdf"].includes(ext)) {
    return <FileText className="h-6 w-6 text-destructive" />;
  }
  if (["doc", "docx", "hwp", "hwpx", "pages"].includes(ext)) {
    return <FileText className="h-6 w-6 text-primary" />;
  }
  if (["xls", "xlsx", "hcell", "numbers"].includes(ext)) {
    return <FileText className="h-6 w-6 text-emerald-600" />;
  }
  if (["ppt", "pptx", "hanshow", "keynote"].includes(ext)) {
    return <Presentation className="h-6 w-6 text-amber-500" />;
  }
  if (["zip", "rar", "7z", "tar", "gz"].includes(ext)) {
    return <Archive className="h-6 w-6 text-muted-foreground" />;
  }

  return <File className="h-6 w-6 text-muted-foreground/70" />;
};

export interface FileUploadComponentProps {
  component: any;
  componentConfig: FileUploadConfig;
  componentStyle: React.CSSProperties;
  className: string;
  isInteractive: boolean;
  isDesignMode: boolean;
  formData: any;
  onFormDataChange: (data: any) => void;
  onClick?: () => void;
  onDragStart?: (e: React.DragEvent) => void;
  onDragEnd?: (e: React.DragEvent) => void;
  onUpdate?: (updates: Partial<any>) => void;
  autoGeneration?: any;
  hidden?: boolean;
  onConfigChange?: (config: any) => void;
}

const FileUploadComponent: React.FC<FileUploadComponentProps> = ({
  component,
  componentConfig,
  componentStyle,
  className,
  isInteractive,
  isDesignMode = false, // 기본값 설정
  formData,
  onFormDataChange,
  onClick,
  onDragStart,
  onDragEnd,
  onUpdate,
}) => {
  // 🔑 인증 정보 가져오기
  const { user } = useAuth();
  
  const [uploadedFiles, setUploadedFiles] = useState<FileInfo[]>([]);
  const [uploadStatus, setUploadStatus] = useState<FileUploadStatus>("idle");
  const [dragOver, setDragOver] = useState(false);
  const [viewerFile, setViewerFile] = useState<FileInfo | null>(null);
  const [isViewerOpen, setIsViewerOpen] = useState(false);
  const [isFileManagerOpen, setIsFileManagerOpen] = useState(false);
  const [forceUpdate, setForceUpdate] = useState(0);
  const [representativeImageUrl, setRepresentativeImageUrl] = useState<string | null>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);
  const containerRef = useRef<HTMLDivElement>(null);

  // 🔑 레코드 모드 판단: formData에 id가 있으면 특정 행에 연결된 파일 관리
  const isRecordMode = !!(formData?.id && !String(formData.id).startsWith('temp_'));
  const recordTableName = formData?.tableName || component.tableName;
  const recordId = formData?.id;
  // 🔑 컬럼명 결정: 레코드 모드에서는 무조건 'attachments' 사용
  // component.columnName이나 component.id는 '파일_업로드' 같은 한글 라벨일 수 있어서 DB 컬럼명으로 부적합
  // 레코드 모드가 아닐 때만 component.columnName 또는 component.id 사용
  const columnName = isRecordMode ? 'attachments' : (component.columnName || component.id || 'attachments');
  
  // 🔑 레코드 모드용 targetObjid 생성
  const getRecordTargetObjid = useCallback(() => {
    if (isRecordMode && recordTableName && recordId) {
      return `${recordTableName}:${recordId}:${columnName}`;
    }
    return null;
  }, [isRecordMode, recordTableName, recordId, columnName]);

  // 🔑 레코드별 고유 키 생성 (localStorage, 전역 상태용)
  const getUniqueKey = useCallback(() => {
    if (isRecordMode && recordTableName && recordId) {
      // 레코드 모드: 테이블명:레코드ID:컴포넌트ID 형태로 고유 키 생성
      return `fileUpload_${recordTableName}_${recordId}_${component.id}`;
    }
    // 기본 모드: 컴포넌트 ID만 사용
    return `fileUpload_${component.id}`;
  }, [isRecordMode, recordTableName, recordId, component.id]);

  // 🔍 디버깅: 레코드 모드 상태 로깅
  useEffect(() => {
    console.log("📎 [FileUploadComponent] 모드 확인:", {
      isRecordMode,
      recordTableName,
      recordId,
      columnName,
      targetObjid: getRecordTargetObjid(),
      uniqueKey: getUniqueKey(),
      formDataKeys: formData ? Object.keys(formData) : [],
      // 🔍 추가 디버깅: 어디서 tableName이 오는지 확인
      "formData.tableName": formData?.tableName,
      "component.tableName": component.tableName,
      "component.columnName": component.columnName,
      "component.id": component.id,
    });
  }, [isRecordMode, recordTableName, recordId, columnName, getRecordTargetObjid, getUniqueKey, formData, component.tableName, component.columnName, component.id]);

  // 🆕 레코드 ID 변경 시 파일 목록 초기화 및 새로 로드
  const prevRecordIdRef = useRef<any>(null);
  const prevIsRecordModeRef = useRef<boolean | null>(null);
  useEffect(() => {
    const recordIdChanged = prevRecordIdRef.current !== null && prevRecordIdRef.current !== recordId;
    const modeChanged = prevIsRecordModeRef.current !== null && prevIsRecordModeRef.current !== isRecordMode;

    if (recordIdChanged || modeChanged) {
      prevRecordIdRef.current = recordId;
      prevIsRecordModeRef.current = isRecordMode;

      // 레코드 변경 또는 등록 모드 전환 시 항상 파일 목록 초기화
      setUploadedFiles([]);
      setRepresentativeImageUrl(null);

      // localStorage 캐시도 정리 (새 등록 모드 전환 시)
      if (!isRecordMode) {
        try {
          const backupKey = getUniqueKey();
          localStorage.removeItem(backupKey);
          if (typeof window !== "undefined") {
            const globalFileState = (window as any).globalFileState || {};
            delete globalFileState[backupKey];
            (window as any).globalFileState = globalFileState;
          }
        } catch {}
      }
    } else if (prevRecordIdRef.current === null) {
      prevRecordIdRef.current = recordId;
      prevIsRecordModeRef.current = isRecordMode;
    }
  }, [recordId, isRecordMode, getUniqueKey]);

  // 컴포넌트 마운트 시 즉시 localStorage에서 파일 복원
  useEffect(() => {
    if (!component?.id) return;

    // 새 등록 모드(레코드 없음)에서는 localStorage 복원 스킵 - 빈 상태 유지
    if (!isRecordMode || !recordId) {
      return;
    }

    try {
      // 🔑 레코드별 고유 키 사용
      const backupKey = getUniqueKey();
      const backupFiles = localStorage.getItem(backupKey);
      if (backupFiles) {
        const parsedFiles = JSON.parse(backupFiles);
        if (parsedFiles.length > 0) {
          setUploadedFiles(parsedFiles);

          // 전역 상태에도 복원 (레코드별 고유 키 사용)
          if (typeof window !== "undefined") {
            (window as any).globalFileState = {
              ...(window as any).globalFileState,
              [backupKey]: parsedFiles,
            };
          }
        }
      }
    } catch (e) {
      console.warn("컴포넌트 마운트 시 파일 복원 실패:", e);
    }
  }, [component.id, getUniqueKey, recordId, isRecordMode]);

  // 모달 닫힘/저장 성공 시 localStorage 파일 캐시 정리 (등록 후 재등록 시 이전 파일 잔존 방지)
  // 모달(Dialog) 내부의 컴포넌트만 초기화 대상 - 일반 화면의 파일 업로드는 초기화하지 않음
  useEffect(() => {
    const handleClearFileCache = (event: Event) => {
      // 모달 내부 컴포넌트만 초기화 (일반 화면에서는 스킵)
      const isInModal = containerRef.current ? !!containerRef.current.closest('[role="dialog"]') : false;
      if (!isInModal) {
        return;
      }

      const backupKey = getUniqueKey();
      try {
        localStorage.removeItem(backupKey);
        setUploadedFiles([]);
        setRepresentativeImageUrl(null);
        if (typeof window !== "undefined") {
          const globalFileState = (window as any).globalFileState || {};
          delete globalFileState[backupKey];
          (window as any).globalFileState = globalFileState;
        }
      } catch (e) {
        console.warn("파일 캐시 정리 실패:", e);
      }
    };

    window.addEventListener("closeEditModal", handleClearFileCache);
    window.addEventListener("saveSuccess", handleClearFileCache);
    window.addEventListener("saveSuccessInModal", handleClearFileCache);

    return () => {
      window.removeEventListener("closeEditModal", handleClearFileCache);
      window.removeEventListener("saveSuccess", handleClearFileCache);
      window.removeEventListener("saveSuccessInModal", handleClearFileCache);
    };
  }, [getUniqueKey]);

  // 🎯 화면설계 모드에서 실제 화면으로의 실시간 동기화 이벤트 리스너
  useEffect(() => {
    const handleDesignModeFileChange = (event: CustomEvent) => {
      console.log("🎯🎯🎯 FileUploadComponent 화면설계 모드 파일 변경 이벤트 수신:", {
        eventComponentId: event.detail.componentId,
        currentComponentId: component.id,
        isMatch: event.detail.componentId === component.id,
        filesCount: event.detail.files?.length || 0,
        action: event.detail.action,
        source: event.detail.source,
        eventDetail: event.detail,
      });

      // 현재 컴포넌트와 일치하고 화면설계 모드에서 온 이벤트인 경우
      if (event.detail.componentId === component.id && event.detail.source === "designMode") {
        // 파일 상태 업데이트
        const newFiles = event.detail.files || [];
        setUploadedFiles(newFiles);

        // localStorage 백업 업데이트 (레코드별 고유 키 사용)
        try {
          const backupKey = getUniqueKey();
          localStorage.setItem(backupKey, JSON.stringify(newFiles));
          console.log("💾 화면설계 모드 동기화 후 localStorage 백업 업데이트:", {
            uniqueKey: backupKey,
            componentId: component.id,
            recordId: recordId,
            fileCount: newFiles.length,
          });
        } catch (e) {
          console.warn("localStorage 백업 업데이트 실패:", e);
        }

        // 전역 상태 업데이트
        if (typeof window !== "undefined") {
          (window as any).globalFileState = {
            ...(window as any).globalFileState,
            [component.id]: newFiles,
          };
        }

        // onUpdate 콜백 호출 (부모 컴포넌트에 알림)
        if (onUpdate) {
          onUpdate({
            uploadedFiles: newFiles,
            lastFileUpdate: event.detail.timestamp,
          });
        }

        console.log("🎉🎉🎉 화면설계 모드 → 실제 화면 동기화 완료:", {
          componentId: component.id,
          finalFileCount: newFiles.length,
        });
      }
    };

    if (typeof window !== "undefined") {
      window.addEventListener("globalFileStateChanged", handleDesignModeFileChange as EventListener);

      return () => {
        window.removeEventListener("globalFileStateChanged", handleDesignModeFileChange as EventListener);
      };
    }
  }, [component.id, onUpdate]);

  // 템플릿 파일과 데이터 파일을 조회하는 함수
  const loadComponentFiles = useCallback(async () => {
    if (!component?.id) return false;

    // 새 등록 모드(레코드 없음)에서는 파일 조회 스킵 - 빈 상태 유지
    if (!isRecordMode || !recordId) {
      return false;
    }

    try {
      // 🔑 레코드 모드: 해당 행의 파일만 조회
      if (recordTableName) {
        console.log("📂 [FileUploadComponent] 레코드 모드 파일 조회:", {
          tableName: recordTableName,
          recordId: recordId,
          columnName: columnName,
          targetObjid: getRecordTargetObjid(),
        });
      }

      // 1. formData에서 screenId 가져오기
      let screenId = formData?.screenId;
      
      // 2. URL에서 screenId 추출 (/screens/:id 패턴)
      if (!screenId && typeof window !== "undefined") {
        const pathname = window.location.pathname;
        const screenMatch = pathname.match(/\/screens\/(\d+)/);
        if (screenMatch) {
          screenId = parseInt(screenMatch[1]);
        }
      }

      // 3. 디자인 모드인 경우 임시 화면 ID 사용
      if (!screenId && isDesignMode) {
        screenId = 999999; // 디자인 모드 임시 ID
      }

      // 4. 화면 ID가 없으면 컴포넌트 ID만으로 조회 시도
      if (!screenId) {
        console.warn("⚠️ 화면 ID 없음, 컴포넌트 ID만으로 파일 조회:", {
          componentId: component.id,
          pathname: window.location.pathname,
          formData: formData,
        });
        // screenId를 0으로 설정하여 컴포넌트 ID로만 조회
        screenId = 0;
      }

      const params = {
        screenId,
        componentId: component.id,
        tableName: recordTableName || formData?.tableName || component.tableName,
        recordId: recordId || formData?.id,
        columnName: columnName, // 🔑 레코드 모드에서 사용하는 columnName
      };

      console.log("📂 [FileUploadComponent] 파일 조회 파라미터:", params);

      const response = await getComponentFiles(params);

      if (response.success) {

        // 파일 데이터 형식 통일
        const formattedFiles = response.totalFiles.map((file: any) => ({
          objid: file.objid || file.id,
          savedFileName: file.savedFileName || file.saved_file_name,
          realFileName: file.realFileName || file.real_file_name,
          fileSize: file.fileSize || file.file_size,
          fileExt: file.fileExt || file.file_ext,
          regdate: file.regdate,
          status: file.status || "ACTIVE",
          uploadedAt: file.uploadedAt || new Date().toISOString(),
          ...file,
        }));


        // 🔄 localStorage의 기존 파일과 서버 파일 병합 (레코드별 고유 키 사용)
        let finalFiles = formattedFiles;
        const uniqueKey = getUniqueKey();
        try {
          const backupFiles = localStorage.getItem(uniqueKey);
          if (backupFiles) {
            const parsedBackupFiles = JSON.parse(backupFiles);

            // 서버에 없는 localStorage 파일들을 추가 (objid 기준으로 중복 제거)
            const serverObjIds = new Set(formattedFiles.map((f: any) => f.objid));
            const additionalFiles = parsedBackupFiles.filter((f: any) => !serverObjIds.has(f.objid));

            finalFiles = [...formattedFiles, ...additionalFiles];
            console.log("📂 [FileUploadComponent] 파일 병합 완료:", {
              uniqueKey,
              serverFiles: formattedFiles.length,
              localFiles: parsedBackupFiles.length,
              finalFiles: finalFiles.length,
            });
          }
        } catch (e) {
          console.warn("파일 병합 중 오류:", e);
        }

        console.log("🔎 [DEBUG-LOAD] API 응답 후 파일 설정:", {
          componentId: component.id,
          serverFiles: formattedFiles.length,
          finalFiles: finalFiles.length,
          files: finalFiles.map((f: any) => ({ objid: f.objid, name: f.realFileName })),
        });
        setUploadedFiles(finalFiles);

        // 전역 상태에도 저장 (레코드별 고유 키 사용)
        if (typeof window !== "undefined") {
          (window as any).globalFileState = {
            ...(window as any).globalFileState,
            [uniqueKey]: finalFiles,
          };

          // 🌐 전역 파일 저장소에 등록 (페이지 간 공유용)
          GlobalFileManager.registerFiles(finalFiles, {
            uploadPage: window.location.pathname,
            componentId: component.id,
            screenId: formData?.screenId,
            recordId: recordId,
          });

          // localStorage 백업도 병합된 파일로 업데이트 (레코드별 고유 키 사용)
          try {
            localStorage.setItem(uniqueKey, JSON.stringify(finalFiles));
          } catch (e) {
            console.warn("localStorage 백업 업데이트 실패:", e);
          }
        }
        return true; // 새로운 로직 사용됨
      }
    } catch (error) {
      console.error("파일 조회 오류:", error);
    }
    return false; // 기존 로직 사용
  }, [component.id, component.tableName, component.columnName, formData?.screenId, formData?.tableName, formData?.id, getUniqueKey, recordId, isRecordMode, recordTableName, columnName]);

  // 컴포넌트 파일 동기화 (DB 우선, localStorage는 보조)
  useEffect(() => {
    const componentFiles = (component as any)?.uploadedFiles || [];

    // 🔒 항상 DB에서 최신 파일 목록을 조회 (멀티테넌시 격리)
    loadComponentFiles().then((dbLoadSuccess) => {
      if (dbLoadSuccess) {
        return; // DB 로드 성공 시 localStorage 무시
      }

      // 새 등록 모드(레코드 없음)에서는 fallback 로드도 스킵 - 항상 빈 상태 유지
      if (!isRecordMode || !recordId) {
        return;
      }

      // DB 로드 실패 시에만 기존 로직 사용 (하위 호환성)
      const globalFileState = typeof window !== "undefined" ? (window as any).globalFileState || {} : {};
      const uniqueKeyForFallback = getUniqueKey();
      const globalFiles = globalFileState[uniqueKeyForFallback] || globalFileState[component.id] || [];

      // 최신 파일 정보 사용 (전역 상태 > 컴포넌트 속성)
      const currentFiles = globalFiles.length > 0 ? globalFiles : componentFiles;

      if (currentFiles.length === 0) {
        return;
      }

      // 최신 파일과 현재 파일 비교
      if (JSON.stringify(currentFiles) !== JSON.stringify(uploadedFiles)) {
        setUploadedFiles(currentFiles);
        setForceUpdate((prev) => prev + 1);
      }
    });
  }, [loadComponentFiles, component.id, (component as any)?.uploadedFiles, (component as any)?.lastFileUpdate, isRecordMode, recordId, getUniqueKey]);

  // 전역 상태 변경 감지 (모든 파일 컴포넌트 동기화 + 화면 복원)
  useEffect(() => {
    const handleGlobalFileStateChange = (event: CustomEvent) => {
      const { componentId, files, fileCount, timestamp, isRestore } = event.detail;

      console.log("🔄 FileUploadComponent 전역 상태 변경 감지:", {
        currentComponentId: component.id,
        eventComponentId: componentId,
        isForThisComponent: componentId === component.id,
        newFileCount: fileCount,
        currentFileCount: uploadedFiles.length,
        timestamp,
        isRestore: !!isRestore,
      });

      // 같은 컴포넌트 ID인 경우에만 업데이트
      if (componentId === component.id) {
        const logMessage = isRestore ? "🔄 화면 복원으로 파일 상태 동기화" : "✅ 파일 상태 동기화 적용";
        console.log(logMessage, {
          componentId: component.id,
          이전파일수: uploadedFiles?.length || 0,
          새파일수: files?.length || 0,
          files: files?.map((f: any) => ({ objid: f.objid, name: f.realFileName })) || [],
        });

        setUploadedFiles(files);
        setForceUpdate((prev) => prev + 1);

        // localStorage 백업도 업데이트 (레코드별 고유 키 사용)
        try {
          const backupKey = getUniqueKey();
          localStorage.setItem(backupKey, JSON.stringify(files));
        } catch (e) {
          console.warn("localStorage 백업 실패:", e);
        }
      }
    };

    if (typeof window !== "undefined") {
      window.addEventListener("globalFileStateChanged", handleGlobalFileStateChange as EventListener);

      return () => {
        window.removeEventListener("globalFileStateChanged", handleGlobalFileStateChange as EventListener);
      };
    }
  }, [component.id, uploadedFiles.length]);

  // 파일 업로드 설정 - componentConfig가 undefined일 수 있으므로 안전하게 처리
  const safeComponentConfig = componentConfig || {};
  const fileConfig = {
    accept: safeComponentConfig.accept || "*/*",
    multiple: safeComponentConfig.multiple || false,
    maxSize: safeComponentConfig.maxSize || 10 * 1024 * 1024, // 10MB
    maxFiles: safeComponentConfig.maxFiles || 5,
    ...safeComponentConfig,
  } as FileUploadConfig;

  // 파일 선택 핸들러
  const handleFileSelect = useCallback(() => {
    console.log("🎯 handleFileSelect 호출됨:", {
      hasFileInputRef: !!fileInputRef.current,
      fileInputRef: fileInputRef.current,
      fileInputType: fileInputRef.current?.type,
      fileInputHidden: fileInputRef.current?.className,
    });

    if (fileInputRef.current) {
      console.log("✅ fileInputRef.current.click() 호출");
      fileInputRef.current.click();
    } else {
      console.log("❌ fileInputRef.current가 null입니다");
    }
  }, []);

  const handleInputChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    const files = Array.from(e.target.files || []);
    if (files.length > 0) {
      handleFileUpload(files);
    }
  }, []);

  // 파일 업로드 처리
  const handleFileUpload = useCallback(
    async (files: File[]) => {
      if (!files.length) return;

      // 중복 파일 체크
      const existingFileNames = uploadedFiles.map((f) => f.realFileName.toLowerCase());
      const duplicates: string[] = [];
      const uniqueFiles: File[] = [];

      files.forEach((file) => {
        const fileName = file.name.toLowerCase();
        if (existingFileNames.includes(fileName)) {
          duplicates.push(file.name);
        } else {
          uniqueFiles.push(file);
        }
      });

      if (duplicates.length > 0) {
        toast.error(`중복된 파일이 있습니다: ${duplicates.join(", ")}`, {
          description: "같은 이름의 파일이 이미 업로드되어 있습니다.",
          duration: 4000,
        });

        if (uniqueFiles.length === 0) {
          return; // 모든 파일이 중복이면 업로드 중단
        }

        // 일부만 중복인 경우 고유한 파일만 업로드
        toast.info(`${uniqueFiles.length}개의 새로운 파일만 업로드합니다.`);
      }

      const filesToUpload = uniqueFiles.length > 0 ? uniqueFiles : files;
      setUploadStatus("uploading");
      toast.loading("파일을 업로드하는 중...", { id: "file-upload" });

      try {
        // 🔑 레코드 모드 우선 사용
        const effectiveTableName = recordTableName || formData?.tableName || component.tableName || "default_table";
        const effectiveRecordId = recordId || formData?.id;
        const effectiveColumnName = columnName;
        
        // screenId 추출 (우선순위: formData > URL)
        let screenId = formData?.screenId;
        if (!screenId && typeof window !== "undefined") {
          const pathname = window.location.pathname;
          const screenMatch = pathname.match(/\/screens\/(\d+)/);
          if (screenMatch) {
            screenId = parseInt(screenMatch[1]);
          }
        }

        let targetObjid;
        // 🔑 레코드 모드 판단 개선
        const effectiveIsRecordMode = isRecordMode || (effectiveRecordId && !String(effectiveRecordId).startsWith('temp_'));
        
        if (effectiveIsRecordMode && effectiveTableName && effectiveRecordId) {
          // 🎯 레코드 모드: 특정 행에 파일 연결
          targetObjid = `${effectiveTableName}:${effectiveRecordId}:${effectiveColumnName}`;
          console.log("📁 [레코드 모드] 파일 업로드:", {
            targetObjid,
            tableName: effectiveTableName,
            recordId: effectiveRecordId,
            columnName: effectiveColumnName,
          });
        } else if (screenId) {
          // 🔑 템플릿 파일 (백엔드 조회 형식과 동일하게)
          targetObjid = `screen_files:${screenId}:${component.id}:${effectiveColumnName}`;
          console.log("📝 [템플릿 모드] 파일 업로드:", targetObjid);
        } else {
          // 기본값 (화면관리에서 사용)
          targetObjid = `temp_${component.id}`;
          console.log("📝 [기본 모드] 파일 업로드:", targetObjid);
        }

        // 🔒 현재 사용자의 회사 코드 가져오기 (멀티테넌시 격리)
        const userCompanyCode = user?.companyCode || (window as any).__user__?.companyCode;
        
        console.log("📤 [FileUploadComponent] 파일 업로드 준비:", {
          userCompanyCode,
          isRecordMode: effectiveIsRecordMode,
          tableName: effectiveTableName,
          recordId: effectiveRecordId,
          columnName: effectiveColumnName,
          targetObjid,
        });
        
        // 🔑 레코드 모드일 때는 effectiveTableName을 우선 사용
        // formData.linkedTable이 'screen_files' 같은 기본값일 수 있으므로 레코드 모드에서는 무시
        const finalLinkedTable = effectiveIsRecordMode 
          ? effectiveTableName 
          : (formData?.linkedTable || effectiveTableName);
        
        const uploadData = {
          // 🎯 formData에서 백엔드 API 설정 가져오기
          autoLink: formData?.autoLink || true,
          linkedTable: finalLinkedTable,
          recordId: effectiveRecordId || `temp_${component.id}`,
          columnName: effectiveColumnName,
          isVirtualFileColumn: formData?.isVirtualFileColumn || true,
          docType: component.fileConfig?.docType || "DOCUMENT",
          docTypeName: component.fileConfig?.docTypeName || "일반 문서",
          companyCode: userCompanyCode, // 🔒 멀티테넌시: 회사 코드 명시적 전달
          // 호환성을 위한 기존 필드들
          tableName: effectiveTableName,
          fieldName: effectiveColumnName,
          targetObjid: targetObjid, // InteractiveDataTable 호환을 위한 targetObjid 추가
          // 🆕 레코드 모드 플래그
          isRecordMode: effectiveIsRecordMode,
        };
        
        console.log("📤 [FileUploadComponent] uploadData 최종:", {
          isRecordMode: effectiveIsRecordMode,
          linkedTable: finalLinkedTable,
          recordId: effectiveRecordId,
          columnName: effectiveColumnName,
          targetObjid,
        });


        console.log("🚀 [FileUploadComponent] uploadFiles API 호출 직전:", {
          filesCount: filesToUpload.length,
          uploadData,
        });
        
        const response = await uploadFiles({
          files: filesToUpload,
          ...uploadData,
        });

        console.log("📥 [FileUploadComponent] uploadFiles API 응답:", response);

        if (response.success) {
          // FileUploadResponse 타입에 맞게 files 배열 사용
          const fileData = response.files || (response as any).data || [];

          if (fileData.length === 0) {
            throw new Error("업로드된 파일 데이터를 받지 못했습니다.");
          }

          const newFiles = fileData.map((file: any) => ({
            objid: file.objid || file.id,
            savedFileName: file.saved_file_name || file.savedFileName,
            realFileName: file.real_file_name || file.realFileName || file.name,
            fileSize: file.file_size || file.fileSize || file.size,
            fileExt: file.file_ext || file.fileExt || file.extension,
            filePath: file.file_path || file.filePath || file.path,
            docType: file.doc_type || file.docType,
            docTypeName: file.doc_type_name || file.docTypeName,
            targetObjid: file.target_objid || file.targetObjid,
            parentTargetObjid: file.parent_target_objid || file.parentTargetObjid,
            companyCode: file.company_code || file.companyCode,
            writer: file.writer,
            regdate: file.regdate,
            status: file.status || "ACTIVE",
            uploadedAt: new Date().toISOString(),
            ...file,
          }));


          const updatedFiles = [...uploadedFiles, ...newFiles];

          setUploadedFiles(updatedFiles);
          setUploadStatus("success");

          // localStorage 백업 (레코드별 고유 키 사용)
          try {
            const backupKey = getUniqueKey();
            localStorage.setItem(backupKey, JSON.stringify(updatedFiles));
          } catch (e) {
            console.warn("localStorage 백업 실패:", e);
          }

          // 전역 상태 업데이트 (모든 파일 컴포넌트 동기화)
          if (typeof window !== "undefined") {
            // 전역 파일 상태 업데이트 (레코드별 고유 키 사용)
            const globalFileState = (window as any).globalFileState || {};
            const uniqueKey = getUniqueKey();
            globalFileState[uniqueKey] = updatedFiles;
            (window as any).globalFileState = globalFileState;

            // 🌐 전역 파일 저장소에 새 파일 등록 (페이지 간 공유용)
            GlobalFileManager.registerFiles(newFiles, {
              uploadPage: window.location.pathname,
              componentId: component.id,
              screenId: formData?.screenId,
              recordId: recordId, // 🆕 레코드 ID 추가
            });

            // 모든 파일 컴포넌트에 동기화 이벤트 발생
            const syncEvent = new CustomEvent("globalFileStateChanged", {
              detail: {
                componentId: component.id,
                uniqueKey: uniqueKey, // 🆕 고유 키 추가
                recordId: recordId, // 🆕 레코드 ID 추가
                files: updatedFiles,
                fileCount: updatedFiles.length,
                timestamp: Date.now(),
              },
            });
            window.dispatchEvent(syncEvent);

            console.log("🌐 전역 파일 상태 업데이트 및 동기화 이벤트 발생:", {
              componentId: component.id,
              fileCount: updatedFiles.length,
              globalState: Object.keys(globalFileState).map((id) => ({
                id,
                fileCount: globalFileState[id]?.length || 0,
              })),
            });
          }

          // 컴포넌트 업데이트
          if (onUpdate) {
            const timestamp = Date.now();
            console.log("🔄 onUpdate 호출:", {
              componentId: component.id,
              uploadedFiles: updatedFiles.length,
              timestamp: timestamp,
            });
            onUpdate({
              uploadedFiles: updatedFiles,
              lastFileUpdate: timestamp,
            });
          } else {
            console.warn("⚠️ onUpdate 콜백이 없습니다!");
          }

          // 🆕 레코드 모드: attachments 컬럼 동기화 (formData 업데이트)
          if (effectiveIsRecordMode && onFormDataChange) {
            // 파일 정보를 간소화하여 attachments 컬럼에 저장할 형태로 변환
            const attachmentsData = updatedFiles.map(file => ({
              objid: file.objid,
              realFileName: file.realFileName,
              fileSize: file.fileSize,
              fileExt: file.fileExt,
              filePath: file.filePath,
              regdate: file.regdate || new Date().toISOString(),
            }));
            
            console.log("📎 [레코드 모드] attachments 컬럼 동기화:", {
              tableName: effectiveTableName,
              recordId: effectiveRecordId,
              columnName: effectiveColumnName,
              fileCount: attachmentsData.length,
            });
            
            // onFormDataChange를 통해 부모 컴포넌트에 attachments 업데이트 알림
            onFormDataChange({ 
              [effectiveColumnName]: attachmentsData,
              // 🆕 백엔드에서 attachments 컬럼 업데이트를 위한 메타 정보
              __attachmentsUpdate: {
                tableName: effectiveTableName,
                recordId: effectiveRecordId,
                columnName: effectiveColumnName,
                files: attachmentsData,
              }
            });
          }

          // 그리드 파일 상태 새로고침 이벤트 발생
          if (typeof window !== "undefined") {
            const refreshEvent = new CustomEvent("refreshFileStatus", {
              detail: {
                tableName: effectiveTableName,
                recordId: effectiveRecordId,
                columnName: effectiveColumnName,
                targetObjid: targetObjid,
                fileCount: updatedFiles.length,
              },
            });
            window.dispatchEvent(refreshEvent);
            console.log("🔄 그리드 파일 상태 새로고침 이벤트 발생:", {
              tableName: effectiveTableName,
              recordId: effectiveRecordId,
              columnName: effectiveColumnName,
              targetObjid,
              fileCount: updatedFiles.length,
            });
          }

          // 폼 데이터 업데이트
          if (onFormDataChange && component.columnName) {
            const fileIds = updatedFiles.map((f) => f.objid);
            onFormDataChange({
              ...formData,
              [component.columnName]: fileIds,
            });
          }

          // 컴포넌트 설정 콜백
          if (safeComponentConfig.onFileUpload) {
            safeComponentConfig.onFileUpload(newFiles);
          }

          // 성공 시 토스트 처리
          setUploadStatus("idle");
          toast.dismiss("file-upload");
          toast.success(`${newFiles.length}개 파일 업로드 완료`);
        } else {
          console.error("❌ 파일 업로드 실패:", response);
          throw new Error(response.message || (response as any).error || "파일 업로드에 실패했습니다.");
        }
      } catch (error) {
        console.error("파일 업로드 오류:", error);
        setUploadStatus("error");
        toast.dismiss("file-upload");
        showErrorToast("파일 업로드에 실패했습니다", error, { guidance: "파일 크기와 형식을 확인하고 다시 시도해 주세요." });
      }
    },
    [safeComponentConfig, uploadedFiles, onFormDataChange, component.columnName, component.id, formData],
  );

  // 파일 뷰어 열기
  const handleFileView = useCallback((file: FileInfo) => {
    setViewerFile(file);
    setIsViewerOpen(true);
  }, []);

  // 파일 뷰어 닫기
  const handleViewerClose = useCallback(() => {
    setIsViewerOpen(false);
    setViewerFile(null);
  }, []);

  // 파일 다운로드
  const handleFileDownload = useCallback(async (file: FileInfo) => {
    try {
      await downloadFile({
        fileId: file.objid,
        serverFilename: file.savedFileName,
        originalName: file.realFileName,
      });
      toast.success(`${file.realFileName} 다운로드 완료`);
    } catch (error) {
      console.error("파일 다운로드 오류:", error);
      toast.error("파일 다운로드에 실패했습니다.");
    }
  }, []);

  // 파일 삭제
  const handleFileDelete = useCallback(
    async (file: FileInfo | string) => {
      try {
        const fileId = typeof file === "string" ? file : file.objid;
        const fileName = typeof file === "string" ? "파일" : file.realFileName;

        const serverFilename = typeof file === "string" ? "temp_file" : file.savedFileName;
        await deleteFile(fileId, serverFilename);

        const updatedFiles = uploadedFiles.filter((f) => f.objid !== fileId);
        setUploadedFiles(updatedFiles);

        // localStorage 백업 업데이트 (레코드별 고유 키 사용)
        try {
          const backupKey = getUniqueKey();
          localStorage.setItem(backupKey, JSON.stringify(updatedFiles));
        } catch (e) {
          console.warn("localStorage 백업 업데이트 실패:", e);
        }

        // 전역 상태 업데이트 (모든 파일 컴포넌트 동기화)
        if (typeof window !== "undefined") {
          // 전역 파일 상태 업데이트 (레코드별 고유 키 사용)
          const globalFileState = (window as any).globalFileState || {};
          const uniqueKey = getUniqueKey();
          globalFileState[uniqueKey] = updatedFiles;
          (window as any).globalFileState = globalFileState;

          // 모든 파일 컴포넌트에 동기화 이벤트 발생
          const syncEvent = new CustomEvent("globalFileStateChanged", {
            detail: {
              componentId: component.id,
              uniqueKey: uniqueKey, // 🆕 고유 키 추가
              recordId: recordId, // 🆕 레코드 ID 추가
              files: updatedFiles,
              fileCount: updatedFiles.length,
              timestamp: Date.now(),
              source: "realScreen", // 🎯 실제 화면에서 온 이벤트임을 표시
              action: "delete",
            },
          });
          window.dispatchEvent(syncEvent);

          console.log("🗑️ 파일 삭제 후 전역 상태 동기화:", {
            componentId: component.id,
            deletedFile: fileName,
            remainingFiles: updatedFiles.length,
          });
        }

        // 컴포넌트 업데이트
        if (onUpdate) {
          const timestamp = Date.now();
          onUpdate({
            uploadedFiles: updatedFiles,
            lastFileUpdate: timestamp,
          });
        }

        // 🆕 레코드 모드: attachments 컬럼 동기화 (파일 삭제 후)
        if (isRecordMode && onFormDataChange && recordTableName && recordId) {
          const attachmentsData = updatedFiles.map(f => ({
            objid: f.objid,
            realFileName: f.realFileName,
            fileSize: f.fileSize,
            fileExt: f.fileExt,
            filePath: f.filePath,
            regdate: f.regdate || new Date().toISOString(),
          }));
          
          console.log("📎 [레코드 모드] 파일 삭제 후 attachments 동기화:", {
            tableName: recordTableName,
            recordId: recordId,
            columnName: columnName,
            remainingFiles: attachmentsData.length,
          });
          
          onFormDataChange({ 
            [columnName]: attachmentsData,
            __attachmentsUpdate: {
              tableName: recordTableName,
              recordId: recordId,
              columnName: columnName,
              files: attachmentsData,
            }
          });
        }

        toast.success(`${fileName} 삭제 완료`);
      } catch (error) {
        console.error("파일 삭제 오류:", error);
        showErrorToast("파일 삭제에 실패했습니다", error, { guidance: "잠시 후 다시 시도해 주세요." });
      }
    },
    [uploadedFiles, onUpdate, component.id, isRecordMode, onFormDataChange, recordTableName, recordId, columnName, getUniqueKey],
  );

  // 대표 이미지 Blob URL 로드
  const loadRepresentativeImage = useCallback(
    async (file: FileInfo) => {
      try {
        const isImage = ["jpg", "jpeg", "png", "gif", "bmp", "webp", "svg"].includes(
          file.fileExt.toLowerCase().replace(".", "")
        );

        if (!isImage) {
          setRepresentativeImageUrl(null);
          return;
        }

        // objid가 없거나 유효하지 않으면 로드 중단
        if (!file.objid || file.objid === "0" || file.objid === "") {
          console.warn("⚠️ 대표 이미지 로드 실패: objid가 없음", file);
          setRepresentativeImageUrl(null);
          return;
        }

        console.log("🖼️ 대표 이미지 로드 시작:", {
          objid: file.objid,
          fileName: file.realFileName,
        });

        // API 클라이언트를 통해 Blob으로 다운로드 (인증 토큰 포함)
        const response = await apiClient.get(`/files/download/${file.objid}`, {
          params: {
            serverFilename: file.savedFileName,
          },
          responseType: "blob",
        });

        // Blob URL 생성
        const blob = new Blob([response.data]);
        const url = window.URL.createObjectURL(blob);
        
        // 이전 URL 정리
        if (representativeImageUrl) {
          window.URL.revokeObjectURL(representativeImageUrl);
        }

        setRepresentativeImageUrl(url);
        console.log("✅ 대표 이미지 로드 성공:", url);
      } catch (error: any) {
        console.error("❌ 대표 이미지 로드 실패:", {
          file: file.realFileName,
          objid: file.objid,
          error: error?.response?.status || error?.message,
        });
        setRepresentativeImageUrl(null);
      }
    },
    [representativeImageUrl],
  );

  // 대표 이미지 설정 핸들러
  const handleSetRepresentative = useCallback(
    async (file: FileInfo) => {
      try {
        // API 호출하여 DB에 대표 파일 설정
        const { setRepresentativeFile } = await import("@/lib/api/file");
        await setRepresentativeFile(file.objid);

        // 상태 업데이트
        const updatedFiles = uploadedFiles.map((f) => ({
          ...f,
          isRepresentative: f.objid === file.objid,
        }));

        setUploadedFiles(updatedFiles);

        // 대표 이미지 로드
        loadRepresentativeImage(file);

        console.log("✅ 대표 파일 설정 완료:", {
          componentId: component.id,
          representativeFile: file.realFileName,
          objid: file.objid,
        });
      } catch (e) {
        console.error("❌ 대표 파일 설정 실패:", e);
      }
    },
    [uploadedFiles, component.id, loadRepresentativeImage]
  );

  // uploadedFiles 변경 시 대표 이미지 로드
  useEffect(() => {
    const representativeFile = uploadedFiles.find(f => f.isRepresentative) || uploadedFiles[0];
    if (representativeFile) {
      loadRepresentativeImage(representativeFile);
    } else {
      setRepresentativeImageUrl(null);
    }

    // 컴포넌트 언마운트 시 Blob URL 정리
    return () => {
      if (representativeImageUrl) {
        window.URL.revokeObjectURL(representativeImageUrl);
      }
    };
  }, [uploadedFiles]);

  // 드래그 앤 드롭 핸들러
  const handleDragOver = useCallback(
    (e: React.DragEvent) => {
      console.log("🎯 드래그 오버 이벤트 감지:", {
        readonly: safeComponentConfig.readonly,
        disabled: safeComponentConfig.disabled,
        dragOver: dragOver,
      });

      e.preventDefault();
      e.stopPropagation();
      if (!safeComponentConfig.readonly && !safeComponentConfig.disabled) {
        setDragOver(true);
        console.log("✅ 드래그 오버 활성화");
      } else {
        console.log("❌ 드래그 차단됨: readonly 또는 disabled");
      }
    },
    [safeComponentConfig.readonly, safeComponentConfig.disabled, dragOver],
  );

  const handleDragLeave = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
    setDragOver(false);
  }, []);

  const handleDrop = useCallback(
    (e: React.DragEvent) => {
      e.preventDefault();
      e.stopPropagation();
      setDragOver(false);

      if (!safeComponentConfig.readonly && !safeComponentConfig.disabled) {
        const files = Array.from(e.dataTransfer.files);
        if (files.length > 0) {
          handleFileUpload(files);
        }
      }
    },
    [safeComponentConfig.readonly, safeComponentConfig.disabled, handleFileUpload],
  );

  // 클릭 핸들러
  const handleClick = useCallback(
    (e: React.MouseEvent) => {
      console.log("🖱️ 파일 업로드 영역 클릭:", {
        readonly: safeComponentConfig.readonly,
        disabled: safeComponentConfig.disabled,
        hasHandleFileSelect: !!handleFileSelect,
      });

      e.preventDefault();
      e.stopPropagation();
      if (!safeComponentConfig.readonly && !safeComponentConfig.disabled) {
        console.log("✅ 파일 선택 함수 호출");
        handleFileSelect();
      } else {
        console.log("❌ 클릭 차단됨: readonly 또는 disabled");
      }
      onClick?.();
    },
    [safeComponentConfig.readonly, safeComponentConfig.disabled, handleFileSelect, onClick],
  );

  return (
    <div
      ref={containerRef}
      style={{
        ...componentStyle,
        width: "100%",
        height: "100%",
        border: "none !important",
        boxShadow: "none !important",
        outline: "none !important",
        backgroundColor: "transparent !important",
        padding: "0px !important",
        borderRadius: "0px !important",
        marginBottom: "8px !important",
      }}
      className={`${className} file-upload-container`}
    >
      {/* 라벨 렌더링 */}
      {component.label && component.style?.labelDisplay !== false && (
        <label
          style={{
            position: "absolute",
            top: "-20px",
            left: "0px",
            fontSize: "12px",
            color: "rgb(107, 114, 128)",
            fontWeight: "400",
            background: "transparent !important",
            border: "none !important",
            boxShadow: "none !important",
            outline: "none !important",
            padding: "0px !important",
            margin: "0px !important"
          }}
        >
          {component.label}
          {component.required && (
            <span style={{ color: "#ef4444" }}>*</span>
          )}
        </label>
      )}

      <div
        className="border-border bg-card relative flex h-full w-full flex-col rounded-lg border overflow-hidden"
      >
        {/* 대표 이미지 전체 화면 표시 */}
        {uploadedFiles.length > 0 ? (() => {
          const representativeFile = uploadedFiles.find(f => f.isRepresentative) || uploadedFiles[0];
          const isImage = representativeFile && ["jpg", "jpeg", "png", "gif", "bmp", "webp", "svg"].includes(
            representativeFile.fileExt.toLowerCase().replace(".", "")
          );

          return (
            <>
              {isImage && representativeImageUrl ? (
                <div className="relative h-full w-full flex items-center justify-center bg-muted/10">
                  <img
                    src={representativeImageUrl}
                    alt={representativeFile.realFileName}
                    className="h-full w-full object-contain"
                  />
                </div>
              ) : isImage && !representativeImageUrl ? (
                <div className="flex h-full w-full flex-col items-center justify-center">
                  <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary mb-2"></div>
                  <p className="text-sm text-muted-foreground">이미지 로딩 중...</p>
                </div>
              ) : (
                <div className="flex h-full w-full flex-col items-center justify-center">
                  {getFileIcon(representativeFile.fileExt)}
                  <p className="mt-3 text-sm font-medium text-center px-4">
                    {representativeFile.realFileName}
                  </p>
                  <Badge variant="secondary" className="mt-2">
                    대표 파일
                  </Badge>
                </div>
              )}
              
              {/* 우측 하단 자세히보기 버튼 */}
              <div className="absolute bottom-3 right-3">
                <Button
                  variant="secondary"
                  size="sm"
                  className="h-8 px-3 text-xs shadow-md"
                  onClick={() => setIsFileManagerOpen(true)}
                >
                  자세히보기 ({uploadedFiles.length})
                </Button>
              </div>
            </>
          );
        })() : (
          <div className="flex h-full w-full flex-col items-center justify-center text-muted-foreground">
            <File className="mb-3 h-12 w-12" />
            <p className="text-sm font-medium">업로드된 파일이 없습니다</p>
            <Button
              variant="outline"
              size="sm"
              className="mt-4 h-8 px-3 text-xs"
              onClick={() => setIsFileManagerOpen(true)}
            >
              파일 업로드
            </Button>
          </div>
        )}
      </div>

      {/* 파일뷰어 모달 */}
      <FileViewerModal
        file={viewerFile}
        isOpen={isViewerOpen}
        onClose={handleViewerClose}
        onDownload={handleFileDownload}
        onDelete={!isDesignMode ? handleFileDelete : undefined}
      />

      {/* 파일 관리 모달 */}
      <FileManagerModal
        isOpen={isFileManagerOpen}
        onClose={() => setIsFileManagerOpen(false)}
        uploadedFiles={uploadedFiles}
        onFileUpload={handleFileUpload}
        onFileDownload={handleFileDownload}
        onFileDelete={handleFileDelete}
        onFileView={handleFileView}
        onSetRepresentative={handleSetRepresentative}
        config={safeComponentConfig}
        isDesignMode={isDesignMode}
      />
    </div>
  );
};

export { FileUploadComponent };
export default FileUploadComponent;
