/**
 * 채번 규칙 관리 API 클라이언트
 */

import { apiClient } from "./client";
import { NumberingRuleConfig } from "@/types/numbering-rule";

export interface ApiResponse<T> {
  success: boolean;
  data?: T;
  error?: string;
  message?: string;
}

export async function getNumberingRules(): Promise<ApiResponse<NumberingRuleConfig[]>> {
  try {
    const response = await apiClient.get("/numbering-rules");
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message || "규칙 목록 조회 실패" };
  }
}

/**
 * 메뉴별 사용 가능한 채번 규칙 조회 (기존 방식, 하위 호환성 유지)
 * @param menuObjid 현재 메뉴의 objid (선택)
 * @returns 사용 가능한 채번 규칙 목록
 */
export async function getAvailableNumberingRules(menuObjid?: number): Promise<ApiResponse<NumberingRuleConfig[]>> {
  try {
    const url = menuObjid ? `/numbering-rules/available/${menuObjid}` : "/numbering-rules/available";
    const response = await apiClient.get(url);
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message || "사용 가능한 규칙 조회 실패" };
  }
}

/**
 * 화면용 채번 규칙 조회 (테이블 기반 필터링 - 간소화)
 * @param tableName 화면의 테이블명 (필수)
 * @returns 해당 테이블의 채번 규칙 목록
 */
export async function getAvailableNumberingRulesForScreen(
  tableName: string,
): Promise<ApiResponse<NumberingRuleConfig[]>> {
  try {
    const response = await apiClient.get("/numbering-rules/available-for-screen", {
      params: { tableName },
    });
    return response.data;
  } catch (error: any) {
    return {
      success: false,
      error: error.message || "화면용 규칙 조회 실패",
    };
  }
}

export async function getNumberingRuleById(ruleId: string): Promise<ApiResponse<NumberingRuleConfig>> {
  try {
    const response = await apiClient.get(`/numbering-rules/${ruleId}`);
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message || "규칙 조회 실패" };
  }
}

export async function createNumberingRule(config: NumberingRuleConfig): Promise<ApiResponse<NumberingRuleConfig>> {
  try {
    const response = await apiClient.post("/numbering-rules", config);
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message || "규칙 생성 실패" };
  }
}

export async function updateNumberingRule(
  ruleId: string,
  config: Partial<NumberingRuleConfig>,
): Promise<ApiResponse<NumberingRuleConfig>> {
  try {
    const response = await apiClient.put(`/numbering-rules/${ruleId}`, config);
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message || "규칙 수정 실패" };
  }
}

export async function deleteNumberingRule(ruleId: string): Promise<ApiResponse<void>> {
  try {
    const response = await apiClient.delete(`/numbering-rules/${ruleId}`);
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message || "규칙 삭제 실패" };
  }
}

/**
 * 코드 미리보기 (순번 증가 없음)
 * 화면 표시용으로 사용
 * @param ruleId 채번 규칙 ID
 * @param formData 폼 데이터 (카테고리 기반 채번 시 사용)
 */
export async function previewNumberingCode(
  ruleId: string,
  formData?: Record<string, unknown>,
  manualInputValue?: string,
): Promise<ApiResponse<{ generatedCode: string }>> {
  // ruleId 유효성 검사
  if (!ruleId || ruleId === "undefined" || ruleId === "null") {
    return { success: false, error: "채번 규칙 ID가 설정되지 않았습니다" };
  }

  try {
    const response = await apiClient.post(`/numbering-rules/${ruleId}/preview`, {
      formData: formData || {},
      manualInputValue,
    });
    if (!response.data) {
      return { success: false, error: "서버 응답이 비어있습니다" };
    }
    return response.data;
  } catch (error: unknown) {
    const err = error as { response?: { data?: { error?: string; message?: string } }; message?: string };
    const errorMessage =
      err.response?.data?.error || err.response?.data?.message || err.message || "코드 미리보기 실패";
    return { success: false, error: errorMessage };
  }
}

/**
 * 코드 할당 (저장 시점에 실제 순번 증가)
 * 실제 저장할 때만 호출
 * @param ruleId 채번 규칙 ID
 * @param userInputCode 사용자가 편집한 최종 코드 (수동 입력 부분 추출용)
 * @param formData 폼 데이터 (카테고리/날짜 기반 채번용)
 */
export async function allocateNumberingCode(
  ruleId: string,
  userInputCode?: string,
  formData?: Record<string, any>,
): Promise<ApiResponse<{ generatedCode: string }>> {
  try {
    const response = await apiClient.post(`/numbering-rules/${ruleId}/allocate`, {
      userInputCode,
      formData,
    });
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message || "코드 할당 실패" };
  }
}

