import React, { useState, useEffect, useRef, useMemo } from "react";
import { filterDOMProps } from "@/lib/utils/domPropsFilter";
import { useCodeOptions, useTableCodeCategory, useTableColumnHierarchy } from "@/hooks/queries/useCodes";
import { cn } from "@/lib/registry/components/common/inputStyles";
import { useScreenContextOptional } from "@/contexts/ScreenContext";
import type { DataProvidable } from "@/types/data-transfer";
import { useCascadingDropdown } from "@/hooks/useCascadingDropdown";
import { HierarchicalCodeSelect } from "@/components/common/HierarchicalCodeSelect";

interface Option {
  value: string;
  label: string;
}

export interface SelectBasicComponentProps {
  component: any;
  componentConfig: any;
  screenId?: number;
  onUpdate?: (field: string, value: any) => void;
  isSelected?: boolean;
  isDesignMode?: boolean;
  isInteractive?: boolean;
  onFormDataChange?: (fieldName: string, value: any) => void;
  className?: string;
  style?: React.CSSProperties;
  onClick?: () => void;
  onDragStart?: () => void;
  onDragEnd?: () => void;
  value?: any; // 외부에서 전달받는 값
  menuObjid?: number; // 🆕 메뉴 OBJID (코드 스코프용)
  formData?: Record<string, any>; // 🆕 폼 데이터 (연쇄 드롭다운용)
  [key: string]: any;
}

// ✅ React Query를 사용하여 중복 요청 방지 및 자동 캐싱 처리
// - 동일한 queryKey에 대해서는 자동으로 중복 요청 제거
// - 10분 staleTime으로 적절한 캐시 관리
// - 30분 gcTime으로 메모리 효율성 확보

