import React, { useState, useEffect, useRef } from "react";
import { commonCodeApi } from "../../../api/commonCode";
import { tableTypeApi } from "../../../api/screen";
import { filterDOMProps } from "@/lib/utils/domPropsFilter";

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; // 외부에서 전달받는 값
  [key: string]: any;
}

// 🚀 전역 상태 관리: 모든 컴포넌트가 공유하는 상태
interface GlobalState {
  tableCategories: Map<string, string>; // tableName.columnName -> codeCategory
  codeOptions: Map<string, { options: Option[]; timestamp: number }>; // codeCategory -> options
  activeRequests: Map<string, Promise<any>>; // 진행 중인 요청들
  subscribers: Set<() => void>; // 상태 변경 구독자들
}

const globalState: GlobalState = {
  tableCategories: new Map(),
  codeOptions: new Map(),
  activeRequests: new Map(),
  subscribers: new Set(),
};

// 전역 상태 변경 알림
const notifyStateChange = () => {
  globalState.subscribers.forEach((callback) => callback());
};

// 캐시 유효 시간 (5분)
const CACHE_DURATION = 5 * 60 * 1000;

// 🔧 전역 테이블 코드 카테고리 로딩 (중복 방지)
const loadGlobalTableCodeCategory = async (tableName: string, columnName: string): Promise<string | null> => {
  const key = `${tableName}.${columnName}`;

  // 이미 진행 중인 요청이 있으면 대기
  if (globalState.activeRequests.has(`table_${key}`)) {
    try {
      await globalState.activeRequests.get(`table_${key}`);
    } catch (error) {
      console.error("❌ 테이블 설정 로딩 대기 중 오류:", error);
    }
  }

  // 캐시된 값이 있으면 반환
  if (globalState.tableCategories.has(key)) {
    const cachedCategory = globalState.tableCategories.get(key);
    console.log(`✅ 캐시된 테이블 설정 사용: ${key} -> ${cachedCategory}`);
    return cachedCategory || null;
  }

  // 새로운 요청 생성
  const request = (async () => {
    try {
      console.log(`🔍 테이블 코드 카테고리 조회: ${key}`);
      const columns = await tableTypeApi.getColumns(tableName);
      const targetColumn = columns.find((col) => col.columnName === columnName);

      const codeCategory =
        targetColumn?.codeCategory && targetColumn.codeCategory !== "none" ? targetColumn.codeCategory : null;

      // 전역 상태에 저장
      globalState.tableCategories.set(key, codeCategory || "");

      console.log(`✅ 테이블 설정 조회 완료: ${key} -> ${codeCategory}`);

      // 상태 변경 알림
      notifyStateChange();

      return codeCategory;
    } catch (error) {
      console.error(`❌ 테이블 코드 카테고리 조회 실패: ${key}`, error);
      return null;
    } finally {
      globalState.activeRequests.delete(`table_${key}`);
    }
  })();

  globalState.activeRequests.set(`table_${key}`, request);
  return request;
};

