"use client";

/**
 * useDbColumns — DB 테이블의 컬럼 목록을 mount/tableName 변경 시 lazy 로드.
 *
 * 사용처: stats / chart / cardList / groupedTable 의 컬럼 선택 dropdown.
 * 모듈 스코프 Map 캐시로 같은 테이블 중복 요청 방지.
 */

import { useEffect, useMemo, useState } from "react";

export interface DbColumnOption {
  value: string;
  label: string;
  data_type?: string;
}

const cache = new Map<string, DbColumnOption[]>();
const inflight = new Map<string, Promise<DbColumnOption[]>>();

export interface UseDbColumnsResult {
  columns: DbColumnOption[];
  loading: boolean;
  error?: string;
}

export function useDbColumns(tableName?: string): UseDbColumnsResult {
  const [columns, setColumns] = useState<DbColumnOption[]>(() =>
    tableName ? cache.get(tableName) ?? [] : [],
  );
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | undefined>(undefined);

  useEffect(() => {
    let cancelled = false;
    setError(undefined);
    if (!tableName) {
      setColumns([]);
      setLoading(false);
      return;
    }
    const cached = cache.get(tableName);
    if (cached) {
      setColumns(cached);
      setLoading(false);
      return;
    }
    setLoading(true);
    const promise =
      inflight.get(tableName) ??
      (async () => {
        const { tableManagementApi } = await import("@/lib/api/tableManagement");
        const res = await tableManagementApi.getColumnList(tableName, 1000);
        const rows = (res?.success ? res.data?.columns ?? [] : []) as any[];
        const opts: DbColumnOption[] = rows
          .map((c) => ({
            value: c?.column_name ?? c?.columnName ?? "",
            label:
              (c?.display_name ?? c?.displayName ?? "") ||
              c?.column_name ||
              c?.columnName ||
              "",
            data_type: c?.data_type ?? c?.dataType,
          }))
          .filter((o) => !!o.value);
        cache.set(tableName, opts);
        return opts;
      })();
    inflight.set(tableName, promise);
    promise
      .then((opts) => {
        if (cancelled) return;
        setColumns(opts);
      })
      .catch((e) => {
        if (cancelled) return;
        setError(e?.message ?? "컬럼 목록 로드 실패");
      })
      .finally(() => {
        inflight.delete(tableName);
        if (!cancelled) setLoading(false);
      });
    return () => {
      cancelled = true;
    };
  }, [tableName]);

  return useMemo(() => ({ columns, loading, error }), [columns, loading, error]);
}
