"use client";

/**
 * V2Input
 *
 * 통합 입력 컴포넌트
 * - text: 텍스트 입력
 * - number: 숫자 입력
 * - password: 비밀번호 입력
 * - slider: 슬라이더 입력
 * - color: 색상 선택
 * - button: 버튼 (입력이 아닌 액션)
 */

import React, { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from "react";
import { Input } from "@/components/ui/input";
import { Slider } from "@/components/ui/slider";
import { Label } from "@/components/ui/label";
import { cn } from "@/lib/utils";
import { V2InputProps, V2InputConfig, V2InputFormat } from "@/types/v2-components";
import { AutoGenerationUtils } from "@/lib/utils/autoGeneration";
import { AutoGenerationConfig } from "@/types/screen";
import { previewNumberingCode } from "@/lib/api/numberingRule";

// 형식별 입력 마스크 및 검증 패턴
const FORMAT_PATTERNS: Record<V2InputFormat, { pattern: RegExp; placeholder: string }> = {
  none: { pattern: /.*/, placeholder: "" },
  email: { pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/, placeholder: "example@email.com" },
  tel: { pattern: /^\d{2,3}-\d{3,4}-\d{4}$/, placeholder: "010-1234-5678" },
  url: { pattern: /^https?:\/\/.+/, placeholder: "https://example.com" },
  currency: { pattern: /^[\d,]+$/, placeholder: "1,000,000" },
  biz_no: { pattern: /^\d{3}-\d{2}-\d{5}$/, placeholder: "123-45-67890" },
};

// 통화 형식 변환
function formatCurrency(value: string | number): string {
  const num = typeof value === "string" ? parseFloat(value.replace(/,/g, "")) : value;
  if (isNaN(num)) return "";
  return num.toLocaleString("ko-KR");
}

// 사업자번호 형식 변환
function formatBizNo(value: string): string {
  const digits = value.replace(/\D/g, "");
  if (digits.length <= 3) return digits;
  if (digits.length <= 5) return `${digits.slice(0, 3)}-${digits.slice(3)}`;
  return `${digits.slice(0, 3)}-${digits.slice(3, 5)}-${digits.slice(5, 10)}`;
}

// 전화번호 형식 변환
function formatTel(value: string): string {
  const digits = value.replace(/\D/g, "");
  if (digits.length <= 3) return digits;
  if (digits.length <= 7) return `${digits.slice(0, 3)}-${digits.slice(3)}`;
  if (digits.length <= 11) return `${digits.slice(0, 3)}-${digits.slice(3, 7)}-${digits.slice(7)}`;
  return `${digits.slice(0, 3)}-${digits.slice(3, 7)}-${digits.slice(7, 11)}`;
}

/**
 * 텍스트 입력 컴포넌트
 */
const TextInput = forwardRef<
  HTMLInputElement,
  {
    value?: string | number;
    onChange?: (value: string) => void;
    format?: V2InputFormat;
    mask?: string;
    placeholder?: string;
    readonly?: boolean;
    disabled?: boolean;
    className?: string;
  }
>(({ value, onChange, format = "none", placeholder, readonly, disabled, className }, ref) => {
  // 형식에 따른 값 포맷팅
  const formatValue = useCallback(
    (val: string): string => {
      switch (format) {
        case "currency":
          return formatCurrency(val);
        case "biz_no":
          return formatBizNo(val);
        case "tel":
          return formatTel(val);
        default:
          return val;
      }
    },
    [format],
  );

  const handleChange = useCallback(
    (e: React.ChangeEvent<HTMLInputElement>) => {
      let newValue = e.target.value;

      // 형식에 따른 자동 포맷팅
      if (format === "currency") {
        // 숫자와 쉼표만 허용
        newValue = newValue.replace(/[^\d,]/g, "");
        newValue = formatCurrency(newValue);
      } else if (format === "biz_no") {
        newValue = formatBizNo(newValue);
      } else if (format === "tel") {
        newValue = formatTel(newValue);
      }

      onChange?.(newValue);
    },
    [format, onChange],
  );

  const displayValue = useMemo(() => {
    if (value === undefined || value === null) return "";
    return formatValue(String(value));
  }, [value, formatValue]);

  const inputPlaceholder = placeholder || FORMAT_PATTERNS[format].placeholder;

  return (
    <Input
      ref={ref}
      type="text"
      value={displayValue}
      onChange={handleChange}
      placeholder={inputPlaceholder}
      readOnly={readonly}
      disabled={disabled}
      className={cn("h-full w-full", className)}
    />
  );
});
TextInput.displayName = "TextInput";

/**
 * 숫자 입력 컴포넌트
 */
const NumberInput = forwardRef<
  HTMLInputElement,
  {
    value?: number;
    onChange?: (value: number | undefined) => void;
    min?: number;
    max?: number;
    step?: number;
    placeholder?: string;
    readonly?: boolean;
    disabled?: boolean;
    className?: string;
  }
>(({ value, onChange, min, max, step = 1, placeholder, readonly, disabled, className }, ref) => {
  const handleChange = useCallback(
    (e: React.ChangeEvent<HTMLInputElement>) => {
      const val = e.target.value;
      if (val === "") {
        onChange?.(undefined);
        return;
      }

      let num = parseFloat(val);

      // 범위 제한
      if (min !== undefined && num < min) num = min;
      if (max !== undefined && num > max) num = max;

      onChange?.(num);
    },
    [min, max, onChange],
  );

  return (
    <Input
      ref={ref}
      type="number"
      value={value ?? ""}
      onChange={handleChange}
      min={min}
      max={max}
      step={step}
      placeholder={placeholder || "숫자 입력"}
      readOnly={readonly}
      disabled={disabled}
      className={cn("h-full w-full", className)}
    />
  );
});
NumberInput.displayName = "NumberInput";

/**
 * 비밀번호 입력 컴포넌트
 */
const PasswordInput = forwardRef<
  HTMLInputElement,
  {
    value?: string;
    onChange?: (value: string) => void;
    placeholder?: string;
    readonly?: boolean;
    disabled?: boolean;
    className?: string;
  }
>(({ value, onChange, placeholder, readonly, disabled, className }, ref) => {
  const [showPassword, setShowPassword] = useState(false);

  return (
    <div className="relative">
      <Input
        ref={ref}
        type={showPassword ? "text" : "password"}
        value={value ?? ""}
        onChange={(e) => onChange?.(e.target.value)}
        placeholder={placeholder || "비밀번호 입력"}
        readOnly={readonly}
        disabled={disabled}
        className={cn("h-full w-full pr-10", className)}
      />
      <button
        type="button"
        onClick={() => setShowPassword(!showPassword)}
        className="text-muted-foreground hover:text-foreground absolute top-1/2 right-2 -translate-y-1/2 text-xs"
      >
        {showPassword ? "숨김" : "보기"}
      </button>
    </div>
  );
});
PasswordInput.displayName = "PasswordInput";

/**
 * 슬라이더 입력 컴포넌트
 */
const SliderInput = forwardRef<
  HTMLDivElement,
  {
    value?: number;
    onChange?: (value: number) => void;
    min?: number;
    max?: number;
    step?: number;
    disabled?: boolean;
    className?: string;
  }
>(({ value, onChange, min = 0, max = 100, step = 1, disabled, className }, ref) => {
  return (
    <div ref={ref} className={cn("flex items-center gap-4", className)}>
      <Slider
        value={[value ?? min]}
        onValueChange={(values) => onChange?.(values[0])}
        min={min}
        max={max}
        step={step}
        disabled={disabled}
        className="flex-1"
      />
      <span className="w-12 text-right text-sm font-medium">{value ?? min}</span>
    </div>
  );
});
SliderInput.displayName = "SliderInput";

/**
 * 색상 선택 컴포넌트
 */
const ColorInput = forwardRef<
  HTMLInputElement,
  {
    value?: string;
    onChange?: (value: string) => void;
    disabled?: boolean;
    className?: string;
  }
>(({ value, onChange, disabled, className }, ref) => {
  return (
    <div className={cn("flex items-center gap-2", className)}>
      <Input
        ref={ref}
        type="color"
        value={value || "#000000"}
        onChange={(e) => onChange?.(e.target.value)}
        disabled={disabled}
        className="h-full w-12 cursor-pointer p-1"
      />
      <Input
        type="text"
        value={value || "#000000"}
        onChange={(e) => onChange?.(e.target.value)}
        disabled={disabled}
        className="h-full flex-1 uppercase"
        maxLength={7}
      />
    </div>
  );
});
ColorInput.displayName = "ColorInput";

/**
 * 여러 줄 텍스트 입력 컴포넌트
 */
const TextareaInput = forwardRef<
  HTMLTextAreaElement,
  {
    value?: string;
    onChange?: (value: string) => void;
    placeholder?: string;
    rows?: number;
    readonly?: boolean;
    disabled?: boolean;
    className?: string;
  }
>(({ value = "", onChange, placeholder, rows = 3, readonly, disabled, className }, ref) => {
  return (
    <textarea
      ref={ref}
      value={value}
      onChange={(e) => onChange?.(e.target.value)}
      placeholder={placeholder}
      rows={rows}
      readOnly={readonly}
      disabled={disabled}
      className={cn(
        "border-input placeholder:text-muted-foreground focus-visible:ring-ring flex min-h-[60px] w-full rounded-md border bg-transparent px-3 py-2 text-sm shadow-sm focus-visible:ring-1 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50",
        className,
      )}
    />
  );
});
TextareaInput.displayName = "TextareaInput";

/**
 * 메인 V2Input 컴포넌트
 */
export const V2Input = forwardRef<HTMLDivElement, V2InputProps>((props, ref) => {
  const { id, label, required, readonly, disabled, style, size, config: configProp, value, onChange } = props;

  // formData 추출 (채번규칙 날짜 컬럼 기준 생성 시 사용)
  const formData = (props as any).formData || {};
  const columnName = (props as any).columnName;
  // onFormDataChange 추출 (채번 규칙 ID를 formData에 저장하기 위함)
  const onFormDataChange = (props as any).onFormDataChange;

  // config가 없으면 기본값 사용
  const config = (configProp || { type: "text" }) as V2InputConfig & {
    inputType?: string;
    rows?: number;
    autoGeneration?: AutoGenerationConfig;
  };

  // 자동생성 설정 추출
  const autoGeneration: AutoGenerationConfig = (props as any).autoGeneration ||
    (config as any).autoGeneration || {
      type: "none",
      enabled: false,
    };

  // 자동생성 상태 관리
  const [autoGeneratedValue, setAutoGeneratedValue] = useState<string | null>(null);
  const isGeneratingRef = useRef(false);
  const hasGeneratedRef = useRef(false);
  const lastFormDataRef = useRef<string>(""); // 마지막 formData 추적 (채번 규칙용)

  // 채번 타입 자동생성 상태
  const [isGeneratingNumbering, setIsGeneratingNumbering] = useState(false);
  const hasGeneratedNumberingRef = useRef(false);

  // tableName 추출 (props에서 전달받거나 config에서)
  const tableName = (props as any).tableName || (config as any).tableName;

  // 수정 모드 여부 확인
  const originalData = (props as any).originalData || (props as any)._originalData;
  const isEditMode = originalData && Object.keys(originalData).length > 0;

  // 채번 규칙인 경우 formData 변경 감지 (자기 자신 필드 제외)
  const formDataForNumbering = useMemo(() => {
    if (autoGeneration.type !== "numbering_rule") return "";
    // 자기 자신의 값은 제외 (무한 루프 방지)
    const { [columnName]: _, ...rest } = formData;
    return JSON.stringify(rest);
  }, [autoGeneration.type, formData, columnName]);

  // 자동생성 로직
  useEffect(() => {
    const generateValue = async () => {
      // 자동생성 비활성화 또는 생성 중
      if (!autoGeneration.enabled || isGeneratingRef.current) {
        return;
      }

      // 수정 모드에서는 자동생성 안함
      if (isEditMode) {
        return;
      }

      // 채번 규칙인 경우: formData가 변경되었는지 확인
      const isNumberingRule = autoGeneration.type === "numbering_rule";
      const formDataChanged =
        isNumberingRule && formDataForNumbering !== lastFormDataRef.current && lastFormDataRef.current !== "";

      // 이미 생성되었고, formData 변경이 아닌 경우 스킵
      if (hasGeneratedRef.current && !formDataChanged) {
        return;
      }

      // 첫 생성 시: 값이 이미 있으면 스킵 (formData 변경 시에는 강제 재생성)
      if (!formDataChanged && value !== undefined && value !== null && value !== "") {
        return;
      }

      isGeneratingRef.current = true;

      try {
        // formData를 전달하여 날짜 컬럼 기준 생성 지원
        const generatedValue = await AutoGenerationUtils.generateValue(autoGeneration, columnName, formData);

        if (generatedValue !== null && generatedValue !== undefined) {
          setAutoGeneratedValue(generatedValue);
          onChange?.(generatedValue);
          hasGeneratedRef.current = true;

          // formData 기록
          if (isNumberingRule) {
            lastFormDataRef.current = formDataForNumbering;
          }
        }
      } catch (error) {
        console.error("자동생성 실패:", error);
      } finally {
        isGeneratingRef.current = false;
      }
    };

    generateValue();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [autoGeneration.enabled, autoGeneration.type, isEditMode, formDataForNumbering]);

  // 채번 규칙 ID 캐싱
  const numberingRuleIdRef = useRef<string | null>(null);
  const lastCategoryValuesRef = useRef<string>("");
  // 사용자가 직접 입력 중인지 추적 (재생성 방지)
  const userEditedNumberingRef = useRef<boolean>(false);
  // 원래 수동 입력 부분이 있었는지 추적 (____가 있었으면 계속 편집 가능)
  const hadManualPartRef = useRef<boolean>(false);
  // 채번 템플릿 저장 (____가 포함된 원본 형태)
  const numberingTemplateRef = useRef<string>("");
  // 사용자가 수동 입력한 값 저장
  const [manualInputValue, setManualInputValue] = useState<string>("");

  // formData에서 카테고리 관련 값 추출 (채번 파트에서 카테고리 사용 시)
  // 채번 필드 자체의 값은 제외해야 함 (무한 루프 방지)
  const categoryValuesForNumbering = useMemo(() => {
    const inputType = config.inputType || config.type || "text";
    if (inputType !== "numbering") return "";
    // formData에서 category 타입 필드 값들을 추출 (채번 필드 자체는 제외)
    const categoryFields: Record<string, string> = {};
    for (const [key, val] of Object.entries(formData)) {
      // 현재 채번 필드(columnName)는 제외
      if (key === columnName) continue;
      if (typeof val === "string" && val) {
        categoryFields[key] = val;
      }
    }
    return JSON.stringify(categoryFields);
  }, [config.inputType, config.type, formData, columnName]);

  // 채번 타입 자동생성 로직 (테이블 관리에서 설정된 numberingRuleId 사용)
  useEffect(() => {
    const generateNumberingCode = async () => {
      const inputType = config.inputType || config.type || "text";

      // numbering 타입이 아니면 스킵
      if (inputType !== "numbering") {
        return;
      }

      // 수정 모드에서는 자동생성 안함
      if (isEditMode) {
        return;
      }

      // 생성 중이면 스킵
      if (isGeneratingNumbering) {
        return;
      }

      // 사용자가 직접 편집한 경우 재생성 안함 (단, 카테고리 변경 시에는 재생성)
      const categoryChanged = categoryValuesForNumbering !== lastCategoryValuesRef.current;
      if (userEditedNumberingRef.current && !categoryChanged) {
        return;
      }
      
      // 이미 생성되었고 카테고리 값이 변경되지 않았으면 스킵
      if (hasGeneratedNumberingRef.current && !categoryChanged) {
        return;
      }

      // 첫 생성 시: 값이 이미 있고 카테고리 변경이 아니면 스킵
      if (!categoryChanged && value !== undefined && value !== null && value !== "") {
        return;
      }

      // tableName과 columnName이 필요
      if (!tableName || !columnName) {
        console.warn("채번 타입: tableName 또는 columnName이 없습니다", { tableName, columnName });
        return;
      }

      setIsGeneratingNumbering(true);

      try {
        // 채번 규칙 ID 캐싱 (한 번만 조회)
        if (!numberingRuleIdRef.current) {
          const { getTableColumns } = await import("@/lib/api/tableManagement");
          const columnsResponse = await getTableColumns(tableName);

          if (!columnsResponse.success || !columnsResponse.data) {
            console.warn("테이블 컬럼 정보 조회 실패:", columnsResponse);
            return;
          }

          const columns = columnsResponse.data.columns || columnsResponse.data;
          const targetColumn = columns.find((col: { columnName: string }) => col.columnName === columnName);

          if (!targetColumn) {
            console.warn("컬럼 정보를 찾을 수 없습니다:", columnName);
            return;
          }

          // detailSettings에서 numberingRuleId 추출
          if (targetColumn.detailSettings && typeof targetColumn.detailSettings === "string") {
            try {
              const parsed = JSON.parse(targetColumn.detailSettings);
              numberingRuleIdRef.current = parsed.numberingRuleId || null;
              
              // 🆕 채번 규칙 ID를 formData에 저장 (저장 시 allocateCode 호출을 위해)
              if (parsed.numberingRuleId && onFormDataChange && columnName) {
                onFormDataChange(`${columnName}_numberingRuleId`, parsed.numberingRuleId);
                console.log("🔧 채번 규칙 ID를 formData에 저장:", {
                  key: `${columnName}_numberingRuleId`,
                  value: parsed.numberingRuleId,
                });
              }
            } catch {
              // JSON 파싱 실패
            }
          }
        }

        const numberingRuleId = numberingRuleIdRef.current;

        if (!numberingRuleId) {
          console.warn("채번 규칙 ID가 설정되지 않았습니다. 테이블 관리에서 설정하세요.", { tableName, columnName });
          return;
        }

        // 채번 코드 생성 (formData 전달하여 카테고리 값 기반 생성)
        const previewResponse = await previewNumberingCode(numberingRuleId, formData);

        if (previewResponse.success && previewResponse.data?.generatedCode) {
          const generatedCode = previewResponse.data.generatedCode;
          hasGeneratedNumberingRef.current = true;
          lastCategoryValuesRef.current = categoryValuesForNumbering;
          
          // 수동 입력 부분이 있는 경우
          if (generatedCode.includes("____")) {
            hadManualPartRef.current = true;
            const oldTemplate = numberingTemplateRef.current;
            numberingTemplateRef.current = generatedCode;
            
            // 카테고리 변경으로 템플릿이 바뀌었을 때 기존 사용자 입력값 유지
            if (oldTemplate && oldTemplate !== generatedCode) {
              // 템플릿이 변경되었지만 사용자 입력값은 유지
              const templateParts = generatedCode.split("____");
              const templatePrefix = templateParts[0] || "";
              const templateSuffix = templateParts.length > 1 ? templateParts.slice(1).join("") : "";
              
              // 기존 manualInputValue를 사용하여 새 값 조합 (상태는 유지)
              // 참고: setManualInputValue는 호출하지 않음 (기존 값 유지)
              const finalValue = templatePrefix + (userEditedNumberingRef.current ? "" : "") + templateSuffix;
              
              // 사용자가 입력한 적이 없으면 템플릿 그대로
              if (!userEditedNumberingRef.current) {
                setAutoGeneratedValue(generatedCode);
                onChange?.(generatedCode);
              }
              // 사용자가 입력한 적이 있으면 입력값 유지하며 템플릿만 변경
              // (manualInputValue 상태는 유지되므로 UI에서 자동 반영)
            } else {
              // 첫 생성
              setAutoGeneratedValue(generatedCode);
              onChange?.(generatedCode);
              userEditedNumberingRef.current = false;
            }
          } else {
            // 수동 입력 부분 없음
            setAutoGeneratedValue(generatedCode);
            onChange?.(generatedCode);
            userEditedNumberingRef.current = false;
          }
          
          // 채번 코드 생성 성공
        } else {
          console.warn("채번 코드 생성 실패:", previewResponse);
        }
      } catch (error) {
        console.error("채번 자동생성 오류:", error);
      } finally {
        setIsGeneratingNumbering(false);
      }
    };

    generateNumberingCode();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [tableName, columnName, isEditMode, categoryValuesForNumbering]);

  // 실제 표시할 값 (자동생성 값 또는 props value)
  const displayValue = autoGeneratedValue ?? value;

  // 조건부 렌더링 체크
  // TODO: conditional 처리 로직 추가

  // 타입별 입력 컴포넌트 렌더링
  const renderInput = () => {
    const inputType = config.inputType || config.type || "text";
    switch (inputType) {
      case "text":
        return (
          <TextInput
            value={displayValue}
            onChange={(v) => {
              setAutoGeneratedValue(null); // 사용자 입력 시 자동생성 값 초기화
              onChange?.(v);
            }}
            format={config.format}
            mask={config.mask}
            placeholder={config.placeholder}
            readonly={readonly || (autoGeneration.enabled && hasGeneratedRef.current)}
            disabled={disabled}
          />
        );

      case "number":
        return (
          <NumberInput
            value={typeof displayValue === "number" ? displayValue : undefined}
            onChange={(v) => {
              setAutoGeneratedValue(null);
              onChange?.(v ?? 0);
            }}
            min={config.min}
            max={config.max}
            step={config.step}
            placeholder={config.placeholder}
            readonly={readonly}
            disabled={disabled}
          />
        );

      case "password":
        return (
          <PasswordInput
            value={typeof displayValue === "string" ? displayValue : ""}
            onChange={(v) => {
              setAutoGeneratedValue(null);
              onChange?.(v);
            }}
            placeholder={config.placeholder}
            readonly={readonly}
            disabled={disabled}
          />
        );

      case "slider":
        return (
          <SliderInput
            value={typeof displayValue === "number" ? displayValue : (config.min ?? 0)}
            onChange={(v) => {
              setAutoGeneratedValue(null);
              onChange?.(v);
            }}
            min={config.min}
            max={config.max}
            step={config.step}
            disabled={disabled}
          />
        );

      case "color":
        return (
          <ColorInput
            value={typeof displayValue === "string" ? displayValue : "#000000"}
            onChange={(v) => {
              setAutoGeneratedValue(null);
              onChange?.(v);
            }}
            disabled={disabled}
          />
        );

      case "textarea":
        return (
          <TextareaInput
            value={displayValue as string}
            onChange={(v) => {
              setAutoGeneratedValue(null);
              onChange?.(v);
            }}
            placeholder={config.placeholder}
            rows={config.rows}
            readonly={readonly}
            disabled={disabled}
          />
        );

      case "numbering": {
        // 채번 타입: ____ 부분만 편집 가능하게 처리
        const template = numberingTemplateRef.current;
        const canEdit = hadManualPartRef.current && template;
        
        // 채번 필드 렌더링
        
        // 템플릿이 없으면 읽기 전용 (아직 생성 전이거나 수동 입력 부분 없음)
        if (!canEdit) {
          return (
            <TextInput
              value={displayValue || ""}
              onChange={() => {}}
              placeholder={isGeneratingNumbering ? "생성 중..." : "자동 생성됩니다"}
              readonly={true}
              disabled={disabled || isGeneratingNumbering}
            />
          );
        }
        
        // 템플릿에서 prefix와 suffix 추출
        const templateParts = template.split("____");
        const templatePrefix = templateParts[0] || "";
        const templateSuffix = templateParts.length > 1 ? templateParts.slice(1).join("") : "";
        
        return (
          <div className="flex h-full items-center rounded-md border">
            {/* 고정 접두어 */}
            {templatePrefix && (
              <span className="text-muted-foreground bg-muted flex h-full items-center px-2 text-sm">
                {templatePrefix}
              </span>
            )}
            {/* 편집 가능한 부분 */}
            <input
              type="text"
              value={manualInputValue}
              onChange={(e) => {
                const newUserInput = e.target.value;
                setManualInputValue(newUserInput);
                
                // 전체 값 조합
                const newValue = templatePrefix + newUserInput + templateSuffix;
                userEditedNumberingRef.current = true;
                setAutoGeneratedValue(newValue);
                onChange?.(newValue);
              }}
              placeholder="입력"
              className="h-full min-w-[60px] flex-1 bg-transparent px-2 text-sm focus-visible:outline-none"
              disabled={disabled || isGeneratingNumbering}
            />
            {/* 고정 접미어 */}
            {templateSuffix && (
              <span className="text-muted-foreground bg-muted flex h-full items-center px-2 text-sm">
                {templateSuffix}
              </span>
            )}
          </div>
        );
      }

      default:
        return (
          <TextInput
            value={displayValue}
            onChange={(v) => {
              setAutoGeneratedValue(null);
              onChange?.(v);
            }}
            placeholder={config.placeholder}
            readonly={readonly}
            disabled={disabled}
          />
        );
    }
  };

  // 라벨이 표시될 때 입력 필드가 차지할 높이 계산
  const showLabel = label && style?.labelDisplay !== false;
  // size에서 우선 가져오고, 없으면 style에서 가져옴
  const componentWidth = size?.width || style?.width;
  const componentHeight = size?.height || style?.height;

  return (
    <div
      ref={ref}
      id={id}
      className="flex flex-col"
      style={{
        width: componentWidth,
        // 🔧 높이는 컨테이너가 아닌 입력 필드에만 적용 (라벨 높이는 별도)
      }}
    >
      {showLabel && (
        <Label
          htmlFor={id}
          style={{
            fontSize: style?.labelFontSize,
            color: style?.labelColor,
            fontWeight: style?.labelFontWeight,
            marginBottom: style?.labelMarginBottom,
          }}
          className="flex-shrink-0 text-sm font-medium"
        >
          {label}
          {required && <span className="ml-0.5 text-orange-500">*</span>}
        </Label>
      )}
      <div 
        className="min-h-0"
        style={{
          height: componentHeight,
        }}
      >
        {renderInput()}
      </div>
    </div>
  );
});

V2Input.displayName = "V2Input";

export default V2Input;
