"use client";

import { getAdaptiveLabelColor } from "@/lib/utils/darkModeColor";

/**
 * V2Media
 *
 * 통합 미디어 컴포넌트 (레거시 FileUploadComponent 기능 통합)
 * - file: 파일 업로드
 * - image: 이미지 업로드/표시
 * - video: 비디오
 * - audio: 오디오
 *
 * 핵심 기능:
 * - FileViewerModal / FileManagerModal (자세히보기)
 * - 대표 이미지 설정
 * - 레코드 모드 (테이블/레코드 연결)
 * - 전역 파일 상태 관리
 * - 파일 다운로드/삭제
 * - DB에서 기존 파일 로드
 */

import React, { forwardRef, useCallback, useRef, useState, useEffect } from "react";
import { Label } from "@/components/ui/label";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { cn } from "@/lib/utils";
import { V2MediaProps } from "@/types/v2-components";
import {
  Upload,
  X,
  File,
  Image as ImageIcon,
  Video,
  Music,
  Eye,
  Download,
  Trash2,
  Plus,
  FileText,
  Archive,
  Presentation,
  FileImage,
  FileVideo,
  FileAudio,
} from "lucide-react";
import { apiClient } from "@/lib/api/client";
import { toast } from "sonner";
import { uploadFiles, downloadFile, deleteFile, getComponentFiles } from "@/lib/api/file";
import { GlobalFileManager } from "@/lib/api/globalFile";
import { formatFileSize } from "@/lib/utils";
import { useAuth } from "@/hooks/useAuth";

// 레거시 모달 컴포넌트 import
import { FileViewerModal } from "@/lib/registry/components/file-upload/FileViewerModal";
import { FileManagerModal } from "@/lib/registry/components/file-upload/FileManagerModal";
import type { FileInfo, FileUploadConfig } from "@/lib/registry/components/file-upload/types";

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

  if (["jpg", "jpeg", "png", "gif", "bmp", "webp", "svg"].includes(ext)) {
    return <FileImage className="text-primary h-6 w-6" />;
  }
  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="text-destructive h-6 w-6" />;
  }
  if (["doc", "docx", "hwp", "hwpx", "pages"].includes(ext)) {
    return <FileText className="text-primary h-6 w-6" />;
  }
  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="text-muted-foreground h-6 w-6" />;
  }

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

/**
 * V2 미디어 컴포넌트 (레거시 기능 통합)
 */
