import { apiClient } from "./client";
import type {
  CodeInfo,
  CodeDetail,
  ApiResponse,
  GetCodeInfoListQuery,
  GetCodeDetailListQuery,
  DuplicateCheckResult,
} from "@/types/commonCode";

/**
 * 공통코드 API 클라이언트 (마스터-디테일 구조)
 *
 *   code_info   — 그룹 마스터
 *   code_detail — 트리 노드 (depth 2 시작, 무한 depth)
 *
 * 백엔드 계약 (BE Agent 가 만드는 것):
 *   /api/common-codes/info/...
 *   /api/common-codes/detail/...
 *
 * 응답 포맷:
 *   목록: { success, data: [...], total: N, message }
 *   단건/CRUD: { success, data: {...}, message }
 */

/* ───────────────────────── code_info (그룹 마스터) ───────────────────────── */

/** 그룹 목록 (페이징/검색) */
export async function getCodeInfoList(
  params?: GetCodeInfoListQuery,
): Promise<ApiResponse<CodeInfo[]>> {
  const search = new URLSearchParams();
  if (params?.search) search.append("search", params.search);
  if (params?.is_active !== undefined) search.append("is_active", params.is_active.toString());
  if (params?.page !== undefined) search.append("page", params.page.toString());
  if (params?.size !== undefined) search.append("size", params.size.toString());

  const qs = search.toString();
  const url = `/common-codes/info${qs ? `?${qs}` : ""}`;
  const response = await apiClient.get(url);
  return response.data;
}

/** 그룹 단건 */
export async function getCodeInfoInfo(codeInfo: string): Promise<ApiResponse<CodeInfo>> {
  const response = await apiClient.get(`/common-codes/info/${encodeURIComponent(codeInfo)}`);
  return response.data;
}

/** 그룹 생성 */
export async function createCodeInfo(data: Record<string, any>): Promise<ApiResponse<CodeInfo>> {
  const response = await apiClient.post("/common-codes/info", data);
  return response.data;
}

/** 그룹 수정 */
export async function updateCodeInfo(
  codeInfo: string,
  data: Record<string, any>,
): Promise<ApiResponse<CodeInfo>> {
  const response = await apiClient.put(
    `/common-codes/info/${encodeURIComponent(codeInfo)}`,
    data,
  );
  return response.data;
}

/** 그룹 삭제 (CASCADE) */
export async function deleteCodeInfo(codeInfo: string): Promise<ApiResponse> {
  const response = await apiClient.delete(`/common-codes/info/${encodeURIComponent(codeInfo)}`);
  return response.data;
}

/** 그룹 중복 체크 */
export async function checkCodeInfoDuplicate(
  field: "code_info" | "code_name" | "code_name_eng",
  value: string,
  excludeCode?: string,
): Promise<ApiResponse<DuplicateCheckResult>> {
  const search = new URLSearchParams();
  search.append("field", field);
  search.append("value", value);
  if (excludeCode) search.append("excludeCode", excludeCode);
  const response = await apiClient.get(`/common-codes/info/check-duplicate?${search}`);
  return response.data;
}

/* ───────────────────────── code_detail (디테일 트리) ───────────────────────── */

/** 그룹의 전체 디테일 트리 (depth+sort_order 평탄화 리스트) */
export async function getCodeDetailTree(
  params: GetCodeDetailListQuery,
): Promise<ApiResponse<CodeDetail[]>> {
  const search = new URLSearchParams();
  search.append("code_info", params.code_info);
  if (params.search) search.append("search", params.search);
  if (params.is_active !== undefined) search.append("is_active", params.is_active.toString());

  const response = await apiClient.get(`/common-codes/detail?${search}`);
  return response.data;
}

/** 디테일 단건 */
export async function getCodeDetailInfo(
  codeDetailId: number | string,
): Promise<ApiResponse<CodeDetail>> {
  const response = await apiClient.get(`/common-codes/detail/${codeDetailId}`);
  return response.data;
}

/** 디테일 생성 */
export async function createCodeDetail(
  data: Record<string, any>,
): Promise<ApiResponse<CodeDetail>> {
  const response = await apiClient.post("/common-codes/detail", data);
  return response.data;
}

/** 디테일 수정 */
export async function updateCodeDetail(
  codeDetailId: number | string,
  data: Record<string, any>,
): Promise<ApiResponse<CodeDetail>> {
  const response = await apiClient.put(`/common-codes/detail/${codeDetailId}`, data);
  return response.data;
}

/** 디테일 삭제 (CASCADE) */
export async function deleteCodeDetail(codeDetailId: number | string): Promise<ApiResponse> {
  const response = await apiClient.delete(`/common-codes/detail/${codeDetailId}`);
  return response.data;
}

/** 디테일 중복 체크 (그룹 + 필드 단위) */
export async function checkCodeDetailDuplicate(
  codeInfo: string,
  field: "code_value" | "code_name" | "code_name_eng",
  value: string,
  excludeId?: number | string,
): Promise<ApiResponse<DuplicateCheckResult>> {
  const search = new URLSearchParams();
  search.append("code_info", codeInfo);
  search.append("field", field);
  search.append("value", value);
  if (excludeId !== undefined && excludeId !== null && excludeId !== "") {
    search.append("excludeId", String(excludeId));
  }
  const response = await apiClient.get(`/common-codes/detail/check-duplicate?${search}`);
  return response.data;
}

/* ───────────────────────── compat: 화면관리/캐시에서 사용 ───────────────────────── */

/**
 * 그룹의 활성 디테일 옵션 (label/value)
 * 기존 `commonCodeApi.options.getOptions(categoryCode)` 의 대체.
 */
export async function getCodeOptions(
  codeInfo: string,
): Promise<ApiResponse<Array<{ value: string; label: string; depth?: number; parent_detail_id?: number | null }>>> {
  const tree = await getCodeDetailTree({ code_info: codeInfo, is_active: true });
  const options = (tree.data || []).map((row) => ({
    value: row.code_value,
    label: row.code_name || row.code_value,
    depth: row.depth,
    parent_detail_id: row.parent_detail_id ?? null,
  }));
  return {
    success: tree.success,
    data: options,
    message: tree.message,
    total: options.length,
  };
}

/**
 * 호환 객체. 기존 코드가 `commonCodeApi.codes.getList(category, ...)` 등으로 부르고 있어
 * 깨끗한 1안 마이그레이션 동안 임시로 노출. 새 코드는 위 함수들을 직접 import.
 *
 * NOTE: 사용처가 점진적으로 제거되면 이 객체도 삭제.
 */
export const commonCodeApi = {
  info: {
    getList: getCodeInfoList,
    get: getCodeInfoInfo,
    create: createCodeInfo,
    update: updateCodeInfo,
    delete: deleteCodeInfo,
    checkDuplicate: checkCodeInfoDuplicate,
  },
  detail: {
    getTree: getCodeDetailTree,
    get: getCodeDetailInfo,
    create: createCodeDetail,
    update: updateCodeDetail,
    delete: deleteCodeDetail,
    checkDuplicate: checkCodeDetailDuplicate,
  },
  options: {
    getOptions: getCodeOptions,
  },
};
