import { apiClient } from "./client";
import {
  CodeCategory,
  CodeInfo,
  CodeOption,
  CreateCategoryRequest,
  UpdateCategoryRequest,
  CreateCodeRequest,
  UpdateCodeRequest,
  GetCategoriesQuery,
  GetCodesQuery,
  ApiResponse,
} from "@/types/commonCode";

/**
 * 공통코드 관리 API 클라이언트
 */
export const commonCodeApi = {
  // 카테고리 관련 API
  categories: {
    /**
     * 카테고리 목록 조회
     */
    async getList(params?: GetCategoriesQuery): Promise<ApiResponse<CodeCategory[]>> {
      const searchParams = new URLSearchParams();

      if (params?.search) searchParams.append("search", params.search);
      if (params?.isActive !== undefined) searchParams.append("isActive", params.isActive.toString());
      if (params?.page) searchParams.append("page", params.page.toString());
      if (params?.size) searchParams.append("size", params.size.toString());

      const queryString = searchParams.toString();
      const url = `/common-codes/categories${queryString ? `?${queryString}` : ""}`;

      const response = await apiClient.get(url);
      return response.data;
    },

    /**
     * 카테고리 생성
     */
    async create(data: CreateCategoryRequest): Promise<ApiResponse<CodeCategory>> {
      const response = await apiClient.post("/common-codes/categories", data);
      return response.data;
    },

    /**
     * 카테고리 수정
     */
    async update(categoryCode: string, data: UpdateCategoryRequest): Promise<ApiResponse<CodeCategory>> {
      const response = await apiClient.put(`/common-codes/categories/${categoryCode}`, data);
      return response.data;
    },

    /**
     * 카테고리 삭제
     */
    async delete(categoryCode: string): Promise<ApiResponse> {
      const response = await apiClient.delete(`/common-codes/categories/${categoryCode}`);
      return response.data;
    },
  },

  // 코드 관련 API
  codes: {
    /**
     * 카테고리별 코드 목록 조회
     */
    async getList(categoryCode: string, params?: GetCodesQuery & { menuObjid?: number }): Promise<ApiResponse<CodeInfo[]>> {
      const searchParams = new URLSearchParams();

      if (params?.search) searchParams.append("search", params.search);
      if (params?.isActive !== undefined) searchParams.append("isActive", params.isActive.toString());
      if (params?.page !== undefined) searchParams.append("page", params.page.toString());
      if (params?.size !== undefined) searchParams.append("size", params.size.toString());
      if (params?.menuObjid !== undefined) searchParams.append("menuObjid", params.menuObjid.toString());

      const queryString = searchParams.toString();
      const url = `/common-codes/categories/${categoryCode}/codes${queryString ? `?${queryString}` : ""}`;

      const response = await apiClient.get(url);
      return response.data;
    },

    /**
     * 코드 생성
     */
    async create(categoryCode: string, data: CreateCodeRequest): Promise<ApiResponse<CodeInfo>> {
      const response = await apiClient.post(`/common-codes/categories/${categoryCode}/codes`, data);
      return response.data;
    },

    /**
     * 코드 수정
     */
    async update(categoryCode: string, codeValue: string, data: UpdateCodeRequest): Promise<ApiResponse<CodeInfo>> {
      const response = await apiClient.put(`/common-codes/categories/${categoryCode}/codes/${codeValue}`, data);
      return response.data;
    },

    /**
     * 코드 삭제
     */
    async delete(categoryCode: string, codeValue: string): Promise<ApiResponse> {
      const response = await apiClient.delete(`/common-codes/categories/${categoryCode}/codes/${codeValue}`);
      return response.data;
    },

    /**
     * 코드 순서 변경
     */
    async reorder(categoryCode: string, codes: Array<{ codeValue: string; sortOrder: number }>): Promise<ApiResponse> {
      const data = { codes }; // 백엔드가 기대하는 형식으로 래핑
      const response = await apiClient.put(`/common-codes/categories/${categoryCode}/codes/reorder`, data);
      return response.data;
    },
  },

  // 중복 검사 API
  validation: {
    /**
     * 카테고리 중복 검사
     */
    async checkCategoryDuplicate(
      field: "categoryCode" | "categoryName" | "categoryNameEng",
      value: string,
      excludeCode?: string,
    ): Promise<ApiResponse<{ isDuplicate: boolean; message: string; field: string; value: string }>> {
      const params = new URLSearchParams();
      params.append("field", field);
      params.append("value", value);
      if (excludeCode) params.append("excludeCode", excludeCode);

      const response = await apiClient.get(`/common-codes/categories/check-duplicate?${params}`);
      return response.data;
    },

    /**
     * 코드 중복 검사
     */
    async checkCodeDuplicate(
      categoryCode: string,
      field: "codeValue" | "codeName" | "codeNameEng",
      value: string,
      excludeCode?: string,
    ): Promise<
      ApiResponse<{ isDuplicate: boolean; message: string; categoryCode: string; field: string; value: string }>
    > {
      const params = new URLSearchParams();
      params.append("field", field);
      params.append("value", value);
      if (excludeCode) params.append("excludeCode", excludeCode);

      const response = await apiClient.get(`/common-codes/categories/${categoryCode}/codes/check-duplicate?${params}`);
      return response.data;
    },
  },

  // 옵션 조회 API (화면관리용)
  options: {
    /**
     * 카테고리별 옵션 조회
     */
    async getOptions(categoryCode: string): Promise<ApiResponse<CodeOption[]>> {
      const response = await apiClient.get(`/common-codes/categories/${categoryCode}/options`);
      return response.data;
    },
  },

  // 계층구조 코드 API
  hierarchy: {
    /**
     * 계층구조 코드 조회
     * @param categoryCode 카테고리 코드
     * @param parentCodeValue 부모 코드값 (빈 문자열이면 최상위 코드)
     * @param depth 특정 깊이만 조회 (선택)
     * @param menuObjid 메뉴 OBJID (선택)
     */
    async getHierarchicalCodes(
      categoryCode: string,
      parentCodeValue?: string | null,
      depth?: number,
      menuObjid?: number
    ): Promise<ApiResponse<CodeInfo[]>> {
      const searchParams = new URLSearchParams();

      if (parentCodeValue !== undefined && parentCodeValue !== null) {
        searchParams.append("parentCodeValue", parentCodeValue);
      }
      if (depth !== undefined) searchParams.append("depth", depth.toString());
      if (menuObjid !== undefined) searchParams.append("menuObjid", menuObjid.toString());

      const queryString = searchParams.toString();
      const url = `/common-codes/categories/${categoryCode}/hierarchy${queryString ? `?${queryString}` : ""}`;

      const response = await apiClient.get(url);
      return response.data;
    },

    /**
     * 코드 트리 조회 (전체 계층구조)
     */
    async getCodeTree(
      categoryCode: string,
      menuObjid?: number
    ): Promise<ApiResponse<{ flat: CodeInfo[]; tree: CodeInfo[] }>> {
      const searchParams = new URLSearchParams();
      if (menuObjid !== undefined) searchParams.append("menuObjid", menuObjid.toString());

      const queryString = searchParams.toString();
      const url = `/common-codes/categories/${categoryCode}/tree${queryString ? `?${queryString}` : ""}`;

      const response = await apiClient.get(url);
      return response.data;
    },

    /**
     * 자식 코드 존재 여부 확인
     */
    async hasChildren(categoryCode: string, codeValue: string): Promise<ApiResponse<{ hasChildren: boolean }>> {
      const response = await apiClient.get(
        `/common-codes/categories/${categoryCode}/codes/${codeValue}/has-children`
      );
      return response.data;
    },
  },
};