/**
 * @deprecated 기존 generateNumberingCode는 previewNumberingCode를 사용하세요
 */
export async function generateNumberingCode(ruleId: string): Promise<ApiResponse<{ generatedCode: string }>> {
  console.warn("generateNumberingCode는 deprecated. previewNumberingCode 사용 권장");
  return previewNumberingCode(ruleId);
}

// 하위 호환성을 위한 별칭
export const generateCode = generateNumberingCode;

export async function resetSequence(ruleId: string): Promise<ApiResponse<void>> {
  try {
    const response = await apiClient.post(`/numbering-rules/${ruleId}/reset`);
    return response.data;
  } catch (error: any) {
    return { success: false, error: error.message || "시퀀스 초기화 실패" };
  }
}

// ====== 테스트용 API (numbering_rules 테이블 사용) ======

/**
 * [테스트] 테스트 테이블에서 채번규칙 목록 조회
 * numbering_rules 테이블 사용
 * @param menuObjid 메뉴 OBJID (선택) - 필터링용
 */
export async function getNumberingRulesFromTest(menuObjid?: number): Promise<ApiResponse<NumberingRuleConfig[]>> {
  try {
    const url = menuObjid ? `/numbering-rules/test/list/${menuObjid}` : "/numbering-rules/test/list";
    const response = await apiClient.get(url);
    return response.data;
  } catch (error: any) {
    return {
      success: false,
      error: error.response?.data?.error || error.message || "테스트 규칙 목록 조회 실패",
    };
  }
}

/**
 * [테스트] 테이블+컬럼 기반 채번규칙 조회
 * numbering_rules 테이블 사용
 */
export async function getNumberingRuleByColumn(
  tableName: string,
  columnName: string,
): Promise<ApiResponse<NumberingRuleConfig>> {
  try {
    const response = await apiClient.get("/numbering-rules/test/by-column", {
      params: { tableName, columnName },
    });
    return response.data;
  } catch (error: any) {
    return {
      success: false,
      error: error.response?.data?.error || error.message || "테이블+컬럼 기반 규칙 조회 실패",
    };
  }
}

/**
 * [테스트] 테스트 테이블에 채번규칙 저장
 * numbering_rules 테이블 사용
 */
export async function saveNumberingRuleToTest(config: NumberingRuleConfig): Promise<ApiResponse<NumberingRuleConfig>> {
  try {
    const response = await apiClient.post("/numbering-rules/test/save", config);
    return response.data;
  } catch (error: any) {
    return {
      success: false,
      error: error.response?.data?.error || error.message || "테스트 규칙 저장 실패",
    };
  }
}

/**
 * [테스트] 테스트 테이블에서 채번규칙 삭제
 * numbering_rules 테이블 사용
 */
export async function deleteNumberingRuleFromTest(ruleId: string): Promise<ApiResponse<void>> {
  try {
    const response = await apiClient.delete(`/numbering-rules/test/${ruleId}`);
    return response.data;
  } catch (error: unknown) {
    const err = error as { response?: { data?: { error?: string } }; message?: string };
    return {
      success: false,
      error: err.response?.data?.error || err.message || "테스트 규칙 삭제 실패",
    };
  }
}

/**
 * [테스트] 카테고리 조건 포함 채번규칙 조회
 */
export async function getNumberingRuleByColumnWithCategory(
  tableName: string,
  columnName: string,
  categoryColumn?: string,
  categoryValueId?: number,
): Promise<ApiResponse<NumberingRuleConfig>> {
  try {
    const response = await apiClient.get("/numbering-rules/test/by-column-with-category", {
      params: { tableName, columnName, categoryColumn, categoryValueId },
    });
    return response.data;
  } catch (error: any) {
    return {
      success: false,
      error: error.response?.data?.error || error.message || "카테고리 조건 규칙 조회 실패",
    };
  }
}

/**
 * [테스트] 테이블.컬럼별 모든 채번규칙 조회 (카테고리 조건별)
 */
export async function getRulesByTableColumn(
  tableName: string,
  columnName: string,
): Promise<ApiResponse<NumberingRuleConfig[]>> {
  try {
    const response = await apiClient.get("/numbering-rules/test/rules-by-table-column", {
      params: { tableName, columnName },
    });
    return response.data;
  } catch (error: any) {
    return {
      success: false,
      error: error.response?.data?.error || error.message || "테이블.컬럼별 규칙 목록 조회 실패",
    };
  }
}
