"use client";

import React, { useRef } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Badge } from "@/components/ui/badge";
import { Upload, File, X } from "lucide-react";
import { WebTypeComponentProps } from "@/lib/registry/types";
import { WidgetComponent, FileTypeConfig } from "@/types/screen";

export const FileWidget: React.FC<WebTypeComponentProps> = ({ component, value, onChange, readonly = false }) => {
  const widget = component as WidgetComponent;
  const { required, style } = widget;
  const config = widget.webTypeConfig as FileTypeConfig | undefined;
  const fileInputRef = useRef<HTMLInputElement>(null);

  // 파일 정보 파싱
  const parseFileValue = (val: any) => {
    if (!val) return [];

    if (typeof val === "string") {
      try {
        return JSON.parse(val);
      } catch {
        return [{ name: val, size: 0, url: val }];
      }
    }

    if (Array.isArray(val)) {
      return val;
    }

    return [];
  };

  const files = parseFileValue(value);

  // 파일 크기 포맷팅
  const formatFileSize = (bytes: number) => {
    if (bytes === 0) return "0 Bytes";
    const k = 1024;
    const sizes = ["Bytes", "KB", "MB", "GB"];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
  };

  // 파일 선택 처리
  const handleFileSelect = () => {
    if (readonly) return;
    fileInputRef.current?.click();
  };

  // 파일 업로드 처리
  const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const selectedFiles = Array.from(e.target.files || []);

    // 파일 개수 제한 검사
    if (config?.maxFiles && files.length + selectedFiles.length > config.maxFiles) {
      alert(`최대 ${config.maxFiles}개 파일까지 업로드 가능합니다.`);
      return;
    }

    // 파일 크기 검사
    if (config?.maxSize) {
      const oversizedFiles = selectedFiles.filter((file) => file.size > config.maxSize! * 1024 * 1024);
      if (oversizedFiles.length > 0) {
        alert(`파일 크기는 최대 ${config.maxSize}MB까지 가능합니다.`);
        return;
      }
    }

    // 파일 형식 검사
    if (config?.accept) {
      const acceptedTypes = config.accept.split(",").map((type) => type.trim());
      const invalidFiles = selectedFiles.filter((file) => {
        return !acceptedTypes.some((acceptType) => {
          if (acceptType.startsWith(".")) {
            return file.name.toLowerCase().endsWith(acceptType.toLowerCase());
          }
          return file.type.match(acceptType.replace("*", ".*"));
        });
      });

      if (invalidFiles.length > 0) {
        alert(`허용되지 않는 파일 형식입니다. 허용 형식: ${config.accept}`);
        return;
      }
    }

    // 새 파일 정보 생성
    const newFiles = selectedFiles.map((file) => ({
      name: file.name,
      size: file.size,
      type: file.type,
      url: URL.createObjectURL(file),
      file: file, // 실제 File 객체 (업로드용)
    }));

    const updatedFiles = config?.multiple !== false ? [...files, ...newFiles] : newFiles;
    onChange?.(JSON.stringify(updatedFiles));
  };

  // 파일 제거
  const removeFile = (index: number) => {
    if (readonly) return;

    const updatedFiles = files.filter((_, i) => i !== index);
    onChange?.(JSON.stringify(updatedFiles));
  };

  // 드래그 앤 드롭 처리
  const handleDragOver = (e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
  };

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

    if (readonly) return;

    const droppedFiles = Array.from(e.dataTransfer.files);

    // 파일 input change 이벤트와 같은 로직 적용
    const fakeEvent = {
      target: { files: droppedFiles },
    } as React.ChangeEvent<HTMLInputElement>;

    handleFileChange(fakeEvent);
  };

  return (
    <div className="h-full w-full space-y-2">
      {/* 파일 업로드 영역 */}
      <div
        className="group cursor-pointer rounded-lg border-2 border-dashed border-border bg-muted/20 p-6 text-center transition-colors duration-150 hover:border-primary/60 hover:bg-muted/30"
        onClick={handleFileSelect}
        onDragOver={handleDragOver}
        onDrop={handleDrop}
        style={style}
      >
        <Upload className="mx-auto mb-2 h-8 w-8 text-muted-foreground transition-colors duration-150 group-hover:text-primary" />
        <p className="mb-1 text-sm font-medium text-foreground">
          {readonly ? "파일 업로드 불가" : "파일을 선택하거나 드래그하여 업로드"}
        </p>
        <p className="text-xs text-muted-foreground">
          {config?.accept && `허용 형식: ${config.accept}`}
          {config?.maxSize && ` (최대 ${config.maxSize}MB)`}
        </p>
      </div>

      {/* 숨겨진 파일 input */}
      <Input
        ref={fileInputRef}
        type="file"
        className="hidden"
        multiple={config?.multiple !== false}
        accept={config?.accept}
        onChange={handleFileChange}
      />

      {/* 업로드된 파일 목록 */}
      {files.length > 0 && (
        <div className="space-y-2">
          <div className="flex items-center justify-between rounded-md border border-border bg-muted/20 px-3 py-2">
            <div className="flex items-center space-x-2">
              <File className="h-4 w-4 text-muted-foreground" />
              <span className="text-sm font-medium text-foreground">
                업로드된 파일 ({files.length}/{config?.maxFiles || "∞"})
              </span>
              <span className="text-xs text-muted-foreground">
                · 총 {formatFileSize(files.reduce((sum, file) => sum + file.size, 0))}
              </span>
            </div>
          </div>

          <div className="max-h-40 space-y-1.5 overflow-y-auto">
            {files.map((file, index) => (
              <div key={index} className="flex items-center justify-between rounded-md border border-border bg-background p-2.5 transition-colors duration-150 hover:bg-accent/30">
                <div className="flex flex-1 items-center space-x-2">
                  <div className="flex h-8 w-8 items-center justify-center rounded-md bg-muted">
                    <File className="h-4 w-4 text-muted-foreground" />
                  </div>
                  <div className="min-w-0 flex-1">
                    <p className="truncate text-sm font-medium text-foreground">
                      {file.name}
                    </p>
                    {file.size > 0 && (
                      <span className="text-xs text-muted-foreground">{formatFileSize(file.size)}</span>
                    )}
                  </div>
                </div>

                {!readonly && (
                  <Button
                    size="sm"
                    variant="ghost"
                    onClick={(e) => {
                      e.stopPropagation();
                      removeFile(index);
                    }}
                    className="h-7 w-7 text-destructive hover:bg-destructive/10 hover:text-destructive"
                  >
                    <X className="h-3.5 w-3.5" />
                  </Button>
                )}
              </div>
            ))}
          </div>
        </div>
      )}

      {/* 파일 개수 표시 */}
      {files.length > 0 && (
        <div className="flex items-center justify-between rounded-md border border-border bg-muted/20 px-3 py-2">
          <div className="flex items-center space-x-1.5">
            <File className="h-3.5 w-3.5 text-muted-foreground" />
            <span className="text-xs text-muted-foreground">
              파일명 클릭으로 미리보기 또는 파일 관리
            </span>
          </div>
          <div className="flex items-center space-x-1.5">
            <Badge variant="outline">{files.length}개 파일</Badge>
            {config?.maxFiles && (
              <Badge variant="outline" className="text-muted-foreground">
                최대 {config.maxFiles}개
              </Badge>
            )}
          </div>
        </div>
      )}

      {required && files.length === 0 && <div className="text-xs text-destructive">* 파일을 업로드해야 합니다</div>}
    </div>
  );
};

FileWidget.displayName = "FileWidget";


