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

// 동적 폼 데이터 타입
export interface DynamicFormData {
  screenId: number;
  tableName: string;
  data: Record<string, any>;
}

// 폼 데이터 저장 응답 타입
export interface SaveFormDataResponse {
  id: number;
  success: boolean;
  message: string;
  data?: Record<string, any>;
}

// 폼 데이터 조회 응답 타입
export interface FormDataResponse {
  id: number;
  screenId: number;
  tableName: string;
  data: Record<string, any>;
  createdAt: string;
  updatedAt: string;
}

// 동적 폼 API 클래스
export class DynamicFormApi {
  /**
   * 폼 데이터 저장 (기존 버전 - 레거시 지원)
   * @param formData 저장할 폼 데이터
   * @returns 저장 결과
   */
  static async saveFormData(formData: DynamicFormData): Promise<ApiResponse<SaveFormDataResponse>> {
    try {
      const response = await apiClient.post("/dynamic-form/save", formData);
      return {
        success: true,
        data: response.data,
        message: "데이터가 성공적으로 저장되었습니다.",
      };
    } catch (error: any) {
      console.error("❌ 폼 데이터 저장 실패:", error);

      const errorMessage = error.response?.data?.message || error.message || "데이터 저장 중 오류가 발생했습니다.";

      return {
        success: false,
        message: errorMessage,
        errorCode: error.response?.data?.errorCode,
      };
    }
  }

  /**
   * 폼 데이터 저장 (개선된 버전)
   * @param formData 저장할 폼 데이터
   * @returns 저장 결과 (상세한 검증 정보 포함)
   */
  static async saveData(formData: DynamicFormData): Promise<ApiResponse<SaveFormDataResponse>> {
    try {
      const response = await apiClient.post("/dynamic-form/save-enhanced", formData);
      return response.data;
    } catch (error: any) {
      console.error("❌ 개선된 폼 데이터 저장 실패:", error);

      // 개선된 오류 처리
      const errorResponse = error.response?.data;
      if (errorResponse && !errorResponse.success) {
        return errorResponse; // 서버에서 온 구조화된 오류 응답 그대로 반환
      }

      const errorMessage = error.response?.data?.message || error.message || "데이터 저장 중 오류가 발생했습니다.";

      return {
        success: false,
        message: errorMessage,
        errorCode: error.response?.data?.errorCode,
      };
    }
  }

  /**
   * 폼 데이터 업데이트
   * @param id 레코드 ID
   * @param formData 업데이트할 폼 데이터
   * @returns 업데이트 결과
   */
  static async updateFormData(
    id: string | number,
    formData: Partial<DynamicFormData>,
  ): Promise<ApiResponse<SaveFormDataResponse>> {
    try {
      console.log("🔄 폼 데이터 업데이트 요청:", { id, formData });
      console.log("🌐 API URL:", `/dynamic-form/${id}`);
      console.log("📦 요청 본문:", JSON.stringify(formData, null, 2));

      const response = await apiClient.put(`/dynamic-form/${id}`, formData);

      console.log("✅ 폼 데이터 업데이트 성공:", response.data);
      console.log("📊 응답 상태:", response.status);
      console.log("📋 응답 헤더:", response.headers);
      
      return {
        success: true,
        data: response.data,
        message: "데이터가 성공적으로 업데이트되었습니다.",
      };
    } catch (error: any) {
      console.error("❌ 폼 데이터 업데이트 실패:", error);
      console.error("📊 에러 응답:", error.response?.data);
      console.error("📊 에러 상태:", error.response?.status);

      const errorMessage = error.response?.data?.message || error.message || "데이터 업데이트 중 오류가 발생했습니다.";

      return {
        success: false,
        message: errorMessage,
        errorCode: error.response?.data?.errorCode,
      };
    }
  }

  /**
   * 폼 데이터 부분 업데이트 (변경된 필드만)
   * @param id 레코드 ID
   * @param originalData 원본 데이터
   * @param newData 변경할 데이터
   * @param tableName 테이블명
   * @returns 업데이트 결과
   */
  static async updateFormDataPartial(
    id: string | number, // 🔧 UUID 문자열도 지원
    originalData: Record<string, any>,
    newData: Record<string, any>,
    tableName: string,
  ): Promise<ApiResponse<SaveFormDataResponse>> {
    try {
      console.log("🔄 폼 데이터 부분 업데이트 요청:", {
        id,
        originalData,
        newData,
        tableName,
      });

      const response = await apiClient.patch(`/dynamic-form/${id}/partial`, {
        tableName,
        originalData,
        newData,
      });

      console.log("✅ 폼 데이터 부분 업데이트 성공:", response.data);
      return {
        success: true,
        data: response.data,
        message: "데이터가 성공적으로 업데이트되었습니다.",
      };
    } catch (error: any) {
      console.error("❌ 폼 데이터 부분 업데이트 실패:", error);

      const errorMessage = error.response?.data?.message || error.message || "부분 업데이트 중 오류가 발생했습니다.";

      return {
        success: false,
        message: errorMessage,
        errorCode: error.response?.data?.errorCode,
      };
    }
  }

