/**
 * 테이블 관리 API
 * 테이블 컬럼 정보 조회 및 관리 기능
 */

import { apiClient, ApiResponse } from "./client";

// 컬럼 정보 타입 (백엔드와 일치)
export interface ColumnTypeInfo {
  tableName?: string;
  columnName: string;
  displayName: string;
  dataType: string;
  dbType: string;
  webType: string;
  inputType?: string; // text, number, entity, code, select, date, checkbox 등
  detailSettings: string;
  description?: string;
  isNullable: string;
  isPrimaryKey: boolean;
  defaultValue?: string;
  maxLength?: number;
  numericPrecision?: number;
  numericScale?: number;
  codeCategory?: string;
  codeValue?: string;
  referenceTable?: string;
  referenceColumn?: string;
  displayColumn?: string;
  displayOrder?: number;
  isVisible?: boolean;
}

// 테이블 정보 타입
export interface TableInfo {
  tableName: string;
  displayName: string;
  description: string;
  columnCount: number;
}

// 컬럼 설정 타입 (백엔드 API와 동일한 필드명 사용)
export interface ColumnSettings {
  columnName?: string;
  columnLabel: string;
  inputType: string; // 백엔드에서 inputType으로 받음
  detailSettings: string;
  codeCategory: string;
  codeValue: string;
  referenceTable: string;
  referenceColumn: string;
  displayColumn?: string;
  displayOrder?: number;
  isVisible?: boolean;
}

// 컬럼 리스트 페이지네이션 응답
export interface ColumnListData {
  columns: ColumnTypeInfo[];
  total: number;
  page: number;
  size: number;
  totalPages: number;
}

// API 응답 타입들
export interface TableListResponse extends ApiResponse<TableInfo[]> {}
export interface ColumnListResponse extends ApiResponse<ColumnListData> {}
export interface ColumnSettingsResponse extends ApiResponse<void> {}

/**
 * 테이블 관리 API 클래스
 */
class TableManagementApi {
  private readonly basePath = "/table-management";

  /**
   * 테이블 목록 조회
   */
  async getTableList(): Promise<TableListResponse> {
    try {
      const response = await apiClient.get(`${this.basePath}/tables`);
      return response.data;
    } catch (error: any) {
      console.error("❌ 테이블 목록 조회 실패:", error);
      return {
        success: false,
        message: error.response?.data?.message || error.message || "테이블 목록을 조회할 수 없습니다.",
        errorCode: error.response?.data?.errorCode,
      };
    }
  }

  /**
   * 특정 테이블의 컬럼 목록 조회
   */
  async getColumnList(tableName: string, size: number = 1000): Promise<ColumnListResponse> {
    try {
      const response = await apiClient.get(`${this.basePath}/tables/${tableName}/columns?size=${size}`);
      return response.data;
    } catch (error: any) {
      console.error(`❌ 테이블 '${tableName}' 컬럼 목록 조회 실패:`, error);
      return {
        success: false,
        message:
          error.response?.data?.message || error.message || `테이블 '${tableName}'의 컬럼 정보를 조회할 수 없습니다.`,
        errorCode: error.response?.data?.errorCode,
      };
    }
  }

  /**
   * 컬럼 타입 설정 저장
   */
  async updateColumnSettings(
    tableName: string,
    columnName: string,
    settings: ColumnSettings,
  ): Promise<ColumnSettingsResponse> {
    try {
      const response = await apiClient.put(`${this.basePath}/tables/${tableName}/columns/${columnName}`, settings);
      return response.data;
    } catch (error: any) {
      console.error(`❌ 컬럼 '${tableName}.${columnName}' 설정 저장 실패:`, error);
      return {
        success: false,
        message: error.response?.data?.message || error.message || "컬럼 설정을 저장할 수 없습니다.",
        errorCode: error.response?.data?.errorCode,
      };
    }
  }