const SelectBasicComponent: React.FC<SelectBasicComponentProps> = ({
  component,
  componentConfig,
  screenId,
  onUpdate,
  isSelected = false,
  isDesignMode = false,
  isInteractive = false,
  onFormDataChange,
  className,
  style,
  onClick,
  onDragStart,
  onDragEnd,
  value: externalValue, // 명시적으로 value prop 받기
  menuObjid, // 🆕 메뉴 OBJID
  formData, // 🆕 폼 데이터 (연쇄 드롭다운용)
  ...props
}) => {
  // 🆕 읽기전용/비활성화 상태 확인
  const isReadonly = (component as any).readonly || (props as any).readonly || componentConfig?.readonly || false;
  const isDisabled = (component as any).disabled || (props as any).disabled || componentConfig?.disabled || false;
  const isFieldDisabledBase = isDesignMode || isReadonly || isDisabled;
  // 화면 컨텍스트 (데이터 제공자로 등록)
  const screenContext = useScreenContextOptional();

  const [isOpen, setIsOpen] = useState(false);

  // webTypeConfig 또는 componentConfig 사용 (DynamicWebTypeRenderer 호환성)
  const config = (props as any).webTypeConfig || componentConfig || {};

  // 🆕 multiple 값: props.multiple (spread된 값) > config.multiple 순서로 우선순위
  const isMultiple = (props as any).multiple ?? config?.multiple ?? false;

  // webType에 따른 세부 타입 결정 (TextInputComponent와 동일한 방식)
  const webType = component.componentConfig?.webType || "select";

  // 외부에서 전달받은 value가 있으면 우선 사용, 없으면 config.value 사용
  const [selectedValue, setSelectedValue] = useState(externalValue || config?.value || "");
  const [selectedLabel, setSelectedLabel] = useState("");

  // multiselect의 경우 배열로 관리 (콤마 구분자로 파싱)
  const [selectedValues, setSelectedValues] = useState<string[]>(() => {
    const initialValue = externalValue || config?.value || "";
    if (isMultiple && typeof initialValue === "string" && initialValue) {
      return initialValue
        .split(",")
        .map((v) => v.trim())
        .filter((v) => v);
    }
    return [];
  });

  // autocomplete의 경우 검색어 관리
  const [searchQuery, setSearchQuery] = useState("");

  const selectRef = useRef<HTMLDivElement>(null);

  // 안정적인 쿼리 키를 위한 메모이제이션
  const stableTableName = useMemo(() => component.tableName, [component.tableName]);
  const stableColumnName = useMemo(() => component.columnName, [component.columnName]);
  const staticCodeCategory = useMemo(() => config?.codeCategory, [config?.codeCategory]);

  // 🚀 React Query: 테이블 코드 카테고리 조회
  const { data: dynamicCodeCategory } = useTableCodeCategory(stableTableName, stableColumnName);

  // 🆕 React Query: 테이블 컬럼의 계층구조 설정 조회
  const { data: columnHierarchy } = useTableColumnHierarchy(stableTableName, stableColumnName);

  // 코드 카테고리 결정: 동적 카테고리 > 설정 카테고리 (메모이제이션)
  const codeCategory = useMemo(() => {
    const category = dynamicCodeCategory || staticCodeCategory;
    return category;
  }, [dynamicCodeCategory, staticCodeCategory, component.id]);

  // 🚀 React Query: 코드 옵션 조회 (안정적인 enabled 조건)
  const isCodeCategoryValid = useMemo(() => {
    return !!codeCategory && codeCategory !== "none";
  }, [codeCategory]);

  const {
    options: codeOptions,
    isLoading: isLoadingCodes,
    isFetching,
  } = useCodeOptions(codeCategory, isCodeCategoryValid, menuObjid);

  // 🆕 계층구조 코드 자동 감지: 비활성화 (테이블 타입관리에서 hierarchyRole 설정 방식 사용)
  // 기존: depth > 1인 코드가 있으면 자동으로 HierarchicalCodeSelect 사용
  // 변경: 항상 false 반환하여 자동 감지 비활성화
  const hasHierarchicalCodes = false;

  // 🆕 카테고리 타입 (category webType)을 위한 옵션 로딩
  const [categoryOptions, setCategoryOptions] = useState<Option[]>([]);
  const [isLoadingCategories, setIsLoadingCategories] = useState(false);

  // 🆕 연쇄 드롭다운 설정 확인
  const cascadingRelationCode = config?.cascadingRelationCode || componentConfig?.cascadingRelationCode;
  // 🆕 카테고리 값 연쇄관계 설정
  const categoryRelationCode = config?.categoryRelationCode || componentConfig?.categoryRelationCode;
  const cascadingRole = config?.cascadingRole || componentConfig?.cascadingRole || "child";
  const cascadingParentField = config?.cascadingParentField || componentConfig?.cascadingParentField;

  if (component.columnName === "data_type" || component.columnName === "unit") {
    console.log("🔥🔥🔥 [PLC 캐스케이딩 디버그]", {
      columnName: component.columnName,
      categoryRelationCode,
      cascadingRole,
      cascadingParentField,
      configKeys: config ? Object.keys(config) : "null",
      componentConfigKeys: componentConfig ? Object.keys(componentConfig) : "null",
      configCategoryRelationCode: config?.categoryRelationCode,
      componentConfigCategoryRelationCode: componentConfig?.categoryRelationCode,
      webType,
      formDataKeys: formData ? Object.keys(formData) : "null",
      parentValue: cascadingParentField && formData ? formData[cascadingParentField] : "N/A",
    });
  }

  // 🆕 계층구조 역할 설정 (대분류/중분류/소분류)
  // 1순위: 동적으로 조회된 값 (테이블 타입관리에서 설정)
  // 2순위: config에서 전달된 값
  const hierarchyRole = columnHierarchy?.hierarchyRole || config?.hierarchyRole || componentConfig?.hierarchyRole;
  const hierarchyParentField =
    columnHierarchy?.hierarchyParentField || config?.hierarchyParentField || componentConfig?.hierarchyParentField;

  // 🆕 자식 역할일 때 부모 값 추출 (단일 또는 다중)
  const rawParentValue =
    cascadingRole === "child" && cascadingParentField && formData ? formData[cascadingParentField] : undefined;

  // 🆕 계층구조 역할에 따른 부모 값 추출
  const hierarchyParentValue = useMemo(() => {
    if (!hierarchyRole || hierarchyRole === "large" || !hierarchyParentField || !formData) {
      return undefined;
    }
    return formData[hierarchyParentField] as string | undefined;
  }, [hierarchyRole, hierarchyParentField, formData]);

  // 🆕 계층구조에서 상위 항목 미선택 시 비활성화
  const isHierarchyDisabled = (hierarchyRole === "medium" || hierarchyRole === "small") && !hierarchyParentValue;

  // 최종 비활성화 상태
  const isFieldDisabled = isFieldDisabledBase || isHierarchyDisabled;

  // 🆕 계층구조 역할에 따라 옵션 필터링
  const filteredCodeOptions = useMemo(() => {
    if (!hierarchyRole || !codeOptions || codeOptions.length === 0) {
      return codeOptions;
    }

    // 대분류: depth = 1 (최상위)
    if (hierarchyRole === "large") {
      const filtered = codeOptions.filter((opt: any) => {
        const depth = opt.depth || 1;
        const parentCodeValue = opt.parentCodeValue || opt.parent_code_value;
        return depth === 1 || !parentCodeValue;
      });
      return filtered;
    }

    // 중분류/소분류: 부모 값이 있어야 함
    if ((hierarchyRole === "medium" || hierarchyRole === "small") && hierarchyParentValue) {
      const filtered = codeOptions.filter((opt: any) => {
        const parentCodeValue = opt.parentCodeValue || opt.parent_code_value;
        return parentCodeValue === hierarchyParentValue;
      });
      return filtered;
    }

    // 부모 값이 없으면 빈 배열 반환 (선택 불가 상태)
    if (hierarchyRole === "medium" || hierarchyRole === "small") {
      return [];
    }

    return codeOptions;
  }, [codeOptions, hierarchyRole, hierarchyParentValue]);

  // 🆕 부모값이 콤마로 구분된 문자열이면 배열로 변환 (다중 선택 지원)
  const parentValues: string[] | undefined = useMemo(() => {
    if (!rawParentValue) return undefined;

    // 이미 배열인 경우
    if (Array.isArray(rawParentValue)) {
      return rawParentValue.map((v) => String(v)).filter((v) => v);
    }

    // 콤마로 구분된 문자열인 경우
    const strValue = String(rawParentValue);
    if (strValue.includes(",")) {
      return strValue
        .split(",")
        .map((v) => v.trim())
        .filter((v) => v);
    }

    // 단일 값
    return [strValue];
  }, [rawParentValue]);

  // 🆕 연쇄 드롭다운 훅 사용 (역할에 따라 다른 옵션 로드) - 다중 부모값 지원
  const { options: cascadingOptions, loading: isLoadingCascading } = useCascadingDropdown({
    relationCode: cascadingRelationCode,
    categoryRelationCode: categoryRelationCode, // 🆕 카테고리 값 연쇄관계 지원
    role: cascadingRole, // 부모/자식 역할 전달
    parentValues: parentValues, // 다중 부모값
  });

  // 🆕 카테고리 값 연쇄관계가 활성화되었는지 확인
  const hasCategoryRelation = !!categoryRelationCode;

  useEffect(() => {
    if (webType === "category" && component.tableName && component.columnName) {
      setIsLoadingCategories(true);

      import("@/lib/api/tableCategoryValue").then(({ getCategoryValues }) => {
        // 🆕 menuObjid를 4번째 파라미터로 전달 (카테고리 스코프 적용)
        getCategoryValues(component.tableName!, component.columnName!, false, menuObjid)
          .then((response) => {
            if (response.success && "data" in response && response.data) {
              const activeValues = response.data.filter((v: any) => v.isActive !== false);
              const options = activeValues.map((v: any) => ({
                value: v.valueCode,
                label: v.valueLabel || v.valueCode,
              }));
              setCategoryOptions(options);
            }
          })
          .catch(() => {
            // 카테고리 값 조회 실패 시 무시
          })
          .finally(() => {
            setIsLoadingCategories(false);
          });
      });
    }
  }, [webType, component.tableName, component.columnName]);

  // 외부 value prop 변경 시 selectedValue 업데이트
  useEffect(() => {
    const newValue = externalValue || config?.value || "";

    // 다중선택 모드인 경우
    if (isMultiple) {
      if (typeof newValue === "string" && newValue) {
        const values = newValue
          .split(",")
          .map((v) => v.trim())
          .filter((v) => v);
        const currentValuesStr = selectedValues.join(",");

        if (newValue !== currentValuesStr) {
          setSelectedValues(values);
        }
      } else if (!newValue && selectedValues.length > 0) {
        setSelectedValues([]);
      }
    } else {
      // 단일선택 모드인 경우
      if (newValue !== selectedValue) {
        setSelectedValue(newValue);
      }
    }
  }, [externalValue, config?.value, isMultiple]);

  // ✅ React Query가 자동으로 처리하므로 복잡한 전역 상태 관리 제거
  // - 캐싱: React Query가 자동 관리 (10분 staleTime, 30분 gcTime)
  // - 중복 요청 방지: 동일한 queryKey에 대해 자동 중복 제거
  // - 상태 동기화: 모든 컴포넌트가 같은 캐시 공유

  // 📦 DataProvidable 인터페이스 구현 (데이터 전달 시 셀렉트 값 제공)
  const dataProvider: DataProvidable = {
    componentId: component.id,
    componentType: "select",

    getSelectedData: () => {
      // 현재 선택된 값을 배열로 반환
      const fieldName = component.columnName || "selectedValue";
      return [
        {
          [fieldName]: selectedValue,
          value: selectedValue,
          label: selectedLabel,
        },
      ];
    },

    getAllData: () => {
      // 모든 옵션 반환
      const configOptions = config.options || [];
      return [...codeOptions, ...categoryOptions, ...configOptions];
    },

    clearSelection: () => {
      setSelectedValue("");
      setSelectedLabel("");
      if (isMultiple) {
        setSelectedValues([]);
      }
    },
  };

  // 화면 컨텍스트에 데이터 제공자로 등록
  useEffect(() => {
    if (screenContext && component.id) {
      screenContext.registerDataProvider(component.id, dataProvider);

      return () => {
        screenContext.unregisterDataProvider(component.id);
      };
    }
  }, [screenContext, component.id, selectedValue, selectedLabel, selectedValues]);

  // 선택된 값에 따른 라벨 업데이트
  useEffect(() => {
    const getAllOptionsForLabel = () => {
      // 🆕 카테고리 값 연쇄관계가 설정된 경우 연쇄 옵션 사용
      if (categoryRelationCode) {
        return cascadingOptions;
      }
      // 🆕 연쇄 드롭다운이 설정된 경우 연쇄 옵션만 사용
      if (cascadingRelationCode) {
        return cascadingOptions;
      }
      const configOptions = config.options || [];
      return [...codeOptions, ...categoryOptions, ...configOptions];
    };

    const options = getAllOptionsForLabel();
    const selectedOption = options.find((option) => option.value === selectedValue);

    // 🎯 코드 타입의 경우 코드값과 코드명을 모두 고려하여 라벨 찾기
    let newLabel = selectedOption?.label || "";

    // selectedOption이 없고 selectedValue가 있다면, 코드명으로도 검색해보기
    if (!selectedOption && selectedValue && codeOptions.length > 0) {
      // 1) selectedValue가 코드명인 경우 (예: "국내")
      const labelMatch = options.find((option) => option.label === selectedValue);
      if (labelMatch) {
        newLabel = labelMatch.label;
      } else {
        // 2) selectedValue가 코드값인 경우라면 원래 로직대로 라벨을 찾되, 없으면 원값 표시
        newLabel = selectedValue; // 코드값 그대로 표시 (예: "555")
      }
    }

    if (newLabel !== selectedLabel) {
      setSelectedLabel(newLabel);
    }
  }, [selectedValue, codeOptions, config.options, cascadingOptions, cascadingRelationCode, categoryRelationCode]);

  // 클릭 이벤트 핸들러 (React Query로 간소화)
  const handleToggle = () => {
    if (isFieldDisabled) return; // 🆕 읽기전용/비활성화 상태에서는 토글 불가

    // React Query가 자동으로 캐시 관리하므로 수동 새로고침 불필요
    setIsOpen(!isOpen);
  };

  // 옵션 선택 핸들러
  const handleOptionSelect = (value: string, label: string) => {
    setSelectedValue(value);
    setSelectedLabel(label);
    setIsOpen(false);

    // 디자인 모드에서의 컴포넌트 속성 업데이트
    if (onUpdate) {
      onUpdate("value", value);
    }

    // 인터랙티브 모드에서 폼 데이터 업데이트 (TextInputComponent와 동일한 로직)
    if (isInteractive && onFormDataChange && component.columnName) {
      onFormDataChange(component.columnName, value);
    }
  };

  // 외부 클릭 시 드롭다운 닫기
  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (selectRef.current && !selectRef.current.contains(event.target as Node)) {
        setIsOpen(false);
      }
    };

    if (isOpen) {
      document.addEventListener("mousedown", handleClickOutside);
    }

    return () => {
      document.removeEventListener("mousedown", handleClickOutside);
    };
  }, [isOpen]);

  // ✅ React Query가 자동으로 처리하므로 수동 이벤트 리스너 불필요
  // - refetchOnWindowFocus: true (기본값)
  // - refetchOnReconnect: true (기본값)
  // - staleTime으로 적절한 캐시 관리

  // 모든 옵션 가져오기
  const getAllOptions = () => {
    // 🆕 카테고리 값 연쇄관계가 설정된 경우 연쇄 옵션 사용
    if (categoryRelationCode) {
      return cascadingOptions;
    }
    // 🆕 연쇄 드롭다운이 설정된 경우 연쇄 옵션만 사용
    if (cascadingRelationCode) {
      return cascadingOptions;
    }

    const configOptions = config.options || [];
    // 🆕 계층구조 역할이 설정된 경우 필터링된 옵션 사용
    return [...filteredCodeOptions, ...categoryOptions, ...configOptions];
  };

  const allOptions = getAllOptions();
  const placeholder = componentConfig.placeholder || "선택하세요";

  // DOM props에서 React 전용 props 필터링
  const {
    component: _component,
    componentConfig: _componentConfig,
    screenId: _screenId,
    onUpdate: _onUpdate,
    isSelected: _isSelected,
    isDesignMode: _isDesignMode,
    className: _className,
    style: _style,
    onClick: _onClick,
    onDragStart: _onDragStart,
    onDragEnd: _onDragEnd,
    ...otherProps
  } = props;

  const safeDomProps = filterDOMProps(otherProps);

  // 세부 타입별 렌더링
  const renderSelectByWebType = () => {
    // 🆕 계층구조 코드: 자동 감지 또는 수동 설정 시 1,2,3단계 셀렉트박스로 렌더링
    // 단, hierarchyRole이 설정된 경우(개별 컬럼별 계층구조)는 일반 셀렉트 사용
    const shouldUseHierarchical = !hierarchyRole && (config?.useHierarchicalCode || hasHierarchicalCodes);

    if (shouldUseHierarchical && codeCategory) {
      const maxDepth = config?.hierarchicalMaxDepth || 3;
      const labels = config?.hierarchicalLabels || ["대분류", "중분류", "소분류"];
      const placeholders = config?.hierarchicalPlaceholders || ["선택하세요", "선택하세요", "선택하세요"];
      const isInline = config?.hierarchicalInline || false;

      return (
        <HierarchicalCodeSelect
          categoryCode={codeCategory}
          menuObjid={menuObjid}
          maxDepth={maxDepth}
          value={selectedValue}
          onChange={(codeValue: string) => {
            setSelectedValue(codeValue);
            // 라벨 업데이트 - 선택된 값을 라벨로도 설정 (계층구조에서는 값=라벨인 경우가 많음)
            setSelectedLabel(codeValue);

            // 디자인 모드에서의 컴포넌트 속성 업데이트
            if (onUpdate) {
              onUpdate("value", codeValue);
            }

            // 인터랙티브 모드에서 폼 데이터 업데이트
            if (isInteractive && onFormDataChange && component.columnName) {
              onFormDataChange(component.columnName, codeValue);
            }
          }}
          labels={labels as [string, string?, string?]}
          placeholders={placeholders as [string, string?, string?]}
          className={isInline ? "flex-row gap-2" : "flex-col gap-2"}
          disabled={isFieldDisabled}
        />
      );
    }

    // code-radio: 라디오 버튼으로 코드 선택
    if (webType === "code-radio") {
      return (
        <div className="flex flex-col gap-2">
          {allOptions.map((option, index) => (
            <label key={index} className="flex cursor-pointer items-center gap-2">
              <input
                type="radio"
                name={component.id || "code-radio-group"}
                value={option.value}
                checked={selectedValue === option.value}
                onChange={() => handleOptionSelect(option.value, option.label)}
                disabled={isFieldDisabled}
                className="border-input text-primary focus:ring-ring h-4 w-4"
              />
              <span className="text-sm">{option.label}</span>
            </label>
          ))}
        </div>
      );
    }

    // code-autocomplete: 코드 자동완성
    if (webType === "code-autocomplete") {
      const filteredOptions = allOptions.filter(
        (opt) =>
          opt.label.toLowerCase().includes(searchQuery.toLowerCase()) ||
          opt.value.toLowerCase().includes(searchQuery.toLowerCase()),
      );

      return (
        <div className="w-full">
          <input
            type="text"
            value={searchQuery || selectedLabel}
            onChange={(e) => {
              setSearchQuery(e.target.value);
              setIsOpen(true);
            }}
            onFocus={() => setIsOpen(true)}
            placeholder="코드 또는 코드명 입력..."
            className={cn(
              "h-10 w-full rounded-lg border border-input bg-white px-3 py-2 transition-all outline-none",
              !isFieldDisabled && "hover:border-orange-400 focus:border-orange-500 focus:ring-2 focus:ring-orange-200",
              isSelected && "ring-2 ring-orange-500",
              isFieldDisabled && "cursor-not-allowed !bg-muted opacity-60",
            )}
            readOnly={isFieldDisabled}
            disabled={isFieldDisabled}
          />
          {isOpen && !isFieldDisabled && filteredOptions.length > 0 && (
            <div className="absolute z-[99999] mt-1 max-h-60 w-full overflow-auto rounded-md border border-input bg-white shadow-lg">
              {filteredOptions.map((option, index) => (
                <div
                  key={`${option.value}-${index}`}
                  className="cursor-pointer bg-white px-3 py-2 hover:bg-muted"
                  onClick={() => {
                    setSearchQuery("");
                    handleOptionSelect(option.value, option.label);
                  }}
                >
                  <div className="flex items-center justify-between">
                    <span className="text-sm font-medium text-foreground">{option.label}</span>
                    <span className="text-xs text-muted-foreground">{option.value}</span>
                  </div>
                </div>
              ))}
            </div>
          )}
        </div>
      );
    }

    // code: 기본 코드 선택박스 (select와 동일)
    if (webType === "code") {
      return (
        <div className="w-full">
          <div
            className={cn(
              "flex h-10 w-full items-center justify-between rounded-lg border border-input bg-white px-3 py-2",
              !isFieldDisabled && "cursor-pointer hover:border-orange-400",
              isSelected && "ring-2 ring-orange-500",
              isOpen && "border-orange-500",
              isFieldDisabled && "cursor-not-allowed !bg-muted opacity-60",
            )}
            onClick={handleToggle}
            style={{ pointerEvents: isFieldDisabled ? "none" : "auto" }}
          >
            <span className={selectedLabel ? "text-foreground" : "text-muted-foreground"}>{selectedLabel || placeholder}</span>
            <svg
              className={`h-4 w-4 transition-transform ${isOpen ? "rotate-180" : ""}`}
              fill="none"
              stroke="currentColor"
              viewBox="0 0 24 24"
            >
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
            </svg>
          </div>
          {isOpen && !isFieldDisabled && (
            <div className="absolute z-[99999] mt-1 max-h-60 w-full overflow-auto rounded-md border border-input bg-white shadow-lg">
              {isLoadingCodes ? (
                <div className="bg-white px-3 py-2 text-foreground">로딩 중...</div>
              ) : allOptions.length > 0 ? (
                allOptions.map((option, index) => (
                  <div
                    key={`${option.value}-${index}`}
                    className="cursor-pointer bg-white px-3 py-2 text-foreground hover:bg-muted"
                    onClick={() => handleOptionSelect(option.value, option.label)}
                  >
                    {option.label}
                  </div>
                ))
              ) : (
                <div className="bg-white px-3 py-2 text-foreground">옵션이 없습니다</div>
              )}
            </div>
          )}
        </div>
      );
    }

    // multiselect: 여러 항목 선택 (태그 형식)
    if (webType === "multiselect") {
      return (
        <div className="w-full">
          <div
            className={cn(
              "box-border flex h-full w-full flex-wrap gap-2 rounded-lg border border-input bg-white px-3 py-2",
              !isFieldDisabled && "hover:border-orange-400",
              isSelected && "ring-2 ring-orange-500",
              isFieldDisabled && "cursor-not-allowed !bg-muted opacity-60",
            )}
          >
            {selectedValues.map((val, idx) => {
              const opt = allOptions.find((o) => o.value === val);
              return (
                <span key={idx} className="flex items-center gap-1 rounded bg-primary/10 px-2 py-1 text-sm text-primary">
                  {opt?.label || val}
                  <button
                    type="button"
                    onClick={() => {
                      const newVals = selectedValues.filter((v) => v !== val);
                      setSelectedValues(newVals);
                      if (isInteractive && onFormDataChange && component.columnName) {
                        onFormDataChange(component.columnName, newVals.join(","));
                      }
                    }}
                    className="ml-1 text-primary hover:text-primary"
                  >
                    ×
                  </button>
                </span>
              );
            })}
            <input
              type="text"
              placeholder={selectedValues.length > 0 ? "" : placeholder}
              className="min-w-[100px] flex-1 border-none bg-transparent outline-none"
              onClick={() => !isFieldDisabled && setIsOpen(true)}
              readOnly={isFieldDisabled}
              disabled={isFieldDisabled}
            />
          </div>
        </div>
      );
    }

    // autocomplete: 검색 기능 포함
    if (webType === "autocomplete") {
      const filteredOptions = allOptions.filter(
        (opt) =>
          opt.label.toLowerCase().includes(searchQuery.toLowerCase()) ||
          opt.value.toLowerCase().includes(searchQuery.toLowerCase()),
      );

      return (
        <div className="w-full">
          <input
            type="text"
            value={searchQuery}
            onChange={(e) => {
              if (isFieldDisabled) return;
              setSearchQuery(e.target.value);
              setIsOpen(true);
            }}
            onFocus={() => !isFieldDisabled && setIsOpen(true)}
            placeholder={placeholder}
            className={cn(
              "h-10 w-full rounded-lg border border-input bg-white px-3 py-2 transition-all outline-none",
              !isFieldDisabled && "hover:border-orange-400 focus:border-orange-500 focus:ring-2 focus:ring-orange-200",
              isSelected && "ring-2 ring-orange-500",
              isFieldDisabled && "cursor-not-allowed !bg-muted opacity-60",
            )}
            readOnly={isFieldDisabled}
            disabled={isFieldDisabled}
          />
          {isOpen && !isFieldDisabled && filteredOptions.length > 0 && (
            <div className="absolute z-[99999] mt-1 max-h-60 w-full overflow-auto rounded-md border border-input bg-white shadow-lg">
              {filteredOptions.map((option, index) => (
                <div
                  key={`${option.value}-${index}`}
                  className="cursor-pointer bg-white px-3 py-2 text-foreground hover:bg-muted"
                  onClick={() => {
                    setSearchQuery(option.label);
                    setSelectedValue(option.value);
                    setSelectedLabel(option.label);
                    setIsOpen(false);
                    if (isInteractive && onFormDataChange && component.columnName) {
                      onFormDataChange(component.columnName, option.value);
                    }
                  }}
                >
                  {option.label}
                </div>
              ))}
            </div>
          )}
        </div>
      );
    }

    // dropdown (검색 선택박스): 기본 select와 유사하지만 검색 가능
    if (webType === "dropdown") {
      return (
        <div className="w-full">
          <div
            className={cn(
              "flex h-10 w-full items-center justify-between rounded-lg border border-input bg-white px-3 py-2",
              !isFieldDisabled && "cursor-pointer hover:border-orange-400",
              isSelected && "ring-2 ring-orange-500",
              isOpen && "border-orange-500",
              isFieldDisabled && "cursor-not-allowed !bg-muted opacity-60",
            )}
            onClick={handleToggle}
            style={{ pointerEvents: isFieldDisabled ? "none" : "auto" }}
          >
            <span className={selectedLabel ? "text-foreground" : "text-muted-foreground"}>{selectedLabel || placeholder}</span>
            <svg
              className={`h-4 w-4 transition-transform ${isOpen ? "rotate-180" : ""}`}
              fill="none"
              stroke="currentColor"
              viewBox="0 0 24 24"
            >
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
            </svg>
          </div>
          {isOpen && !isFieldDisabled && (
            <div className="absolute z-[99999] mt-1 w-full rounded-md border border-input bg-white shadow-lg">
              <input
                type="text"
                value={searchQuery}
                onChange={(e) => setSearchQuery(e.target.value)}
                placeholder="검색..."
                className="w-full border-b border-input px-3 py-2 outline-none"
              />
              <div className="max-h-60 overflow-auto">
                {allOptions
                  .filter(
                    (opt) =>
                      opt.label.toLowerCase().includes(searchQuery.toLowerCase()) ||
                      opt.value.toLowerCase().includes(searchQuery.toLowerCase()),
                  )
                  .map((option, index) => (
                    <div
                      key={`${option.value}-${index}`}
                      className="cursor-pointer bg-white px-3 py-2 text-foreground hover:bg-muted"
                      onClick={() => handleOptionSelect(option.value, option.label)}
                    >
                      {option.label || option.value}
                    </div>
                  ))}
              </div>
            </div>
          )}
        </div>
      );
    }

    // select (기본 선택박스)
    // 다중선택 모드인 경우
    if (isMultiple) {
      return (
        <div className="w-full" style={{ height: "100%" }}>
          <div
            className={cn(
              "box-border flex w-full flex-wrap items-center gap-2 rounded-lg border border-input bg-white px-3 py-2",
              !isFieldDisabled && "hover:border-orange-400",
              isSelected && "ring-2 ring-orange-500",
              isFieldDisabled && "cursor-not-allowed !bg-muted opacity-60",
            )}
            onClick={() => !isFieldDisabled && setIsOpen(true)}
            style={{
              pointerEvents: isFieldDisabled ? "none" : "auto",
              height: "100%",
            }}
          >
            {selectedValues.map((val, idx) => {
              const opt = allOptions.find((o) => o.value === val);
              return (
                <span key={idx} className="flex items-center gap-1 rounded bg-primary/10 px-2 py-1 text-sm text-primary">
                  {opt?.label || val}
                  <button
                    type="button"
                    onClick={(e) => {
                      e.stopPropagation();
                      const newVals = selectedValues.filter((v) => v !== val);
                      setSelectedValues(newVals);
                      const newValue = newVals.join(",");
                      if (isInteractive && onFormDataChange && component.columnName) {
                        onFormDataChange(component.columnName, newValue);
                      }
                    }}
                    className="ml-1 text-primary hover:text-primary"
                  >
                    ×
                  </button>
                </span>
              );
            })}
            {selectedValues.length === 0 && <span className="text-muted-foreground">{placeholder}</span>}
          </div>
          {isOpen && !isFieldDisabled && (
            <div className="absolute z-[99999] mt-1 max-h-60 w-full overflow-auto rounded-md border border-input bg-white shadow-lg">
              {isLoadingCodes || isLoadingCategories ? (
                <div className="bg-white px-3 py-2 text-foreground">로딩 중...</div>
              ) : allOptions.length > 0 ? (
                (() => {
                  // 부모별 그룹핑 (카테고리 연쇄관계인 경우)
                  const hasParentInfo = allOptions.some((opt: any) => opt.parent_label);

                  if (hasParentInfo) {
                    // 부모별로 그룹핑
                    const groupedOptions: Record<string, { parentLabel: string; options: typeof allOptions }> = {};
                    allOptions.forEach((opt: any) => {
                      const parentKey = opt.parent_value || "기타";
                      const parentLabel = opt.parent_label || "기타";
                      if (!groupedOptions[parentKey]) {
                        groupedOptions[parentKey] = { parentLabel, options: [] };
                      }
                      groupedOptions[parentKey].options.push(opt);
                    });

                    return Object.entries(groupedOptions).map(([parentKey, group]) => (
                      <div key={parentKey}>
                        {/* 그룹 헤더 */}
                        <div className="sticky top-0 border-b bg-muted px-3 py-1.5 text-xs font-semibold text-muted-foreground">
                          {group.parentLabel}
                        </div>
                        {/* 그룹 옵션들 */}
                        {group.options.map((option, index) => {
                          const isOptionSelected = selectedValues.includes(option.value);
                          return (
                            <div
                              key={`${option.value}-${index}`}
                              className={cn(
                                "cursor-pointer px-3 py-2 text-foreground hover:bg-muted",
                                isOptionSelected && "bg-primary/10 font-medium",
                              )}
                              onClick={() => {
                                const newVals = isOptionSelected
                                  ? selectedValues.filter((v) => v !== option.value)
                                  : [...selectedValues, option.value];
                                setSelectedValues(newVals);
                                const newValue = newVals.join(",");
                                if (isInteractive && onFormDataChange && component.columnName) {
                                  onFormDataChange(component.columnName, newValue);
                                }
                              }}
                            >
                              <div className="flex items-center gap-2">
                                <input
                                  type="checkbox"
                                  checked={isOptionSelected}
                                  value={option.value}
                                  onChange={(e) => {
                                    e.stopPropagation();
                                    const newVals = isOptionSelected
                                      ? selectedValues.filter((v) => v !== option.value)
                                      : [...selectedValues, option.value];
                                    setSelectedValues(newVals);
                                    const newValue = newVals.join(",");
                                    if (isInteractive && onFormDataChange && component.columnName) {
                                      onFormDataChange(component.columnName, newValue);
                                    }
                                  }}
                                  className="pointer-events-auto h-4 w-4"
                                />
                                <span>{option.label || option.value}</span>
                              </div>
                            </div>
                          );
                        })}
                      </div>
                    ));
                  }

                  // 부모 정보가 없으면 기존 방식
                  return allOptions.map((option, index) => {
                    const isOptionSelected = selectedValues.includes(option.value);
                    return (
                      <div
                        key={`${option.value}-${index}`}
                        className={cn(
                          "cursor-pointer px-3 py-2 text-foreground hover:bg-muted",
                          isOptionSelected && "bg-primary/10 font-medium",
                        )}
                        onClick={() => {
                          const newVals = isOptionSelected
                            ? selectedValues.filter((v) => v !== option.value)
                            : [...selectedValues, option.value];
                          setSelectedValues(newVals);
                          const newValue = newVals.join(",");
                          if (isInteractive && onFormDataChange && component.columnName) {
                            onFormDataChange(component.columnName, newValue);
                          }
                        }}
                      >
                        <div className="flex items-center gap-2">
                          <input
                            type="checkbox"
                            checked={isOptionSelected}
                            value={option.value}
                            onChange={(e) => {
                              e.stopPropagation();
                              const newVals = isOptionSelected
                                ? selectedValues.filter((v) => v !== option.value)
                                : [...selectedValues, option.value];
                              setSelectedValues(newVals);
                              const newValue = newVals.join(",");
                              if (isInteractive && onFormDataChange && component.columnName) {
                                onFormDataChange(component.columnName, newValue);
                              }
                            }}
                            className="pointer-events-auto h-4 w-4"
                          />
                          <span>{option.label || option.value}</span>
                        </div>
                      </div>
                    );
                  });
                })()
              ) : (
                <div className="bg-white px-3 py-2 text-foreground">옵션이 없습니다</div>
              )}
            </div>
          )}
        </div>
      );
    }

    // 단일선택 모드
    return (
      <div className="w-full">
        <div
          className={cn(
            "flex h-10 w-full items-center justify-between rounded-lg border border-input bg-white px-3 py-2",
            !isFieldDisabled && "cursor-pointer hover:border-orange-400",
            isSelected && "ring-2 ring-orange-500",
            isOpen && "border-orange-500",
            isFieldDisabled && "cursor-not-allowed !bg-muted opacity-60",
          )}
          onClick={handleToggle}
          style={{ pointerEvents: isFieldDisabled ? "none" : "auto" }}
        >
          <span className={selectedLabel ? "text-foreground" : "text-muted-foreground"}>{selectedLabel || placeholder}</span>
          <svg
            className={`h-4 w-4 transition-transform ${isOpen ? "rotate-180" : ""}`}
            fill="none"
            stroke="currentColor"
            viewBox="0 0 24 24"
          >
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
          </svg>
        </div>
        {isOpen && !isFieldDisabled && (
          <div className="absolute z-[99999] mt-1 max-h-60 w-full overflow-auto rounded-md border border-input bg-white shadow-lg">
            {isLoadingCodes ? (
              <div className="bg-white px-3 py-2 text-foreground">로딩 중...</div>
            ) : allOptions.length > 0 ? (
              allOptions.map((option, index) => (
                <div
                  key={`${option.value}-${index}`}
                  className="cursor-pointer bg-white px-3 py-2 text-foreground hover:bg-muted"
                  onClick={() => handleOptionSelect(option.value, option.label)}
                >
                  {option.label || option.value}
                </div>
              ))
            ) : (
              <div className="bg-white px-3 py-2 text-foreground">옵션이 없습니다</div>
            )}
          </div>
        )}
      </div>
    );
  };

  return (
    <div
      ref={selectRef}
      className={`relative w-full ${className || ""}`}
      style={style}
      onClick={onClick}
      onDragStart={onDragStart}
      onDragEnd={onDragEnd}
      {...safeDomProps}
    >
      {/* 라벨 렌더링 */}
      {component.label && (component.style?.labelDisplay ?? true) && (
        <label className="absolute -top-6 left-0 text-sm font-medium text-slate-600">
          {component.label}
          {component.required && <span className="text-destructive">*</span>}
        </label>
      )}

      {/* 세부 타입별 UI 렌더링 */}
      {renderSelectByWebType()}
    </div>
  );
};

// Wrapper 컴포넌트 (기존 호환성을 위해)
export const SelectBasicWrapper = SelectBasicComponent;

// 기본 export
export { SelectBasicComponent };