  /**
   * 폼 데이터 삭제
   * @param id 레코드 ID
   * @returns 삭제 결과
   */
  static async deleteFormData(id: number): Promise<ApiResponse<void>> {
    try {
      console.log("🗑️ 폼 데이터 삭제 요청:", id);

      await apiClient.delete(`/dynamic-form/${id}`);

      console.log("✅ 폼 데이터 삭제 성공");
      return {
        success: true,
        message: "데이터가 성공적으로 삭제되었습니다.",
      };
    } catch (error: any) {
      console.error("❌ 폼 데이터 삭제 실패:", error);

      const errorMessage = error.response?.data?.message || error.message || "데이터 삭제 중 오류가 발생했습니다.";

      return {
        success: false,
        message: errorMessage,
        errorCode: error.response?.data?.errorCode,
      };
    }
  }

  /**
   * 실제 테이블에서 폼 데이터 삭제
   * @param id 레코드 ID
   * @param tableName 테이블명
   * @param screenId 화면 ID (제어관리 실행용, 선택사항)
   * @returns 삭제 결과
   */
  static async deleteFormDataFromTable(
    id: string | number,
    tableName: string,
    screenId?: number
  ): Promise<ApiResponse<void>> {
    try {
      console.log("🗑️ 실제 테이블에서 폼 데이터 삭제 요청:", { id, tableName, screenId });

      await apiClient.delete(`/dynamic-form/${id}`, {
        data: { tableName, screenId },
      });

      console.log("✅ 실제 테이블에서 폼 데이터 삭제 성공");
      return {
        success: true,
        message: "데이터가 성공적으로 삭제되었습니다.",
      };
    } catch (error: any) {
      console.error("❌ 실제 테이블에서 폼 데이터 삭제 실패:", error);

      const errorMessage = error.response?.data?.message || error.message || "데이터 삭제 중 오류가 발생했습니다.";

      return {
        success: false,
        message: errorMessage,
        errorCode: error.response?.data?.errorCode,
      };
    }
  }

  /**
   * 폼 데이터 목록 조회
   * @param screenId 화면 ID
   * @param params 검색 파라미터
   * @returns 폼 데이터 목록
   */
  static async getFormDataList(
    screenId: number,
    params?: {
      page?: number;
      size?: number;
      search?: string;
      sortBy?: string;
      sortOrder?: "asc" | "desc";
    },
  ): Promise<
    ApiResponse<{
      content: FormDataResponse[];
      totalElements: number;
      totalPages: number;
      currentPage: number;
      size: number;
    }>
  > {
    try {
      console.log("📋 폼 데이터 목록 조회 요청:", { screenId, params });

      const response = await apiClient.get(`/dynamic-form/screen/${screenId}`, { params });

      console.log("✅ 폼 데이터 목록 조회 성공:", response.data);
      return {
        success: true,
        data: response.data,
      };
    } catch (error: any) {
      console.error("❌ 폼 데이터 목록 조회 실패:", error);

      const errorMessage = error.response?.data?.message || error.message || "데이터 조회 중 오류가 발생했습니다.";

      return {
        success: false,
        message: errorMessage,
        errorCode: error.response?.data?.errorCode,
      };
    }
  }

  /**
   * 특정 폼 데이터 조회
   * @param id 레코드 ID
   * @returns 폼 데이터
   */
  static async getFormData(id: number): Promise<ApiResponse<FormDataResponse>> {
    try {
      console.log("📄 폼 데이터 단건 조회 요청:", id);

      const response = await apiClient.get(`/dynamic-form/${id}`);

      console.log("✅ 폼 데이터 단건 조회 성공:", response.data);
      return {
        success: true,
        data: response.data,
      };
    } catch (error: any) {
      console.error("❌ 폼 데이터 단건 조회 실패:", error);

      const errorMessage = error.response?.data?.message || error.message || "데이터 조회 중 오류가 발생했습니다.";

      return {
        success: false,
        message: errorMessage,
        errorCode: error.response?.data?.errorCode,
      };
    }
  }