  /**
   * 여러 컬럼 설정 일괄 저장
   */
  async updateMultipleColumnSettings(
    tableName: string,
    settingsArray: Array<{ columnName: string; settings: ColumnSettings }>,
  ): Promise<ColumnSettingsResponse> {
    try {
      const response = await apiClient.put(`${this.basePath}/tables/${tableName}/columns/batch`, {
        settings: settingsArray,
      });
      return response.data;
    } catch (error: any) {
      console.error(`❌ 테이블 '${tableName}' 컬럼 설정 일괄 저장 실패:`, error);
      return {
        success: false,
        message: error.response?.data?.message || error.message || "컬럼 설정을 일괄 저장할 수 없습니다.",
        errorCode: error.response?.data?.errorCode,
      };
    }
  }

  /**
   * 테이블 스키마 정보 조회 (컬럼 존재 여부 검증용)
   */
  async getTableSchema(tableName: string): Promise<ApiResponse<ColumnTypeInfo[]>> {
    try {
      const response = await apiClient.get(`${this.basePath}/tables/${tableName}/schema`);
      return response.data;
    } catch (error: any) {
      console.error(`❌ 테이블 '${tableName}' 스키마 조회 실패:`, error);
      return {
        success: false,
        message:
          error.response?.data?.message || error.message || `테이블 '${tableName}'의 스키마 정보를 조회할 수 없습니다.`,
        errorCode: error.response?.data?.errorCode,
      };
    }
  }

  /**
   * 테이블 존재 여부 확인
   */
  async checkTableExists(tableName: string): Promise<ApiResponse<{ exists: boolean }>> {
    try {
      const response = await apiClient.get(`${this.basePath}/tables/${tableName}/exists`);
      return response.data;
    } catch (error: any) {
      console.error(`❌ 테이블 '${tableName}' 존재 여부 확인 실패:`, error);
      return {
        success: false,
        message: error.response?.data?.message || error.message || "테이블 존재 여부를 확인할 수 없습니다.",
        errorCode: error.response?.data?.errorCode,
      };
    }
  }

  /**
   * 컬럼 웹타입 정보 조회 (화면관리 연동용)
   */
  async getColumnWebTypes(tableName: string): Promise<ApiResponse<ColumnTypeInfo[]>> {
    try {
      const response = await apiClient.get(`${this.basePath}/tables/${tableName}/web-types`);
      return response.data;
    } catch (error: any) {
      console.error(`❌ 테이블 '${tableName}' 웹타입 정보 조회 실패:`, error);
      return {
        success: false,
        message: error.response?.data?.message || error.message || "웹타입 정보를 조회할 수 없습니다.",
        errorCode: error.response?.data?.errorCode,
      };
    }
  }

  /**
   * 데이터베이스 연결 상태 확인
   */
  async checkDatabaseConnection(): Promise<ApiResponse<{ connected: boolean; message: string }>> {
    try {
      const response = await apiClient.get(`${this.basePath}/health`);
      return response.data;
    } catch (error: any) {
      console.error("❌ 데이터베이스 연결 상태 확인 실패:", error);
      return {
        success: false,
        message: error.response?.data?.message || error.message || "데이터베이스 연결 상태를 확인할 수 없습니다.",
        errorCode: error.response?.data?.errorCode,
      };
    }
  }

  // ========================================
  // 테이블 로그 시스템 API
  // ========================================

  /**
   * 로그 테이블 생성
   */
  async createLogTable(
    tableName: string,
    pkColumn: { columnName: string; dataType: string },
  ): Promise<ApiResponse<void>> {
    try {
      const response = await apiClient.post(`${this.basePath}/tables/${tableName}/log`, { pkColumn });
      return response.data;
    } catch (error: any) {
      console.error(`❌ 로그 테이블 생성 실패: ${tableName}`, error);
      return {
        success: false,
        message: error.response?.data?.message || error.message || "로그 테이블을 생성할 수 없습니다.",
        errorCode: error.response?.data?.errorCode,
      };
    }
  }

  /**
   * 로그 설정 조회
   */
  async getLogConfig(tableName: string): Promise<
    ApiResponse<{
      originalTableName: string;
      logTableName: string;
      triggerName: string;
      triggerFunctionName: string;
      isActive: string;
      createdAt: Date;
      createdBy: string;
    } | null>
  > {
    try {
      const response = await apiClient.get(`${this.basePath}/tables/${tableName}/log/config`);
      return response.data;
    } catch (error: any) {
      console.error(`❌ 로그 설정 조회 실패: ${tableName}`, error);
      return {
        success: false,
        message: error.response?.data?.message || error.message || "로그 설정을 조회할 수 없습니다.",
        errorCode: error.response?.data?.errorCode,
      };
    }
  }

