import { apiClient, API_BASE_URL } from "./client";

export interface FileInfo {
  id: string;
  name: string;
  size: number;
  type: string;
  extension: string;
  uploadedAt: string;
  lastModified: string;
  serverPath?: string;
  serverFilename?: string;
}

export interface FileUploadResponse {
  success: boolean;
  message: string;
  files: FileInfo[];
  data?: FileInfo[];
}

export interface FileDownloadParams {
  fileId: string;
  serverFilename: string;
  originalName: string;
}

/**
 * 파일 업로드
 */
export const uploadFiles = async (params: {
  files: FileList | File[];
  tableName?: string;
  fieldName?: string;
  recordId?: string | number;
  docType?: string;
  docTypeName?: string;
  targetObjid?: string;
  parentTargetObjid?: string;
  linkedTable?: string;
  linkedField?: string;
  autoLink?: boolean;
  columnName?: string;
  isVirtualFileColumn?: boolean;
  companyCode?: string; // 🔒 멀티테넌시: 회사 코드
  isRecordMode?: boolean; // 🆕 레코드 모드 플래그
}): Promise<FileUploadResponse> => {
  const formData = new FormData();

  // 파일 추가
  const fileArray = Array.isArray(params.files) ? params.files : Array.from(params.files);
  fileArray.forEach((file) => {
    formData.append("files", file);
  });

  // 추가 파라미터들 추가
  if (params.tableName) formData.append("tableName", params.tableName);
  if (params.fieldName) formData.append("fieldName", params.fieldName);
  if (params.recordId) formData.append("recordId", String(params.recordId));
  if (params.docType) formData.append("docType", params.docType);
  if (params.docTypeName) formData.append("docTypeName", params.docTypeName);
  if (params.targetObjid) formData.append("targetObjid", params.targetObjid);
  if (params.parentTargetObjid) formData.append("parentTargetObjid", params.parentTargetObjid);
  if (params.linkedTable) formData.append("linkedTable", params.linkedTable);
  if (params.linkedField) formData.append("linkedField", params.linkedField);
  if (params.autoLink !== undefined) formData.append("autoLink", params.autoLink.toString());
  if (params.columnName) formData.append("columnName", params.columnName);
  if (params.isVirtualFileColumn !== undefined) formData.append("isVirtualFileColumn", params.isVirtualFileColumn.toString());
  if (params.companyCode) formData.append("companyCode", params.companyCode); // 🔒 멀티테넌시
  // 🆕 레코드 모드 플래그 추가 (백엔드에서 attachments 컬럼 자동 업데이트용)
  if (params.isRecordMode !== undefined) formData.append("isRecordMode", params.isRecordMode.toString());

  const response = await apiClient.post("/files/upload", formData, {
    headers: {
      "Content-Type": undefined, // axios가 자동으로 multipart/form-data를 설정하도록
    },
  });

  return response.data;
};

/**
 * 파일 다운로드
 */
export const downloadFile = async (params: FileDownloadParams): Promise<void> => {
  try {
    console.log("📥 downloadFile 호출:", params);

    const response = await apiClient.get(`/files/download/${params.fileId}`, {
      params: {
        serverFilename: params.serverFilename,
        originalName: params.originalName,
      },
      responseType: "blob", // 파일 다운로드를 위해 blob 타입으로 설정
    });

    console.log("📥 다운로드 응답:", response);

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

    // 다운로드 링크 생성 및 클릭
    const link = document.createElement("a");
    link.href = url;
    link.download = params.originalName;
    document.body.appendChild(link);
    link.click();

    // 정리
    document.body.removeChild(link);
    window.URL.revokeObjectURL(url);
  } catch (error) {
    console.error("파일 다운로드 오류:", error);
    throw new Error("파일 다운로드에 실패했습니다.");
  }
};

/**
 * 파일 삭제
 */
export const deleteFile = async (fileId: string, serverFilename: string): Promise<void> => {
  const response = await apiClient.delete(`/files/${fileId}`, {
    data: { serverFilename },
  });

  if (!response.data.success) {
    throw new Error(response.data.message || "파일 삭제에 실패했습니다.");
  }
};

/**
 * 파일 정보 조회
 */
export const getFileInfo = async (fileId: string, serverFilename: string) => {
  const response = await apiClient.get(`/files/info/${fileId}`, {
    params: { serverFilename },
  });

  return response.data;
};

/**
 * 컴포넌트의 템플릿 파일과 데이터 파일을 모두 조회
 */
export const getComponentFiles = async (params: {
  screenId: number;
  componentId: string;
  tableName?: string;
  recordId?: string;
  columnName?: string;
}): Promise<{
  success: boolean;
  templateFiles: FileInfo[];
  dataFiles: FileInfo[];
  totalFiles: FileInfo[];
}> => {
  const response = await apiClient.get('/files/component-files', {
    params,
  });

  return response.data;
};

/**
 * 파일 업로드 및 JSON 데이터 생성
 * InteractiveScreenViewer에서 사용할 통합 함수
 */