  /**
   * 테이블의 컬럼 정보 조회 (폼 검증용)
   * @param tableName 테이블명
   * @returns 컬럼 정보
   */
  static async getTableColumns(tableName: string): Promise<
    ApiResponse<{
      tableName: string;
      columns: Array<{
        columnName: string;
        dataType: string;
        nullable: boolean;
        primaryKey: boolean;
        maxLength?: number;
        defaultValue?: any;
      }>;
    }>
  > {
    try {
      console.log("📊 테이블 컬럼 정보 조회 요청:", tableName);

      const response = await apiClient.get(`/dynamic-form/table/${tableName}/columns`);

      console.log("✅ 테이블 컬럼 정보 조회 성공:", response.data);
      return {
        success: true,
        data: response.data,
      };
    } catch (error: any) {
      console.error("❌ 테이블 컬럼 정보 조회 실패:", error);

      const errorMessage = error.response?.data?.message || error.message || "테이블 정보 조회 중 오류가 발생했습니다.";

      return {
        success: false,
        message: errorMessage,
        errorCode: error.response?.data?.errorCode,
      };
    }
  }

  /**
   * 폼 데이터 검증
   * @param tableName 테이블명
   * @param data 검증할 데이터
   * @returns 검증 결과
   */
  static async validateFormData(
    tableName: string,
    data: Record<string, any>,
  ): Promise<
    ApiResponse<{
      valid: boolean;
      errors: Array<{
        field: string;
        message: string;
        code: string;
      }>;
    }>
  > {
    try {
      console.log("✅ 폼 데이터 검증 요청:", { tableName, data });

      const response = await apiClient.post(`/dynamic-form/validate`, {
        tableName,
        data,
      });

      console.log("✅ 폼 데이터 검증 성공:", response.data);
      return {
        success: true,
        data: response.data,
      };
    } catch (error: any) {
      console.error("❌ 폼 데이터 검증 실패:", error);

      const errorMessage = error.response?.data?.message || error.message || "데이터 검증 중 오류가 발생했습니다.";

      return {
        success: false,
        message: errorMessage,
        errorCode: error.response?.data?.errorCode,
      };
    }
  }

  /**
   * 테이블의 기본키 조회
   * @param tableName 테이블명
   * @returns 기본키 컬럼명 배열
   */
  static async getTablePrimaryKeys(tableName: string): Promise<ApiResponse<string[]>> {
    try {
      const response = await apiClient.get(`/dynamic-form/table/${tableName}/primary-keys`);
      return {
        success: true,
        data: response.data.data,
        message: "기본키 조회가 완료되었습니다.",
      };
    } catch (error: any) {
      console.error("❌ 테이블 기본키 조회 실패:", error);

      const errorMessage = error.response?.data?.message || error.message || "기본키 조회 중 오류가 발생했습니다.";

      return {
        success: false,
        message: errorMessage,
        errorCode: error.response?.data?.errorCode,
      };
    }
  }

