/**
 * 🔗 연쇄 드롭다운(Cascading Dropdown) 훅
 * 
 * 부모 필드의 값에 따라 자식 드롭다운의 옵션을 동적으로 로드합니다.
 * 
 * @example
 * // 방법 1: 관계 코드 사용 (권장)
 * const { options, loading, error } = useCascadingDropdown({
 *   relationCode: "WAREHOUSE_LOCATION",
 *   parentValue: formData.warehouse_code,
 * });
 * 
 * @example
 * // 방법 2: 직접 설정 (레거시)
 * const { options, loading, error } = useCascadingDropdown({
 *   config: {
 *     enabled: true,
 *     parentField: "warehouse_code",
 *     sourceTable: "warehouse_location",
 *     parentKeyColumn: "warehouse_id",
 *     valueColumn: "location_code",
 *     labelColumn: "location_name",
 *   },
 *   parentValue: formData.warehouse_code,
 * });
 */

import { useState, useEffect, useCallback, useRef, useMemo } from "react";
import { apiClient } from "@/lib/api/client";
import { CascadingDropdownConfig } from "@/types/screen-management";

export interface CascadingOption {
  value: string;
  label: string;
  [key: string]: any; // 추가 데이터
}

export interface UseCascadingDropdownProps {
  /** 🆕 연쇄 관계 코드 (관계 관리에서 정의한 코드) */
  relationCode?: string;
  /** 🆕 카테고리 값 연쇄 관계 코드 (카테고리 값 연쇄관계용) */
  categoryRelationCode?: string;
  /** 🆕 역할: parent(부모-전체 옵션) 또는 child(자식-필터링된 옵션) */
  role?: "parent" | "child";
  /** @deprecated 직접 설정 방식 - relationCode 사용 권장 */
  config?: CascadingDropdownConfig;
  /** 부모 필드의 현재 값 (자식 역할일 때 필요) - 단일 값 또는 배열(다중 선택) */
  parentValue?: string | number | null;
  /** 🆕 다중 부모값 (배열) - parentValue보다 우선 */
  parentValues?: (string | number)[];
  /** 초기 옵션 (캐시된 데이터가 있을 경우) */
  initialOptions?: CascadingOption[];
}

export interface UseCascadingDropdownResult {
  /** 드롭다운 옵션 목록 */
  options: CascadingOption[];
  /** 로딩 상태 */
  loading: boolean;
  /** 에러 메시지 */
  error: string | null;
  /** 옵션 새로고침 */
  refresh: () => void;
  /** 옵션 초기화 */
  clear: () => void;
  /** 특정 값의 라벨 가져오기 */
  getLabelByValue: (value: string) => string | undefined;
  /** API에서 가져온 관계 설정 (relationCode 사용 시) */
  relationConfig: CascadingDropdownConfig | null;
}

// 글로벌 캐시 (컴포넌트 간 공유)
const optionsCache = new Map<string, { options: CascadingOption[]; timestamp: number }>();
const CACHE_TTL = 5 * 60 * 1000; // 5분