// 🔧 전역 코드 옵션 로딩 (중복 방지)
const loadGlobalCodeOptions = async (codeCategory: string): Promise<Option[]> => {
  if (!codeCategory || codeCategory === "none") {
    return [];
  }

  // 이미 진행 중인 요청이 있으면 대기
  if (globalState.activeRequests.has(`code_${codeCategory}`)) {
    try {
      await globalState.activeRequests.get(`code_${codeCategory}`);
    } catch (error) {
      console.error("❌ 코드 옵션 로딩 대기 중 오류:", error);
    }
  }

  // 캐시된 값이 유효하면 반환
  const cached = globalState.codeOptions.get(codeCategory);
  if (cached && Date.now() - cached.timestamp < CACHE_DURATION) {
    console.log(`✅ 캐시된 코드 옵션 사용: ${codeCategory} (${cached.options.length}개)`);
    return cached.options;
  }

  // 새로운 요청 생성
  const request = (async () => {
    try {
      console.log(`🔄 코드 옵션 로딩: ${codeCategory}`);
      const response = await commonCodeApi.codes.getList(codeCategory, { isActive: true });

      console.log(`🔍 [API 응답 원본] ${codeCategory}:`, {
        response,
        success: response.success,
        data: response.data,
        dataType: typeof response.data,
        isArray: Array.isArray(response.data),
        dataLength: response.data?.length,
        firstItem: response.data?.[0],
      });

      if (response.success && response.data) {
        const options = response.data.map((code: any, index: number) => {
          console.log(`🔍 [코드 매핑] ${index}:`, {
            originalCode: code,
            codeKeys: Object.keys(code),
            values: Object.values(code),
            // 가능한 모든 필드 확인
            code: code.code,
            codeName: code.codeName,
            name: code.name,
            label: code.label,
            // 대문자 버전
            CODE: code.CODE,
            CODE_NAME: code.CODE_NAME,
            NAME: code.NAME,
            LABEL: code.LABEL,
            // 스네이크 케이스
            code_name: code.code_name,
            code_value: code.code_value,
            // 기타 가능한 필드들
            value: code.value,
            text: code.text,
            title: code.title,
            description: code.description,
          });

          // 실제 값 찾기 시도 (우선순위 순)
          const actualValue = code.code || code.CODE || code.value || code.code_value || `code_${index}`;
          const actualLabel =
            code.codeName ||
            code.code_name || // 스네이크 케이스 추가!
            code.name ||
            code.CODE_NAME ||
            code.NAME ||
            code.label ||
            code.LABEL ||
            code.text ||
            code.title ||
            code.description ||
            actualValue;

          console.log(`✨ [최종 매핑] ${index}:`, {
            actualValue,
            actualLabel,
            hasValue: !!actualValue,
            hasLabel: !!actualLabel,
          });

          return {
            value: actualValue,
            label: actualLabel,
          };
        });

        console.log(`🔍 [최종 옵션 배열] ${codeCategory}:`, {
          optionsLength: options.length,
          options: options.map((opt, idx) => ({
            index: idx,
            value: opt.value,
            label: opt.label,
            hasLabel: !!opt.label,
            hasValue: !!opt.value,
          })),
        });

        // 전역 상태에 저장
        globalState.codeOptions.set(codeCategory, {
          options,
          timestamp: Date.now(),
        });

        console.log(`✅ 코드 옵션 로딩 완료: ${codeCategory} (${options.length}개)`);

        // 상태 변경 알림
        notifyStateChange();

        return options;
      } else {
        console.log(`⚠️ 빈 응답: ${codeCategory}`);
        return [];
      }
    } catch (error) {
      console.error(`❌ 코드 옵션 로딩 실패: ${codeCategory}`, error);
      return [];
    } finally {
      globalState.activeRequests.delete(`code_${codeCategory}`);
    }
  })();

  globalState.activeRequests.set(`code_${codeCategory}`, request);
  return request;
};

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 받기
  ...props
}) => {
  const [isOpen, setIsOpen] = useState(false);

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

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

  console.log("🔍 SelectBasicComponent 초기화:", {
    componentId: component.id,
    externalValue,
    componentConfigValue: componentConfig?.value,
    webTypeConfigValue: (props as any).webTypeConfig?.value,
    configValue: config?.value,
    finalSelectedValue: externalValue || config?.value || "",
    props: Object.keys(props),
  });
  const [codeOptions, setCodeOptions] = useState<Option[]>([]);
  const [isLoadingCodes, setIsLoadingCodes] = useState(false);
  const [dynamicCodeCategory, setDynamicCodeCategory] = useState<string | null>(null);
  const [globalStateVersion, setGlobalStateVersion] = useState(0); // 전역 상태 변경 감지용
  const selectRef = useRef<HTMLDivElement>(null);

  // 코드 카테고리 결정: 동적 카테고리 > 설정 카테고리
  const codeCategory = dynamicCodeCategory || config?.codeCategory;

  // 외부 value prop 변경 시 selectedValue 업데이트
  useEffect(() => {
    const newValue = externalValue || config?.value || "";
    // 값이 실제로 다른 경우에만 업데이트 (빈 문자열도 유효한 값으로 처리)
    if (newValue !== selectedValue) {
      console.log(`🔄 SelectBasicComponent value 업데이트: "${selectedValue}" → "${newValue}"`);
      console.log("🔍 업데이트 조건 분석:", {
        externalValue,
        componentConfigValue: componentConfig?.value,
        configValue: config?.value,
        newValue,
        selectedValue,
        shouldUpdate: newValue !== selectedValue,
      });
      setSelectedValue(newValue);
    }
  }, [externalValue, config?.value]);

  // 🚀 전역 상태 구독 및 동기화
  useEffect(() => {
    const updateFromGlobalState = () => {
      setGlobalStateVersion((prev) => prev + 1);
    };

    // 전역 상태 변경 구독
    globalState.subscribers.add(updateFromGlobalState);

    return () => {
      globalState.subscribers.delete(updateFromGlobalState);
    };
  }, []);

  // 🔧 테이블 코드 카테고리 로드 (전역 상태 사용)
  const loadTableCodeCategory = async () => {
    if (!component.tableName || !component.columnName) return;

    try {
      console.log(`🔍 [${component.id}] 전역 테이블 코드 카테고리 조회`);
      const category = await loadGlobalTableCodeCategory(component.tableName, component.columnName);

      if (category !== dynamicCodeCategory) {
        console.log(`🔄 [${component.id}] 코드 카테고리 변경: ${dynamicCodeCategory} → ${category}`);
        setDynamicCodeCategory(category);
      }
    } catch (error) {
      console.error(`❌ [${component.id}] 테이블 코드 카테고리 조회 실패:`, error);
    }
  };

  // 🔧 코드 옵션 로드 (전역 상태 사용)
  const loadCodeOptions = async (category: string) => {
    if (!category || category === "none") {
      setCodeOptions([]);
      setIsLoadingCodes(false);
      return;
    }

    try {
      setIsLoadingCodes(true);
      console.log(`🔄 [${component.id}] 전역 코드 옵션 로딩: ${category}`);

      const options = await loadGlobalCodeOptions(category);
      setCodeOptions(options);

      console.log(`✅ [${component.id}] 코드 옵션 업데이트 완료: ${category} (${options.length}개)`);
    } catch (error) {
      console.error(`❌ [${component.id}] 코드 옵션 로딩 실패:`, error);
      setCodeOptions([]);
    } finally {
      setIsLoadingCodes(false);
    }
  };

  // 초기 테이블 코드 카테고리 로드
  useEffect(() => {
    loadTableCodeCategory();
  }, [component.tableName, component.columnName]);

  // 전역 상태 변경 시 동기화
  useEffect(() => {
    if (component.tableName && component.columnName) {
      const key = `${component.tableName}.${component.columnName}`;
      const cachedCategory = globalState.tableCategories.get(key);

      if (cachedCategory && cachedCategory !== dynamicCodeCategory) {
        console.log(`🔄 [${component.id}] 전역 상태 동기화: ${dynamicCodeCategory} → ${cachedCategory}`);
        setDynamicCodeCategory(cachedCategory || null);
      }
    }
  }, [globalStateVersion, component.tableName, component.columnName]);

  // 코드 카테고리 변경 시 옵션 로드
  useEffect(() => {
    if (codeCategory && codeCategory !== "none") {
      // 전역 캐시된 옵션부터 확인
      const cached = globalState.codeOptions.get(codeCategory);
      if (cached && Date.now() - cached.timestamp < CACHE_DURATION) {
        console.log(`🚀 [${component.id}] 전역 캐시 즉시 적용: ${codeCategory} (${cached.options.length}개)`);
        setCodeOptions(cached.options);
        setIsLoadingCodes(false);
      } else {
        loadCodeOptions(codeCategory);
      }
    } else {
      setCodeOptions([]);
      setIsLoadingCodes(false);
    }
  }, [codeCategory]);

  // 전역 상태에서 코드 옵션 변경 감지
  useEffect(() => {
    if (codeCategory) {
      const cached = globalState.codeOptions.get(codeCategory);
      if (cached && Date.now() - cached.timestamp < CACHE_DURATION) {
        if (JSON.stringify(cached.options) !== JSON.stringify(codeOptions)) {
          console.log(`🔄 [${component.id}] 전역 옵션 변경 감지: ${codeCategory}`);
          setCodeOptions(cached.options);
        }
      }
    }
  }, [globalStateVersion, codeCategory]);

  // 선택된 값에 따른 라벨 업데이트
  useEffect(() => {
    const getAllOptions = () => {
      const configOptions = config.options || [];
      return [...codeOptions, ...configOptions];
    };

    const options = getAllOptions();
    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;
        console.log(`🔍 [${component.id}] 코드명으로 매치 발견: "${selectedValue}" → "${newLabel}"`);
      } else {
        // 2) selectedValue가 코드값인 경우라면 원래 로직대로 라벨을 찾되, 없으면 원값 표시
        newLabel = selectedValue; // 코드값 그대로 표시 (예: "555")
        console.log(`🔍 [${component.id}] 코드값 원본 유지: "${selectedValue}"`);
      }
    }

    console.log(`🏷️ [${component.id}] 라벨 업데이트:`, {
      selectedValue,
      selectedOption: selectedOption ? { value: selectedOption.value, label: selectedOption.label } : null,
      newLabel,
      optionsCount: options.length,
      allOptionsValues: options.map((o) => o.value),
      allOptionsLabels: options.map((o) => o.label),
    });

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

  // 클릭 이벤트 핸들러 (전역 상태 새로고침)
  const handleToggle = () => {
    if (isDesignMode) return;

    console.log(`🖱️ [${component.id}] 드롭다운 토글: ${isOpen} → ${!isOpen}`);
    console.log(`📊 [${component.id}] 현재 상태:`, {
      isDesignMode,
      isLoadingCodes,
      allOptionsLength: allOptions.length,
      allOptions: allOptions.map((o) => ({ value: o.value, label: o.label })),
    });

    // 드롭다운을 열 때 전역 상태 새로고침
    if (!isOpen) {
      console.log(`🖱️ [${component.id}] 셀렉트박스 클릭 - 전역 상태 새로고침`);

      // 테이블 설정 캐시 무효화 후 재로드
      if (component.tableName && component.columnName) {
        const key = `${component.tableName}.${component.columnName}`;
        globalState.tableCategories.delete(key);

        // 현재 코드 카테고리의 캐시도 무효화
        if (dynamicCodeCategory) {
          globalState.codeOptions.delete(dynamicCodeCategory);
          console.log(`🗑️ [${component.id}] 코드 옵션 캐시 무효화: ${dynamicCodeCategory}`);

          // 강제로 새로운 API 호출 수행
          console.log(`🔄 [${component.id}] 강제 코드 옵션 재로드 시작: ${dynamicCodeCategory}`);
          loadCodeOptions(dynamicCodeCategory);
        }

        loadTableCodeCategory();
      }
    }

    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) {
      console.log(`📤 SelectBasicComponent -> onFormDataChange 호출: ${component.columnName} = "${value}"`);
      onFormDataChange(component.columnName, value);
    } else {
      console.log("❌ SelectBasicComponent onFormDataChange 조건 미충족:", {
        isInteractive,
        hasOnFormDataChange: !!onFormDataChange,
        hasColumnName: !!component.columnName,
      });
    }

    console.log(`✅ [${component.id}] 옵션 선택:`, { value, label });
  };

  // 외부 클릭 시 드롭다운 닫기
  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]);

  // 🚀 실시간 업데이트를 위한 이벤트 리스너
  useEffect(() => {
    const handleFocus = () => {
      console.log(`👁️ [${component.id}] 윈도우 포커스 - 전역 상태 새로고침`);
      if (component.tableName && component.columnName) {
        const key = `${component.tableName}.${component.columnName}`;
        globalState.tableCategories.delete(key); // 캐시 무효화
        loadTableCodeCategory();
      }
    };

    const handleVisibilityChange = () => {
      if (!document.hidden) {
        console.log(`👁️ [${component.id}] 페이지 가시성 변경 - 전역 상태 새로고침`);
        if (component.tableName && component.columnName) {
          const key = `${component.tableName}.${component.columnName}`;
          globalState.tableCategories.delete(key); // 캐시 무효화
          loadTableCodeCategory();
        }
      }
    };

    window.addEventListener("focus", handleFocus);
    document.addEventListener("visibilitychange", handleVisibilityChange);

    return () => {
      window.removeEventListener("focus", handleFocus);
      document.removeEventListener("visibilitychange", handleVisibilityChange);
    };
  }, [component.tableName, component.columnName]);

  // 모든 옵션 가져오기
  const getAllOptions = () => {
    const configOptions = config.options || [];
    console.log(`🔧 [${component.id}] 옵션 병합:`, {
      codeOptionsLength: codeOptions.length,
      codeOptions: codeOptions.map((o) => ({ value: o.value, label: o.label })),
      configOptionsLength: configOptions.length,
      configOptions: configOptions.map((o) => ({ value: o.value, label: o.label })),
    });
    return [...codeOptions, ...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);

  return (
    <div
      ref={selectRef}
      className={`relative w-full ${className || ""}`}
      style={style}
      onClick={onClick}
      onDragStart={onDragStart}
      onDragEnd={onDragEnd}
      {...safeDomProps}
    >
      {/* 라벨 렌더링 */}
      {component.label && component.style?.labelDisplay !== false && (
        <label
          style={{
            position: "absolute",
            top: "-25px",
            left: "0px",
            fontSize: component.style?.labelFontSize || "14px",
            color: component.style?.labelColor || "#374151",
            fontWeight: "500",
            // isInteractive 모드에서는 사용자 스타일 우선 적용
            ...(isInteractive && component.style ? component.style : {}),
          }}
        >
          {component.label}
          {component.required && <span style={{ color: "#ef4444" }}>*</span>}
        </label>
      )}

      {/* 커스텀 셀렉트 박스 */}
      <div
        className={`flex w-full cursor-pointer items-center justify-between rounded-md border border-gray-300 bg-white px-3 py-2 ${isDesignMode ? "pointer-events-none" : "hover:border-gray-400"} ${isSelected ? "ring-2 ring-blue-500" : ""} ${isOpen ? "border-blue-500" : ""} `}
        onClick={handleToggle}
        style={{
          pointerEvents: isDesignMode ? "none" : "auto",
        }}
      >
        <span className={selectedLabel ? "text-gray-900" : "text-gray-500"}>{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 && !isDesignMode && (
        <div
          className="absolute mt-1 max-h-60 w-full overflow-auto rounded-md border border-gray-300 bg-white shadow-lg"
          style={{
            backgroundColor: "white",
            color: "black",
            zIndex: 99999, // 더 높은 z-index로 설정
          }}
        >
          {(() => {
            console.log(`🎨 [${component.id}] 드롭다운 렌더링:`, {
              isOpen,
              isDesignMode,
              isLoadingCodes,
              allOptionsLength: allOptions.length,
              allOptions: allOptions.map((o) => ({ value: o.value, label: o.label })),
            });
            return null;
          })()}
          {isLoadingCodes ? (
            <div className="bg-white px-3 py-2 text-gray-900">로딩 중...</div>
          ) : allOptions.length > 0 ? (
            allOptions.map((option, index) => (
              <div
                key={`${option.value}-${index}`}
                className="cursor-pointer bg-white px-3 py-2 text-gray-900 hover:bg-gray-100"
                style={{
                  color: "black",
                  backgroundColor: "white",
                  minHeight: "32px",
                  border: "1px solid #e5e7eb",
                }}
                onClick={() => handleOptionSelect(option.value, option.label)}
              >
                {option.label || option.value || `옵션 ${index + 1}`}
              </div>
            ))
          ) : (
            <div className="bg-white px-3 py-2 text-gray-900">옵션이 없습니다</div>
          )}
        </div>
      )}
    </div>
  );
};

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

// 기본 export
export { SelectBasicComponent };