  /**
   * 테이블 데이터 조회 (페이징 + 검색)
   * @param tableName 테이블명
   * @param params 검색 파라미터
   * @returns 테이블 데이터
   */
  static async getTableData(
    tableName: string,
    params?: {
      page?: number;
      pageSize?: number;
      search?: string;
      sortBy?: string;
      sortOrder?: "asc" | "desc";
      filters?: Record<string, any>;
      autoFilter?: {
        enabled: boolean;
        filterColumn?: string;
        userField?: string;
      };
    },
  ): Promise<ApiResponse<any[]>> {
    try {
      console.log("📊 테이블 데이터 조회 요청:", { tableName, params });

      // autoFilter가 없으면 기본값으로 멀티테넌시 필터 적용
      // pageSize를 size로 변환 (백엔드 파라미터명 호환)
      const requestParams = {
        ...params,
        size: params?.pageSize || params?.size || 100, // 기본값 100
        autoFilter: params?.autoFilter ?? {
          enabled: true,
          filterColumn: "company_code",
          userField: "companyCode",
        },
      };

      const response = await apiClient.post(`/table-management/tables/${tableName}/data`, requestParams);

      console.log("✅ 테이블 데이터 조회 성공 (원본):", response.data);
      console.log("🔍 response.data 상세:", {
        type: typeof response.data,
        isArray: Array.isArray(response.data),
        keys: response.data ? Object.keys(response.data) : [],
        hasData: response.data?.data !== undefined,
        dataType: response.data?.data ? typeof response.data.data : "N/A",
        dataIsArray: response.data?.data ? Array.isArray(response.data.data) : false,
        dataLength: response.data?.data ? (Array.isArray(response.data.data) ? response.data.data.length : "not array") : "no data",
        // 중첩 구조 확인
        dataDataExists: response.data?.data?.data !== undefined,
        dataDataIsArray: response.data?.data?.data ? Array.isArray(response.data.data.data) : false,
        dataDataLength: response.data?.data?.data ? (Array.isArray(response.data.data.data) ? response.data.data.data.length : "not array") : "no nested data",
      });

      // API 응답 구조: { data: [...], total, page, size, totalPages }
      // 또는 중첩: { success: true, data: { data: [...], total, ... } }
      // data 배열만 추출
      let tableData: any[] = [];
      
      if (Array.isArray(response.data)) {
        // 케이스 1: 응답이 배열이면 그대로 사용
        console.log("✅ 케이스 1: 응답이 배열");
        tableData = response.data;
      } else if (response.data && Array.isArray(response.data.data)) {
        // 케이스 2: 응답이 { data: [...] } 구조면 data 배열 추출
        console.log("✅ 케이스 2: 응답이 { data: [...] } 구조");
        tableData = response.data.data;
      } else if (response.data?.data?.data && Array.isArray(response.data.data.data)) {
        // 케이스 2-1: 중첩 구조 { success: true, data: { data: [...] } }
        console.log("✅ 케이스 2-1: 중첩 구조 { data: { data: [...] } }");
        tableData = response.data.data.data;
      } else if (response.data && typeof response.data === "object") {
        // 케이스 3: 응답이 객체면 배열로 감싸기 (최후의 수단)
        console.log("⚠️ 케이스 3: 응답이 객체 (배열로 감싸기)");
        tableData = [response.data];
      }

      console.log("✅ 테이블 데이터 추출 완료:", {
        originalType: typeof response.data,
        isArray: Array.isArray(response.data),
        hasDataProperty: response.data?.data !== undefined,
        extractedCount: tableData.length,
        firstRow: tableData[0],
        allRows: tableData,
      });

      return {
        success: true,
        data: tableData,
        message: "테이블 데이터 조회가 완료되었습니다.",
      };
    } catch (error: any) {
      console.error("❌ 테이블 데이터 조회 실패:", error);

      const errorMessage = error.response?.data?.message || error.message || "테이블 데이터 조회 중 오류가 발생했습니다.";

      return {
        success: false,
        message: errorMessage,
        errorCode: error.response?.data?.errorCode,
      };
    }
  }

  /**
   * 엑셀 업로드 (대량 데이터 삽입/업데이트)
   * @param payload 업로드 데이터
   * @returns 업로드 결과
   */
  static async uploadExcelData(payload: {
    tableName: string;
    data: any[];
    uploadMode: "insert" | "update" | "upsert";
    keyColumn?: string;
  }): Promise<ApiResponse<any>> {
    try {
      console.log("📤 엑셀 업로드 요청:", payload);

      const response = await apiClient.post(`/dynamic-form/excel-upload`, payload);

      console.log("✅ 엑셀 업로드 성공:", response.data);
      return {
        success: true,
        data: response.data,
        message: "엑셀 파일이 성공적으로 업로드되었습니다.",
      };
    } catch (error: any) {
      console.error("❌ 엑셀 업로드 실패:", error);

      const errorMessage = error.response?.data?.message || error.message || "엑셀 업로드 중 오류가 발생했습니다.";

      return {
        success: false,
        message: errorMessage,
        errorCode: error.response?.data?.errorCode,
      };
    }
  }

  // ================================
  // 마스터-디테일 엑셀 API
  // ================================

  /**
   * 마스터-디테일 관계 정보 조회
   * @param screenId 화면 ID
   * @returns 마스터-디테일 관계 정보 (null이면 마스터-디테일 구조 아님)
   */
  static async getMasterDetailRelation(screenId: number): Promise<ApiResponse<MasterDetailRelation | null>> {
    try {
      console.log("🔍 마스터-디테일 관계 조회:", screenId);

      const response = await apiClient.get(`/data/master-detail/relation/${screenId}`);

      return {
        success: true,
        data: response.data?.data || null,
        message: response.data?.message || "조회 완료",
      };
    } catch (error: any) {
      console.error("❌ 마스터-디테일 관계 조회 실패:", error);
      return {
        success: false,
        data: null,
        message: error.response?.data?.message || error.message,
      };
    }
  }