export const V2Media = forwardRef<HTMLDivElement, V2MediaProps>((props, ref) => {
  const {
    id,
    label,
    required,
    readonly,
    disabled,
    style,
    size,
    config: configProp,
    value,
    onChange,
    formData,
    columnName,
    tableName,
    onFormDataChange,
    isDesignMode = false,
    isInteractive = true,
    onUpdate,
    ...restProps
  } = props;

  // 인증 정보
  const { user } = useAuth();

  // config 기본값
  const config = configProp || { type: "file" as const };
  const mediaType = config.type || "file";

  // 파일 상태
  const [uploadedFiles, setUploadedFiles] = useState<FileInfo[]>([]);
  const [uploadStatus, setUploadStatus] = useState<"idle" | "uploading" | "success" | "error">("idle");
  const [dragOver, setDragOver] = useState(false);
  const [representativeImageUrl, setRepresentativeImageUrl] = useState<string | null>(null);

  // 모달 상태
  const [viewerFile, setViewerFile] = useState<FileInfo | null>(null);
  const [isViewerOpen, setIsViewerOpen] = useState(false);
  const [isFileManagerOpen, setIsFileManagerOpen] = useState(false);

  const fileInputRef = useRef<HTMLInputElement>(null);

  // 레코드 모드 판단
  const isRecordMode = !!(formData?.id && !String(formData.id).startsWith("temp_"));
  const recordTableName = formData?.tableName || tableName;
  const recordId = formData?.id;
  // 🔑 columnName 우선 사용 (실제 DB 컬럼명), 없으면 id, 최후에 attachments
  const effectiveColumnName = columnName || id || "attachments";

  // 레코드용 targetObjid 생성
  const getRecordTargetObjid = useCallback(() => {
    if (isRecordMode && recordTableName && recordId) {
      return `${recordTableName}:${recordId}:${effectiveColumnName}`;
    }
    return null;
  }, [isRecordMode, recordTableName, recordId, effectiveColumnName]);

  // 레코드별 고유 키 생성
  const getUniqueKey = useCallback(() => {
    if (isRecordMode && recordTableName && recordId) {
      return `v2media_${recordTableName}_${recordId}_${id}`;
    }
    return `v2media_${id}`;
  }, [isRecordMode, recordTableName, recordId, id]);

  // 레코드 ID 변경 시 파일 목록 초기화
  const prevRecordIdRef = useRef<any>(null);
  useEffect(() => {
    if (prevRecordIdRef.current !== recordId) {
      prevRecordIdRef.current = recordId;
      if (isRecordMode) {
        setUploadedFiles([]);
      }
    }
  }, [recordId, isRecordMode]);

  // 컴포넌트 마운트 시 localStorage에서 파일 복원
  useEffect(() => {
    if (!id) 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);
    }
  }, [id, getUniqueKey, recordId]);

  // DB에서 파일 목록 로드
  const loadComponentFiles = useCallback(async () => {
    if (!id) return false;

    try {
      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]);
        }
      }

      if (!screenId && isDesignMode) {
        screenId = 999999;
      }

      if (!screenId) {
        screenId = 0;
      }

      const params = {
        screenId,
        componentId: id,
        tableName: recordTableName || formData?.tableName || tableName,
        recordId: recordId || formData?.id,
        columnName: effectiveColumnName,
      };

      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(),
          targetObjid: file.targetObjid || file.target_objid,
          filePath: file.filePath || file.file_path,
          ...file,
        }));

        // localStorage와 병합
        let finalFiles = formattedFiles;
        const uniqueKey = getUniqueKey();
        try {
          const backupFiles = localStorage.getItem(uniqueKey);
          if (backupFiles) {
            const parsedBackupFiles = JSON.parse(backupFiles);
            const serverObjIds = new Set(formattedFiles.map((f: any) => f.objid));
            const additionalFiles = parsedBackupFiles.filter((f: any) => !serverObjIds.has(f.objid));
            finalFiles = [...formattedFiles, ...additionalFiles];
          }
        } catch (e) {
          console.warn("파일 병합 오류:", e);
        }

        setUploadedFiles(finalFiles);

        if (typeof window !== "undefined") {
          (window as any).globalFileState = {
            ...(window as any).globalFileState,
            [uniqueKey]: finalFiles,
          };

          GlobalFileManager.registerFiles(finalFiles, {
            uploadPage: window.location.pathname,
            componentId: id,
            screenId: formData?.screenId,
            recordId: recordId,
          });

          try {
            localStorage.setItem(uniqueKey, JSON.stringify(finalFiles));
          } catch (e) {
            console.warn("localStorage 백업 실패:", e);
          }
        }
        return true;
      }
    } catch (error) {
      console.error("파일 조회 오류:", error);
    }
    return false;
  }, [
    id,
    tableName,
    columnName,
    formData?.screenId,
    formData?.tableName,
    formData?.id,
    getUniqueKey,
    recordId,
    isRecordMode,
    recordTableName,
    effectiveColumnName,
    isDesignMode,
  ]);

  // 파일 동기화
  useEffect(() => {
    loadComponentFiles();
  }, [loadComponentFiles]);

  // 전역 상태 변경 감지
  useEffect(() => {
    const handleGlobalFileStateChange = (event: CustomEvent) => {
      const { componentId, files, isRestore } = event.detail;

      if (componentId === id) {
        setUploadedFiles(files);

        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);
      };
    }
  }, [id, getUniqueKey]);

  // 파일 업로드 처리
  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(", ")}`);
        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 || tableName || "default_table";
        const effectiveRecordId = recordId || formData?.id;

        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}`;
        } else if (screenId) {
          targetObjid = `screen_files:${screenId}:${id}:${effectiveColumnName}`;
        } else {
          targetObjid = `temp_${id}`;
        }

        const userCompanyCode = user?.companyCode || (window as any).__user__?.companyCode;

        const finalLinkedTable = effectiveIsRecordMode
          ? effectiveTableName
          : formData?.linkedTable || effectiveTableName;

        const uploadData = {
          autoLink: formData?.autoLink || true,
          linkedTable: finalLinkedTable,
          recordId: effectiveRecordId || `temp_${id}`,
          columnName: effectiveColumnName,
          isVirtualFileColumn: formData?.isVirtualFileColumn || true,
          docType: config?.docType || "DOCUMENT",
          docTypeName: config?.docTypeName || "일반 문서",
          companyCode: userCompanyCode,
          tableName: effectiveTableName,
          fieldName: effectiveColumnName,
          targetObjid: targetObjid,
          isRecordMode: effectiveIsRecordMode,
        };

        const response = await uploadFiles({
          files: filesToUpload,
          ...uploadData,
        });

        if (response.success) {
          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: id,
              screenId: formData?.screenId,
              recordId: recordId,
            });

            const syncEvent = new CustomEvent("globalFileStateChanged", {
              detail: {
                componentId: id,
                uniqueKey: uniqueKey,
                recordId: recordId,
                files: updatedFiles,
                fileCount: updatedFiles.length,
                timestamp: Date.now(),
              },
            });
            window.dispatchEvent(syncEvent);
          }

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

          // onChange 콜백 (objid 배열 또는 단일 값)
          const fileIds = updatedFiles.map((f) => f.objid);
          const finalValue = config.multiple ? fileIds : fileIds[0] || "";
          const targetColumn = columnName || effectiveColumnName;

          console.log("📤 [V2Media] 파일 업로드 완료 - 값 전달:", {
            columnName: targetColumn,
            fileIds,
            finalValue,
            hasOnChange: !!onChange,
            hasOnFormDataChange: !!onFormDataChange,
          });

          if (onChange) {
            onChange(finalValue);
          }

          // 폼 데이터 업데이트 - 부모 컴포넌트 시그니처에 맞게 (fieldName, value) 형식
          if (onFormDataChange && targetColumn) {
            // 🔑 단일 파일: 첫 번째 objid만 전달 (DB 컬럼에 저장될 값)
            // 복수 파일: 콤마 구분 문자열로 전달
            const formValue = config.multiple ? fileIds.join(",") : fileIds[0] || "";

            console.log("📝 [V2Media] formData 업데이트:", {
              columnName: targetColumn,
              fileIds,
              formValue,
              isMultiple: config.multiple,
              isRecordMode: effectiveIsRecordMode,
            });
            // (fieldName: string, value: any) 형식으로 호출
            onFormDataChange(targetColumn, formValue);
          }

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

          toast.dismiss("file-upload");
          toast.success(`${newFiles.length}개 파일 업로드 완료`);
        } else {
          throw new Error(response.message || (response as any).error || "파일 업로드 실패");
        }
      } catch (error) {
        console.error("파일 업로드 오류:", error);
        setUploadStatus("error");
        toast.dismiss("file-upload");
        toast.error(`업로드 오류: ${error instanceof Error ? error.message : "알 수 없는 오류"}`);
      }
    },
    [
      config,
      uploadedFiles,
      onChange,
      id,
      getUniqueKey,
      recordId,
      isRecordMode,
      recordTableName,
      effectiveColumnName,
      tableName,
      onUpdate,
      onFormDataChange,
      user,
      columnName,
    ],
  );

  // 파일 뷰어 열기/닫기
  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: id,
              uniqueKey: uniqueKey,
              recordId: recordId,
              files: updatedFiles,
              fileCount: updatedFiles.length,
              timestamp: Date.now(),
              action: "delete",
            },
          });
          window.dispatchEvent(syncEvent);
        }

        if (onUpdate) {
          onUpdate({
            uploadedFiles: updatedFiles,
            lastFileUpdate: Date.now(),
          });
        }

        // onChange 콜백
        const fileIds = updatedFiles.map((f) => f.objid);
        const finalValue = config.multiple ? fileIds : fileIds[0] || "";
        const targetColumn = columnName || effectiveColumnName;

        console.log("🗑️ [V2Media] 파일 삭제 완료 - 값 전달:", {
          columnName: targetColumn,
          fileIds,
          finalValue,
        });

        if (onChange) {
          onChange(finalValue);
        }

        // 폼 데이터 업데이트 - 부모 컴포넌트 시그니처에 맞게 (fieldName, value) 형식
        if (onFormDataChange && targetColumn) {
          // 🔑 단일 파일: 첫 번째 objid만 전달 (DB 컬럼에 저장될 값)
          // 복수 파일: 콤마 구분 문자열로 전달
          const formValue = config.multiple ? fileIds.join(",") : fileIds[0] || "";

          console.log("🗑️ [V2Media] 삭제 후 formData 업데이트:", {
            columnName: targetColumn,
            fileIds,
            formValue,
          });
          // (fieldName: string, value: any) 형식으로 호출
          onFormDataChange(targetColumn, formValue);
        }

        toast.success(`${fileName} 삭제 완료`);
      } catch (error) {
        console.error("파일 삭제 오류:", error);
        toast.error("파일 삭제 실패");
      }
    },
    [
      uploadedFiles,
      onUpdate,
      id,
      isRecordMode,
      onFormDataChange,
      recordTableName,
      recordId,
      effectiveColumnName,
      getUniqueKey,
      onChange,
      config.multiple,
      columnName,
    ],
  );

  // 대표 이미지 로드
  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;
        }

        if (!file.objid || file.objid === "0" || file.objid === "") {
          setRepresentativeImageUrl(null);
          return;
        }

        const response = await apiClient.get(`/files/download/${file.objid}`, {
          params: { serverFilename: file.savedFileName },
          responseType: "blob",
        });

        const blob = new Blob([response.data]);
        const url = window.URL.createObjectURL(blob);

        if (representativeImageUrl) {
          window.URL.revokeObjectURL(representativeImageUrl);
        }

        setRepresentativeImageUrl(url);
      } catch (error) {
        console.error("대표 이미지 로드 실패:", error);
        setRepresentativeImageUrl(null);
      }
    },
    [representativeImageUrl],
  );

  // 대표 이미지 설정
  const handleSetRepresentative = useCallback(
    async (file: FileInfo) => {
      try {
        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);
      } catch (e) {
        console.error("대표 파일 설정 실패:", e);
      }
    },
    [uploadedFiles, loadRepresentativeImage],
  );

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

    return () => {
      if (representativeImageUrl) {
        window.URL.revokeObjectURL(representativeImageUrl);
      }
    };
  }, [uploadedFiles]);

  // 드래그 앤 드롭 핸들러
  const handleDragOver = useCallback(
    (e: React.DragEvent) => {
      e.preventDefault();
      e.stopPropagation();
      if (!readonly && !disabled) {
        setDragOver(true);
      }
    },
    [readonly, disabled],
  );

  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 (!readonly && !disabled) {
        const files = Array.from(e.dataTransfer.files);
        if (files.length > 0) {
          handleFileUpload(files);
        }
      }
    },
    [readonly, disabled, handleFileUpload],
  );

  // 파일 선택
  const handleFileSelect = useCallback(() => {
    if (fileInputRef.current) {
      fileInputRef.current.click();
    }
  }, []);

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

  // 파일 설정
  const fileConfig: FileUploadConfig = {
    accept: config.accept || "*/*",
    multiple: config.multiple || false,
    maxSize: config.maxSize || 10 * 1024 * 1024,
    disabled: disabled,
    readonly: readonly,
  };

  const showLabel = label && style?.labelDisplay !== false;
  const componentWidth = size?.width || style?.width;
  const componentHeight = size?.height || style?.height;

  return (
    <div ref={ref} id={id} className="flex w-full flex-col" style={{ width: componentWidth }}>
      {/* 라벨 */}
      {showLabel && (
        <Label
          htmlFor={id}
          style={{
            fontSize: style?.labelFontSize,
            color: getAdaptiveLabelColor(style?.labelColor),
            fontWeight: style?.labelFontWeight,
            marginBottom: style?.labelMarginBottom,
          }}
          className="shrink-0 text-sm font-medium"
        >
          {label}
          {required && <span className="ml-0.5 text-amber-500">*</span>}
        </Label>
      )}

      {/* 메인 컨테이너 */}
      <div className="min-h-0" style={{ height: componentHeight }}>
        <div
          className="border-border bg-card relative flex h-full w-full flex-col overflow-hidden rounded-lg border"
          onDragOver={handleDragOver}
          onDragLeave={handleDragLeave}
          onDrop={handleDrop}
        >
          {/* 숨겨진 파일 입력 */}
          <input
            ref={fileInputRef}
            type="file"
            multiple={config.multiple}
            accept={config.accept}
            onChange={handleInputChange}
            className="hidden"
            disabled={disabled || readonly}
          />

          {/* 파일이 있는 경우: 대표 이미지/파일 표시 */}
          {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="bg-muted/10 relative flex h-full w-full items-center justify-center">
                      <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="border-primary mb-2 h-8 w-8 animate-spin rounded-full border-b-2"></div>
                      <p className="text-muted-foreground text-sm">이미지 로딩 중...</p>
                    </div>
                  ) : (
                    <div className="flex h-full w-full flex-col items-center justify-center">
                      {getFileIcon(representativeFile.fileExt)}
                      <p className="mt-3 px-4 text-center text-sm font-medium">{representativeFile.realFileName}</p>
                      <Badge variant="secondary" className="mt-2">
                        대표 파일
                      </Badge>
                    </div>
                  )}

                  {/* 우측 하단 자세히보기 버튼 */}
                  <div className="absolute right-3 bottom-3">
                    <Button
                      variant="secondary"
                      size="sm"
                      className="h-8 px-3 text-xs shadow-md"
                      onClick={() => setIsFileManagerOpen(true)}
                    >
                      자세히보기 ({uploadedFiles.length})
                    </Button>
                  </div>
                </>
              );
            })()
          ) : (
            // 파일이 없는 경우: 업로드 안내
            <div
              className={cn(
                "text-muted-foreground flex h-full w-full cursor-pointer flex-col items-center justify-center",
                dragOver && "border-primary bg-primary/5",
                (disabled || readonly) && "cursor-not-allowed opacity-50",
              )}
              onClick={() => !disabled && !readonly && handleFileSelect()}
            >
              <Upload className="mb-3 h-12 w-12" />
              <p className="text-sm font-medium">파일을 드래그하거나 클릭하세요</p>
              <p className="text-muted-foreground mt-1 text-xs">
                최대 {formatFileSize(config.maxSize || 10 * 1024 * 1024)}
                {config.accept && config.accept !== "*/*" && ` (${config.accept})`}
              </p>
              <Button
                variant="outline"
                size="sm"
                className="mt-4 h-8 px-3 text-xs"
                onClick={(e) => {
                  e.stopPropagation();
                  setIsFileManagerOpen(true);
                }}
                disabled={disabled || readonly}
              >
                파일 관리
              </Button>
            </div>
          )}
        </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={fileConfig}
        isDesignMode={isDesignMode}
      />
    </div>
  );
});

V2Media.displayName = "V2Media";

export default V2Media;