export function useCascadingDropdown({
  relationCode,
  categoryRelationCode,
  role = "child", // 기본값은 자식 역할 (기존 동작 유지)
  config,
  parentValue,
  parentValues,
  initialOptions = [],
}: UseCascadingDropdownProps): UseCascadingDropdownResult {
  const [options, setOptions] = useState<CascadingOption[]>(initialOptions);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [relationConfig, setRelationConfig] = useState<CascadingDropdownConfig | null>(null);
  
  // 이전 부모 값 추적 (변경 감지용)
  const prevParentValueRef = useRef<string | number | null | undefined>(undefined);
  
  // 관계 코드 또는 직접 설정 중 하나라도 있는지 확인
  const isEnabled = !!relationCode || !!categoryRelationCode || config?.enabled;
  
  // 유효한 부모값 배열 계산 (다중 또는 단일) - 메모이제이션으로 불필요한 리렌더 방지
  const effectiveParentValues: string[] = useMemo(() => {
    if (parentValues && parentValues.length > 0) {
      return parentValues.map(v => String(v));
    }
    if (parentValue !== null && parentValue !== undefined) {
      return [String(parentValue)];
    }
    return [];
  }, [parentValues, parentValue]);
  
  // 부모값 배열의 문자열 키 (의존성 비교용)
  const parentValuesKey = useMemo(() => JSON.stringify(effectiveParentValues), [effectiveParentValues]);

  // 캐시 키 생성
  const getCacheKey = useCallback(() => {
    if (categoryRelationCode) {
      // 카테고리 값 연쇄관계
      if (role === "parent") {
        return `category-value:${categoryRelationCode}:parent:all`;
      }
      if (effectiveParentValues.length === 0) return null;
      const sortedValues = [...effectiveParentValues].sort().join(',');
      return `category-value:${categoryRelationCode}:child:${sortedValues}`;
    }
    if (relationCode) {
      // 부모 역할: 전체 옵션 캐시
      if (role === "parent") {
        return `relation:${relationCode}:parent:all`;
      }
      // 자식 역할: 부모 값별 캐시 (다중 부모값 지원)
      if (effectiveParentValues.length === 0) return null;
      const sortedValues = [...effectiveParentValues].sort().join(',');
      return `relation:${relationCode}:child:${sortedValues}`;
    }
    if (config) {
      if (effectiveParentValues.length === 0) return null;
      const sortedValues = [...effectiveParentValues].sort().join(',');
      return `${config.sourceTable}:${config.parentKeyColumn}:${sortedValues}`;
    }
    return null;
  }, [categoryRelationCode, relationCode, role, config, effectiveParentValues]);

  // 🆕 부모 역할 옵션 로드 (관계의 parent_table에서 전체 옵션 로드)
  const loadParentOptions = useCallback(async () => {
    if (!relationCode) {
      setOptions([]);
      return;
    }

    const cacheKey = getCacheKey();
    
    // 캐시 확인
    if (cacheKey) {
      const cached = optionsCache.get(cacheKey);
      if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
        setOptions(cached.options);
        return;
      }
    }

    setLoading(true);
    setError(null);

    try {
      // 부모 역할용 API 호출 (전체 옵션)
      const response = await apiClient.get(`/cascading-relations/parent-options/${relationCode}`);

      if (response.data?.success) {
        const loadedOptions: CascadingOption[] = response.data.data || [];
        setOptions(loadedOptions);
        
        // 캐시 저장
        if (cacheKey) {
          optionsCache.set(cacheKey, {
            options: loadedOptions,
            timestamp: Date.now(),
          });
        }

        console.log("✅ Parent options 로드 완료:", {
          relationCode,
          count: loadedOptions.length,
        });
      } else {
        throw new Error(response.data?.message || "옵션 로드 실패");
      }
    } catch (err: any) {
      console.error("❌ Parent options 로드 실패:", err);
      setError(err.message || "옵션을 불러오는 데 실패했습니다.");
      setOptions([]);
    } finally {
      setLoading(false);
    }
  }, [relationCode, getCacheKey]);

  // 자식 역할 옵션 로드 (관계 코드 방식) - 다중 부모값 지원
  const loadChildOptions = useCallback(async () => {
    if (!relationCode || effectiveParentValues.length === 0) {
      setOptions([]);
      return;
    }

    const cacheKey = getCacheKey();
    
    // 캐시 확인
    if (cacheKey) {
      const cached = optionsCache.get(cacheKey);
      if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
        setOptions(cached.options);
        return;
      }
    }

    setLoading(true);
    setError(null);

    try {
      // 다중 부모값 지원: parentValues 파라미터 사용
      let url: string;
      if (effectiveParentValues.length === 1) {
        // 단일 값 (기존 호환)
        url = `/cascading-relations/options/${relationCode}?parentValue=${encodeURIComponent(effectiveParentValues[0])}`;
      } else {
        // 다중 값
        const parentValuesParam = effectiveParentValues.join(',');
        url = `/cascading-relations/options/${relationCode}?parentValues=${encodeURIComponent(parentValuesParam)}`;
      }
      
      const response = await apiClient.get(url);

      if (response.data?.success) {
        const loadedOptions: CascadingOption[] = response.data.data || [];
        setOptions(loadedOptions);
        
        // 캐시 저장
        if (cacheKey) {
          optionsCache.set(cacheKey, {
            options: loadedOptions,
            timestamp: Date.now(),
          });
        }

        console.log("✅ Child options 로드 완료 (다중 부모값 지원):", {
          relationCode,
          parentValues: effectiveParentValues,
          count: loadedOptions.length,
        });
      } else {
        throw new Error(response.data?.message || "옵션 로드 실패");
      }
    } catch (err: any) {
      console.error("❌ Child options 로드 실패:", err);
      setError(err.message || "옵션을 불러오는 데 실패했습니다.");
      setOptions([]);
    } finally {
      setLoading(false);
    }
  }, [relationCode, effectiveParentValues, getCacheKey]);

  // 🆕 카테고리 값 연쇄관계 - 부모 옵션 로드
  const loadCategoryParentOptions = useCallback(async () => {
    if (!categoryRelationCode) {
      setOptions([]);
      return;
    }

    const cacheKey = getCacheKey();
    
    // 캐시 확인
    if (cacheKey) {
      const cached = optionsCache.get(cacheKey);
      if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
        setOptions(cached.options);
        return;
      }
    }

    setLoading(true);
    setError(null);

    try {
      const response = await apiClient.get(`/category-value-cascading/parent-options/${categoryRelationCode}`);

      if (response.data?.success) {
        const loadedOptions: CascadingOption[] = response.data.data || [];
        setOptions(loadedOptions);
        
        // 캐시 저장
        if (cacheKey) {
          optionsCache.set(cacheKey, {
            options: loadedOptions,
            timestamp: Date.now(),
          });
        }

        console.log("✅ Category parent options 로드 완료:", {
          categoryRelationCode,
          count: loadedOptions.length,
        });
      } else {
        throw new Error(response.data?.message || "옵션 로드 실패");
      }
    } catch (err: any) {
      console.error("❌ Category parent options 로드 실패:", err);
      setError(err.message || "옵션을 불러오는 데 실패했습니다.");
      setOptions([]);
    } finally {
      setLoading(false);
    }
  }, [categoryRelationCode, getCacheKey]);

  // 🆕 카테고리 값 연쇄관계 - 자식 옵션 로드 (다중 부모값 지원)
  const loadCategoryChildOptions = useCallback(async () => {
    if (!categoryRelationCode || effectiveParentValues.length === 0) {
      setOptions([]);
      return;
    }

    const cacheKey = getCacheKey();
    
    // 캐시 확인
    if (cacheKey) {
      const cached = optionsCache.get(cacheKey);
      if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
        setOptions(cached.options);
        return;
      }
    }

    setLoading(true);
    setError(null);

    try {
      // 다중 부모값 지원
      let url: string;
      if (effectiveParentValues.length === 1) {
        url = `/category-value-cascading/options/${categoryRelationCode}?parentValue=${encodeURIComponent(effectiveParentValues[0])}`;
      } else {
        const parentValuesParam = effectiveParentValues.join(',');
        url = `/category-value-cascading/options/${categoryRelationCode}?parentValues=${encodeURIComponent(parentValuesParam)}`;
      }
      
      const response = await apiClient.get(url);

      if (response.data?.success) {
        const loadedOptions: CascadingOption[] = response.data.data || [];
        setOptions(loadedOptions);
        
        // 캐시 저장
        if (cacheKey) {
          optionsCache.set(cacheKey, {
            options: loadedOptions,
            timestamp: Date.now(),
          });
        }

        console.log("✅ Category child options 로드 완료 (다중 부모값 지원):", {
          categoryRelationCode,
          parentValues: effectiveParentValues,
          count: loadedOptions.length,
        });
      } else {
        throw new Error(response.data?.message || "옵션 로드 실패");
      }
    } catch (err: any) {
      console.error("❌ Category child options 로드 실패:", err);
      setError(err.message || "옵션을 불러오는 데 실패했습니다.");
      setOptions([]);
    } finally {
      setLoading(false);
    }
  }, [categoryRelationCode, effectiveParentValues, getCacheKey]);

  // 옵션 로드 (직접 설정 방식 - 레거시)
  const loadOptionsByConfig = useCallback(async () => {
    if (!config?.enabled || !parentValue) {
      setOptions([]);
      return;
    }

    const cacheKey = getCacheKey();
    
    // 캐시 확인
    if (cacheKey) {
      const cached = optionsCache.get(cacheKey);
      if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
        setOptions(cached.options);
        return;
      }
    }

    setLoading(true);
    setError(null);

    try {
      // API 호출하여 옵션 로드
      const response = await apiClient.post(`/table-management/tables/${config.sourceTable}/data`, {
        page: 1,
        size: 1000, // 충분히 큰 값
        search: {
          [config.parentKeyColumn]: parentValue,
          ...config.additionalFilters,
        },
        autoFilter: true,
      });

      const items = response.data?.data?.data || response.data?.data || [];
      
      const loadedOptions: CascadingOption[] = items.map((item: any) => ({
        value: String(item[config.valueColumn] || ""),
        label: String(item[config.labelColumn] || item[config.valueColumn] || ""),
        ...item, // 전체 데이터 보존
      }));

      setOptions(loadedOptions);
      
      // 캐시 저장
      if (cacheKey) {
        optionsCache.set(cacheKey, {
          options: loadedOptions,
          timestamp: Date.now(),
        });
      }

      console.log("✅ Cascading options 로드 완료 (직접설정):", {
        sourceTable: config.sourceTable,
        parentValue,
        count: loadedOptions.length,
      });
    } catch (err: any) {
      console.error("❌ Cascading options 로드 실패:", err);
      setError(err.message || "옵션을 불러오는 데 실패했습니다.");
      setOptions([]);
    } finally {
      setLoading(false);
    }
  }, [config, parentValue, getCacheKey]);

  // 통합 로드 함수
  const loadOptions = useCallback(() => {
    // 카테고리 값 연쇄관계 우선
    if (categoryRelationCode) {
      if (role === "parent") {
        loadCategoryParentOptions();
      } else {
        loadCategoryChildOptions();
      }
    } else if (relationCode) {
      // 역할에 따라 다른 로드 함수 호출
      if (role === "parent") {
        loadParentOptions();
      } else {
        loadChildOptions();
      }
    } else if (config?.enabled) {
      loadOptionsByConfig();
    } else {
      setOptions([]);
    }
  }, [categoryRelationCode, relationCode, role, config?.enabled, loadCategoryParentOptions, loadCategoryChildOptions, loadParentOptions, loadChildOptions, loadOptionsByConfig]);

  // 옵션 로드 트리거
  useEffect(() => {
    if (!isEnabled) {
      setOptions([]);
      return;
    }

    // 부모 역할: 즉시 전체 옵션 로드 (최초 1회만)
    if (role === "parent") {
      loadOptions();
      return;
    }

    // 자식 역할: 부모 값이 있을 때만 로드
    // 부모 값 배열의 변경 감지를 위해 JSON 문자열 비교
    const prevParentKey = prevParentValueRef.current;
    
    if (prevParentKey !== parentValuesKey) {
      prevParentValueRef.current = parentValuesKey as any;
      
      if (effectiveParentValues.length > 0) {
        loadOptions();
      } else {
        // 부모 값이 없으면 옵션 초기화
        setOptions([]);
      }
    }
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isEnabled, role, parentValuesKey]);

  // 옵션 새로고침
  const refresh = useCallback(() => {
    const cacheKey = getCacheKey();
    if (cacheKey) {
      optionsCache.delete(cacheKey);
    }
    loadOptions();
  }, [getCacheKey, loadOptions]);

  // 옵션 초기화
  const clear = useCallback(() => {
    setOptions([]);
    setError(null);
  }, []);

  // 값으로 라벨 찾기
  const getLabelByValue = useCallback((value: string): string | undefined => {
    const option = options.find((opt) => opt.value === value);
    return option?.label;
  }, [options]);

  return {
    options,
    loading,
    error,
    refresh,
    clear,
    getLabelByValue,
    relationConfig: relationConfig || config || null,
  };
}

// 캐시 관리 유틸리티
export const cascadingDropdownCache = {
  /** 특정 테이블의 캐시 삭제 */
  invalidateTable: (tableName: string) => {
    const keysToDelete: string[] = [];
    optionsCache.forEach((_, key) => {
      if (key.startsWith(`${tableName}:`)) {
        keysToDelete.push(key);
      }
    });
    keysToDelete.forEach((key) => optionsCache.delete(key));
  },
  
  /** 모든 캐시 삭제 */
  invalidateAll: () => {
    optionsCache.clear();
  },
  
  /** 캐시 상태 확인 */
  getStats: () => ({
    size: optionsCache.size,
    keys: Array.from(optionsCache.keys()),
  }),
};

export default useCascadingDropdown;