  /**
   * 마스터-디테일 엑셀 다운로드 데이터 조회
   * @param screenId 화면 ID
   * @param filters 필터 조건
   * @returns JOIN된 플랫 데이터
   */
  static async getMasterDetailDownloadData(
    screenId: number,
    filters?: Record<string, any>
  ): Promise<ApiResponse<MasterDetailDownloadData>> {
    try {
      console.log("📥 마스터-디테일 다운로드 데이터 조회:", { screenId, filters });

      const response = await apiClient.post(`/data/master-detail/download`, {
        screenId,
        filters,
      });

      return {
        success: true,
        data: response.data?.data,
        message: "데이터 조회 완료",
      };
    } catch (error: any) {
      console.error("❌ 마스터-디테일 다운로드 실패:", error);
      return {
        success: false,
        message: error.response?.data?.message || error.message,
      };
    }
  }

  /**
   * 마스터-디테일 엑셀 업로드
   * @param screenId 화면 ID
   * @param data 엑셀에서 읽은 플랫 데이터
   * @returns 업로드 결과
   */
  static async uploadMasterDetailData(
    screenId: number,
    data: Record<string, any>[]
  ): Promise<ApiResponse<MasterDetailUploadResult>> {
    try {
      console.log("📤 마스터-디테일 업로드:", { screenId, rowCount: data.length });

      const response = await apiClient.post(`/data/master-detail/upload`, {
        screenId,
        data,
      });

      return {
        success: response.data?.success,
        data: response.data?.data,
        message: response.data?.message,
      };
    } catch (error: any) {
      console.error("❌ 마스터-디테일 업로드 실패:", error);
      return {
        success: false,
        message: error.response?.data?.message || error.message,
      };
    }
  }

  /**
   * 마스터-디테일 간단 모드 엑셀 업로드
   * - 마스터 정보는 UI에서 선택
   * - 디테일 정보만 엑셀에서 업로드
   * - 채번 규칙을 통해 마스터 키 자동 생성
   * @param screenId 화면 ID
   * @param detailData 디테일 데이터 배열
   * @param masterFieldValues UI에서 선택한 마스터 필드 값
   * @param numberingRuleId 채번 규칙 ID (optional)
   * @param afterUploadFlowId 업로드 후 실행할 제어 ID (optional, 하위 호환성)
   * @param afterUploadFlows 업로드 후 실행할 제어 목록 (optional)
   * @returns 업로드 결과
   */
  static async uploadMasterDetailSimple(
    screenId: number,
    detailData: Record<string, any>[],
    masterFieldValues: Record<string, any>,
    numberingRuleId?: string,
    afterUploadFlowId?: string,
    afterUploadFlows?: Array<{ flowId: string; order: number }>
  ): Promise<ApiResponse<MasterDetailSimpleUploadResult>> {
    try {
      console.log("📤 마스터-디테일 간단 모드 업로드:", {
        screenId,
        detailRowCount: detailData.length,
        masterFieldValues,
        numberingRuleId,
        afterUploadFlows: afterUploadFlows?.length || 0,
      });

      const response = await apiClient.post(`/data/master-detail/upload-simple`, {
        screenId,
        detailData,
        masterFieldValues,
        numberingRuleId,
        afterUploadFlowId,
        afterUploadFlows,
      });

      return {
        success: response.data?.success,
        data: response.data?.data,
        message: response.data?.message,
      };
    } catch (error: any) {
      console.error("❌ 마스터-디테일 간단 모드 업로드 실패:", error);
      return {
        success: false,
        message: error.response?.data?.message || error.message,
      };
    }
  }
}

// 마스터-디테일 관계 타입
export interface MasterDetailRelation {
  masterTable: string;
  detailTable: string;
  masterKeyColumn: string;
  detailFkColumn: string;
  masterColumns: Array<{ name: string; label: string; inputType: string; isFromMaster: boolean }>;
  detailColumns: Array<{ name: string; label: string; inputType: string; isFromMaster: boolean }>;
}

// 마스터-디테일 다운로드 데이터 타입
export interface MasterDetailDownloadData {
  headers: string[];
  columns: string[];
  data: Record<string, any>[];
  masterColumns: string[];
  detailColumns: string[];
  joinKey: string;
}

// 마스터-디테일 업로드 결과 타입
export interface MasterDetailUploadResult {
  success: boolean;
  masterInserted: number;
  masterUpdated: number;
  detailInserted: number;
  detailDeleted: number;
  errors: string[];
}

// 🆕 마스터-디테일 간단 모드 업로드 결과 타입
export interface MasterDetailSimpleUploadResult {
  success: boolean;
  masterInserted: number;
  detailInserted: number;
  generatedKey: string; // 생성된 마스터 키
  errors?: string[];
}

// 편의를 위한 기본 export
export const dynamicFormApi = DynamicFormApi;