  /**
   * 로그 데이터 조회
   */
  async getLogData(
    tableName: string,
    options: {
      page?: number;
      size?: number;
      operationType?: string;
      startDate?: string;
      endDate?: string;
      changedBy?: string;
      originalId?: string;
    } = {},
  ): Promise<
    ApiResponse<{
      data: any[];
      total: number;
      page: number;
      size: number;
      totalPages: number;
    }>
  > {
    try {
      const response = await apiClient.get(`${this.basePath}/tables/${tableName}/log`, {
        params: options,
      });
      return response.data;
    } catch (error: any) {
      console.error(`❌ 로그 데이터 조회 실패: ${tableName}`, error);
      return {
        success: false,
        message: error.response?.data?.message || error.message || "로그 데이터를 조회할 수 없습니다.",
        errorCode: error.response?.data?.errorCode,
      };
    }
  }

  /**
   * 로그 테이블 활성화/비활성화
   */
  async toggleLogTable(tableName: string, isActive: boolean): Promise<ApiResponse<void>> {
    try {
      const response = await apiClient.post(`${this.basePath}/tables/${tableName}/log/toggle`, {
        isActive,
      });
      return response.data;
    } catch (error: any) {
      console.error(`❌ 로그 테이블 토글 실패: ${tableName}`, error);
      return {
        success: false,
        message: error.response?.data?.message || error.message || "로그 테이블 설정을 변경할 수 없습니다.",
        errorCode: error.response?.data?.errorCode,
      };
    }
  }

  /**
   * 두 테이블 간의 엔티티 관계 자동 감지
   * column_labels에서 정의된 엔티티/카테고리 타입 설정을 기반으로
   * 두 테이블 간의 외래키 관계를 자동으로 감지합니다.
   */
  async getTableEntityRelations(
    leftTable: string,
    rightTable: string
  ): Promise<ApiResponse<{
    leftTable: string;
    rightTable: string;
    relations: Array<{
      leftColumn: string;
      rightColumn: string;
      direction: "left_to_right" | "right_to_left";
      inputType: string;
      displayColumn?: string;
    }>;
  }>> {
    try {
      const response = await apiClient.get(
        `${this.basePath}/tables/entity-relations?leftTable=${encodeURIComponent(leftTable)}&rightTable=${encodeURIComponent(rightTable)}`
      );
      return response.data;
    } catch (error: any) {
      console.error(`❌ 테이블 엔티티 관계 조회 실패: ${leftTable} <-> ${rightTable}`, error);
      return {
        success: false,
        message: error.response?.data?.message || error.message || "테이블 엔티티 관계를 조회할 수 없습니다.",
        errorCode: error.response?.data?.errorCode,
      };
    }
  }
}

// 싱글톤 인스턴스 생성
export const tableManagementApi = new TableManagementApi();

// 편의 함수들
export const getTableColumns = (tableName: string) => tableManagementApi.getColumnList(tableName);
export const updateColumnType = (tableName: string, columnName: string, settings: ColumnSettings) =>
  tableManagementApi.updateColumnSettings(tableName, columnName, settings);
export const checkTableExists = (tableName: string) => tableManagementApi.checkTableExists(tableName);

// 엑셀 업로드 전 데이터 검증 API
export interface ExcelValidationResult {
  isValid: boolean;
  notNullErrors: { row: number; column: string; label: string }[];
  uniqueInExcelErrors: { rows: number[]; column: string; label: string; value: string }[];
  uniqueInDbErrors: { row: number; column: string; label: string; value: string }[];
  summary: { notNull: number; uniqueInExcel: number; uniqueInDb: number };
}

export async function validateExcelData(
  tableName: string,
  data: Record<string, any>[]
): Promise<ApiResponse<ExcelValidationResult>> {
  try {
    const response = await apiClient.post<ApiResponse<ExcelValidationResult>>(
      "/table-management/validate-excel",
      { tableName, data }
    );
    return response.data;
  } catch (error: any) {
    return {
      success: false,
      message: error.response?.data?.message || "데이터 검증 실패",
    };
  }
}