export const uploadFilesAndCreateData = async (files: FileList) => {
  try {
    // 1. 파일 업로드
    const uploadResponse = await uploadFiles(files);

    if (!uploadResponse.success) {
      throw new Error(uploadResponse.message);
    }

    // 2. JSON 데이터 구조 생성
    const fileData = {
      files: uploadResponse.files.map((file) => ({
        id: file.id,
        name: file.name,
        size: file.size,
        type: file.type,
        extension: file.extension,
        uploadedAt: file.uploadedAt,
        lastModified: file.lastModified,
        serverFilename: file.serverFilename, // 다운로드에 필요
      })),
      totalCount: uploadResponse.files.length,
      totalSize: uploadResponse.files.reduce((sum, file) => sum + file.size, 0),
      lastModified: new Date().toISOString(),
    };

    return {
      success: true,
      data: fileData,
      message: uploadResponse.message,
    };
  } catch (error) {
    console.error("파일 업로드 및 데이터 생성 오류:", error);
    throw error;
  }
};

/**
 * 테이블 연결된 파일 조회
 */
export const getLinkedFiles = async (
  tableName: string,
  recordId: string,
): Promise<{
  success: boolean;
  files: any[];
  totalCount: number;
  targetObjid: string;
}> => {
  try {
    console.log("📎 연결된 파일 조회:", { tableName, recordId });

    const response = await apiClient.get(`/files/linked/${tableName}/${recordId}`);

    console.log("✅ 연결된 파일 조회 성공:", response.data);

    return response.data;
  } catch (error) {
    console.error("연결된 파일 조회 오류:", error);
    throw new Error("연결된 파일 조회에 실패했습니다.");
  }
};

/**
 * 파일 미리보기 URL 생성
 * 🔑 상대 경로(/api) 대신 API_BASE_URL 사용 (Docker 환경에서 Next.js rewrite 의존 방지)
 */
export const getFilePreviewUrl = (fileId: string): string => {
  return `${API_BASE_URL}/files/preview/${fileId}`;
};

/**
 * 파일 다운로드 URL 생성
 */
export const getFileDownloadUrl = (fileId: string): string => {
  const baseUrl = process.env.NEXT_PUBLIC_API_URL || "/api";
  return `${baseUrl}/files/download/${fileId}`;
};

/**
 * 직접 파일 경로 URL 생성 (정적 파일 서빙)
 * 주의: 모듈 로드 시점이 아닌 런타임에 hostname을 확인해야 SSR 문제 방지
 */
export const getDirectFileUrl = (filePath: string): string => {
  // 빈 값 체크
  if (!filePath) return "";
  
  // 이미 전체 URL인 경우 그대로 반환
  if (filePath.startsWith("http://") || filePath.startsWith("https://")) {
    return filePath;
  }
  
  // 런타임에 현재 hostname 확인 (SSR 시점이 아닌 클라이언트에서 실행될 때)
  if (typeof window !== "undefined") {
    const currentHost = window.location.hostname;
    
    // 프로덕션 환경: v1.vexplor.com → api.vexplor.com
    if (currentHost === "v1.vexplor.com") {
      return `https://api.vexplor.com${filePath}`;
    }
    
    // 로컬 개발환경
    if (currentHost === "localhost" || currentHost === "127.0.0.1") {
      return `http://localhost:8080${filePath}`;
    }
  }
  
  // SSR 또는 알 수 없는 환경에서는 환경변수 사용 (fallback)
  // 주의: 프로덕션 URL이 https://api.vexplor.com/api 이므로
  // 단순 .replace("/api", "")는 호스트명의 /api까지 제거하는 버그 발생
  const baseUrl = process.env.NEXT_PUBLIC_API_URL?.replace(/\/api$/, "") || "";
  if (baseUrl.startsWith("http://") || baseUrl.startsWith("https://")) {
    return `${baseUrl}${filePath}`;
  }
  
  // 최종 fallback
  return filePath;
};

/**
 * 대표 파일 설정
 */
export const setRepresentativeFile = async (objid: string): Promise<{
  success: boolean;
  message: string;
}> => {
  try {
    const response = await apiClient.put(`/files/representative/${objid}`);
    return response.data;
  } catch (error) {
    console.error("대표 파일 설정 오류:", error);
    throw new Error("대표 파일 설정에 실패했습니다.");
  }
};

/**
 * 파일 정보 조회 (메타데이터만, objid로 조회)
 */
export const getFileInfoByObjid = async (objid: string): Promise<{
  success: boolean;
  data?: {
    objid: string;
    realFileName: string;
    fileSize: number;
    fileExt: string;
    filePath: string;
    regdate: string;
    isRepresentative: boolean;
  };
  message?: string;
}> => {
  try {
    const response = await apiClient.get(`/files/info/${objid}`);
    return response.data;
  } catch (error) {
    console.error("파일 정보 조회 오류:", error);
    return {
      success: false,
      message: "파일 정보 조회에 실패했습니다.",
    };
  }
};
