"use client";

/**
 * ImageUpload — 공통 이미지 업로드 컴포넌트
 *
 * 기능:
 * - 이미지 파일 선택 (클릭 or 드래그)
 * - 미리보기 표시
 * - /api/files/upload API로 업로드
 * - 업로드 후 파일 objid 반환
 * - 기존 이미지 표시 (objid 또는 URL)
 *
 * 사용법:
 * <ImageUpload
 *   value={form.image_path}           // 기존 파일 objid 또는 URL
 *   onChange={(objid) => setForm(...)} // 업로드 완료 시 objid 반환
 *   tableName="equipment_mng"         // 연결 테이블
 *   recordId="xxx"                    // 연결 레코드 ID
 *   columnName="image_path"           // 연결 컬럼명
 * />
 */

import React, { useState, useRef, useCallback } from "react";
import { Button } from "@/components/ui/button";
import { Upload, X, Loader2, ImageIcon } from "lucide-react";
import { cn } from "@/lib/utils";
import { apiClient } from "@/lib/api/client";
import { toast } from "sonner";

interface ImageUploadProps {
  /** 현재 이미지 값 (파일 objid, URL, 또는 빈 문자열) */
  value?: string;
  /** 업로드 완료 시 콜백 (파일 objid) */
  onChange?: (value: string) => void;
  /** 연결할 테이블명 */
  tableName?: string;
  /** 연결할 레코드 ID */
  recordId?: string;
  /** 연결할 컬럼명 */
  columnName?: string;
  /** 높이 (기본 160px) */
  height?: string;
  /** 비활성화 */
  disabled?: boolean;
  className?: string;
}

export function ImageUpload({
  value, onChange, tableName, recordId, columnName,
  height = "h-40", disabled = false, className,
}: ImageUploadProps) {
  const [uploading, setUploading] = useState(false);
  const [dragOver, setDragOver] = useState(false);
  const fileRef = useRef<HTMLInputElement>(null);

  // 이미지 URL 결정 (Next.js 프록시 우회 — 바이너리 스트림 500 에러 방지)
  const apiBase = typeof window !== "undefined"
    ? (process.env.NEXT_PUBLIC_API_URL || "").replace(/\/api\/?$/, "")
    : "";
  const imageUrl = value
    ? (value.startsWith("http") || value.startsWith("/"))
      ? value
      : `${apiBase}/api/files/preview/${value}`
    : null;

  const handleUpload = useCallback(async (file: File) => {
    if (!file.type.startsWith("image/")) {
      toast.error("이미지 파일만 업로드 가능합니다.");
      return;
    }
    if (file.size > 10 * 1024 * 1024) {
      toast.error("파일 크기는 10MB 이하만 가능합니다.");
      return;
    }

    setUploading(true);
    try {
      const formData = new FormData();
      formData.append("files", file);
      formData.append("docType", "IMAGE");
      formData.append("docTypeName", "이미지");
      if (tableName) formData.append("linkedTable", tableName);
      if (recordId) formData.append("recordId", recordId);
      if (columnName) formData.append("columnName", columnName);
      if (tableName && recordId) {
        formData.append("autoLink", "true");
        if (columnName) formData.append("isVirtualFileColumn", "true");
      }

      const res = await apiClient.post("/files/upload", formData, {
        headers: { "Content-Type": "multipart/form-data" },
      });

      if (res.data?.success && (res.data.files?.length > 0 || res.data.data?.length > 0)) {
        const file = res.data.files?.[0] || res.data.data?.[0];
        const objid = file.objid;
        onChange?.(objid);
        toast.success("이미지가 업로드되었습니다.");
      } else {
        toast.error(res.data?.message || "업로드에 실패했습니다.");
      }
    } catch (err: any) {
      console.error("이미지 업로드 실패:", err);
      toast.error(err.response?.data?.message || "업로드에 실패했습니다.");
    } finally {
      setUploading(false);
    }
  }, [tableName, recordId, columnName, onChange]);

  const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (file) handleUpload(file);
    e.target.value = "";
  };

  const handleDrop = (e: React.DragEvent) => {
    e.preventDefault();
    setDragOver(false);
    const file = e.dataTransfer.files?.[0];
    if (file) handleUpload(file);
  };

  const handleRemove = () => {
    onChange?.("");
  };

  return (
    <div className={cn("relative", className)}>
      <div
        className={cn(
          "border-2 border-dashed rounded-lg flex flex-col items-center justify-center cursor-pointer transition-colors overflow-hidden",
          height,
          dragOver ? "border-primary bg-primary/5" : imageUrl ? "border-transparent" : "border-muted-foreground/25 hover:border-primary hover:bg-muted/50",
          disabled && "opacity-50 cursor-not-allowed",
        )}
        onClick={() => !disabled && !uploading && fileRef.current?.click()}
        onDragOver={(e) => { e.preventDefault(); if (!disabled) setDragOver(true); }}
        onDragLeave={() => setDragOver(false)}
        onDrop={!disabled ? handleDrop : undefined}
      >
        {uploading ? (
          <div className="flex flex-col items-center gap-2">
            <Loader2 className="h-8 w-8 animate-spin text-muted-foreground" />
            <span className="text-xs text-muted-foreground">업로드 중...</span>
          </div>
        ) : imageUrl ? (
          <img src={imageUrl} alt="이미지" className="w-full h-full object-contain" />
        ) : (
          <div className="flex flex-col items-center gap-2">
            <ImageIcon className="h-8 w-8 text-muted-foreground/50" />
            <span className="text-xs text-muted-foreground">클릭 또는 드래그하여 업로드</span>
          </div>
        )}
      </div>

      {/* 삭제 버튼 */}
      {imageUrl && !disabled && (
        <Button variant="destructive" size="sm" className="absolute top-1 right-1 h-6 w-6 p-0 rounded-full"
          onClick={(e) => { e.stopPropagation(); handleRemove(); }}>
          <X className="h-3 w-3" />
        </Button>
      )}

      <input ref={fileRef} type="file" accept="image/*" onChange={handleFileChange} className="hidden" />
    </div>
  );
}
