/**
 * 🌐 API 연동 타입 안전성 테스트
 *
 * 실제 백엔드 API와 연동하여 타입 안전성을 검증합니다.
 */

import { apiClient } from "@/lib/api/client";
import {
  ComponentData,
  WidgetComponent,
  ScreenDefinition,
  LayoutData,
  TableInfo,
  V2ColumnInfo,
  ColumnTypeInfo,
  ButtonActionType,
  WebType,
  isWebType,
  isButtonActionType,
  ynToBoolean,
  booleanToYN,
} from "@/types";

export class APIIntegrationTestSuite {
  /**
   * 🧪 Test 1: 테이블 정보 API 타입 안전성
   */
  static async testTableInfoAPI() {
    console.log("🧪 API Test 1: 테이블 정보 API 타입 안전성");

    try {
      // 실제 API 호출
      const response = await apiClient.get("/api/admin/table-management/tables", {
        params: { companyCode: "COMPANY_1" },
      });

      if (response.data && Array.isArray(response.data)) {
        const tables = response.data as TableInfo[];

        tables.forEach((table, index) => {
          // 필수 필드 검증
          console.assert(typeof table.tableName === "string", `테이블 ${index}: tableName이 문자열이 아님`);
          console.assert(typeof table.tableLabel === "string", `테이블 ${index}: tableLabel이 문자열이 아님`);

          if (table.columns && Array.isArray(table.columns)) {
            table.columns.forEach((column, colIndex) => {
              // 컬럼 타입 검증
              console.assert(
                typeof column.columnName === "string",
                `테이블 ${index}, 컬럼 ${colIndex}: columnName이 문자열이 아님`,
              );

              // WebType 안전성 검증
              if (column.webType) {
                const isValidWebType = isWebType(column.webType);
                if (!isValidWebType) {
                  console.warn(
                    `테이블 ${table.tableName}, 컬럼 ${column.columnName}: 유효하지 않은 webType: ${column.webType}`,
                  );
                }
              }
            });
          }
        });

        console.log(`✅ 테이블 정보 API: ${tables.length}개 테이블 검증 완료`);
        return true;
      }
    } catch (error) {
      console.error("❌ 테이블 정보 API 테스트 실패:", error);
      return false;
    }
  }

  /**
   * 🧪 Test 2: 컬럼 타입 정보 API 호환성
   */
  static async testColumnTypeAPI() {
    console.log("🧪 API Test 2: 컬럼 타입 정보 API 호환성");

    try {
      const response = await apiClient.get("/api/admin/table-management/columns", {
        params: {
          tableName: "user_info",
          companyCode: "COMPANY_1",
        },
      });

      if (response.data && Array.isArray(response.data)) {
        const columns = response.data as ColumnTypeInfo[];

        // 백엔드 타입을 프론트엔드 통합 타입으로 변환 테스트
        const v2Columns: V2ColumnInfo[] = columns.map((col) => ({
          columnName: col.columnName,
          displayName: col.displayName,
          dataType: col.dataType,
          dbType: col.dbType,
          webType: isWebType(col.webType) ? (col.webType as WebType) : "text",
          inputType: col.inputType || "direct",
          detailSettings: col.detailSettings ? JSON.parse(col.detailSettings) : {},
          description: col.description || "",
          isNullable: ynToBoolean(col.isNullable),
          isPrimaryKey: col.isPrimaryKey,
          defaultValue: col.defaultValue,
          maxLength: col.maxLength,
          companyCode: col.companyCode,
        }));

        // 변환 검증
        v2Columns.forEach((v2Col, index) => {
          const originalCol = columns[index];

          // WebType 변환 검증
          console.assert(isWebType(v2Col.webType), `컬럼 ${v2Col.columnName}: WebType 변환 실패`);

          // Y/N → boolean 변환 검증
          console.assert(
            typeof v2Col.isNullable === "boolean",
            `컬럼 ${v2Col.columnName}: isNullable boolean 변환 실패`,
          );

          // JSON 파싱 검증
          console.assert(
            typeof v2Col.detailSettings === "object",
            `컬럼 ${v2Col.columnName}: detailSettings 객체 변환 실패`,
          );
        });

        console.log(`✅ 컬럼 타입 API: ${v2Columns.length}개 컬럼 변환 완료`);
        return true;
      }
    } catch (error) {
      console.error("❌ 컬럼 타입 API 테스트 실패:", error);
      return false;
    }
  }

  /**
   * 🧪 Test 3: 화면 정의 저장/불러오기 API
   */
  static async testScreenDefinitionAPI() {
    console.log("🧪 API Test 3: 화면 정의 저장/불러오기 API");

    try {
      // 테스트용 화면 정의 생성
      const testScreenDefinition: ScreenDefinition = {
        screenId: 9999, // 테스트용 임시 ID
        screenName: "API 테스트 화면",
        screenCode: "API_TEST_SCREEN",
        tableName: "test_table",
        tableLabel: "테스트 테이블",
        description: "API 타입 안전성 테스트용 화면",
        isActive: "Y",
        layoutData: {
          screenId: 9999,
          components: [
            {
              id: "testWidget",
              type: "widget",
              widgetType: "text",
              position: { x: 10, y: 10 },
              size: { width: 200, height: 40 },
              label: "테스트 입력",
              columnName: "test_column",
              required: true,
              webTypeConfig: { maxLength: 100 },
            } as WidgetComponent,
          ],
          gridSettings: {
            enabled: true,
            size: 10,
            snapToGrid: true,
            showGrid: true,
            color: "#e0e0e0",
            opacity: 0.5,
          },
        },
      };

      // 화면 정의 저장 시도
      const saveResponse = await apiClient.post("/api/admin/screen-management/screens", testScreenDefinition);

      if (saveResponse.status === 200 || saveResponse.status === 201) {
        console.log("✅ 화면 정의 저장 성공");

        // 저장된 화면 불러오기 시도
        const loadResponse = await apiClient.get(
          `/api/admin/screen-management/screens/${testScreenDefinition.screenId}`,
        );

        if (loadResponse.data) {
          const loadedScreen = loadResponse.data as ScreenDefinition;

          // 데이터 무결성 검증
          console.assert(loadedScreen.screenName === testScreenDefinition.screenName, "화면명 불일치");
          console.assert(loadedScreen.layoutData.components.length > 0, "컴포넌트 데이터 손실");

          // 컴포넌트 타입 안전성 검증
          loadedScreen.layoutData.components.forEach((component) => {
            if (component.type === "widget") {
              const widget = component as WidgetComponent;
              console.assert(isWebType(widget.widgetType), `위젯 타입 검증 실패: ${widget.widgetType}`);
            }
          });

          console.log("✅ 화면 정의 불러오기 및 검증 완료");
        }

        // 테스트 데이터 정리
        try {
          await apiClient.delete(`/api/admin/screen-management/screens/${testScreenDefinition.screenId}`);
          console.log("✅ 테스트 데이터 정리 완료");
        } catch (cleanupError) {
          console.warn("⚠️ 테스트 데이터 정리 실패 (정상적일 수 있음):", cleanupError);
        }

        return true;
      }
    } catch (error) {
      console.error("❌ 화면 정의 API 테스트 실패:", error);
      return false;
    }
  }

  /**
   * 🧪 Test 4: 폼 데이터 저장 API 타입 안전성
   */
  static async testFormDataSaveAPI() {
    console.log("🧪 API Test 4: 폼 데이터 저장 API 타입 안전성");

    try {
      // 다양한 웹타입의 폼 데이터 준비
      const formData = {
        textField: "테스트 텍스트",
        numberField: 123,
        booleanField: true,
        dateField: "2024-01-01",
        selectField: "option1",
        emailField: "test@example.com",
      };

      // 컴포넌트 정의 (폼 구조)
      const formComponents: WidgetComponent[] = [
        {
          id: "textField",
          type: "widget",
          widgetType: "text",
          position: { x: 0, y: 0 },
          size: { width: 200, height: 40 },
          label: "텍스트",
          columnName: "text_column",
          webTypeConfig: {},
        },
        {
          id: "numberField",
          type: "widget",
          widgetType: "number",
          position: { x: 0, y: 50 },
          size: { width: 200, height: 40 },
          label: "숫자",
          columnName: "number_column",
          webTypeConfig: {},
        },
        {
          id: "booleanField",
          type: "widget",
          widgetType: "checkbox",
          position: { x: 0, y: 100 },
          size: { width: 200, height: 40 },
          label: "체크박스",
          columnName: "boolean_column",
          webTypeConfig: {},
        },
      ];

      // 타입 안전한 데이터 변환
      const processedData: Record<string, any> = {};

      formComponents.forEach((component) => {
        const fieldValue = formData[component.id as keyof typeof formData];

        if (fieldValue !== undefined && component.columnName) {
          switch (component.widgetType) {
            case "text":
            case "email":
              processedData[component.columnName] = String(fieldValue);
              break;

            case "number":
              processedData[component.columnName] = Number(fieldValue);
              break;

            case "checkbox":
            case "boolean":
              processedData[component.columnName] = booleanToYN(Boolean(fieldValue));
              break;

            case "date":
              processedData[component.columnName] = fieldValue ? String(fieldValue) : null;
              break;

            default:
              processedData[component.columnName] = fieldValue;
          }
        }
      });

      // 실제 API 호출 시뮬레이션 (일반적인 폼 저장 엔드포인트)
      console.log("📤 처리된 폼 데이터:", processedData);

      // 타입 검증
      console.assert(typeof processedData.text_column === "string", "텍스트 필드 타입 오류");
      console.assert(typeof processedData.number_column === "number", "숫자 필드 타입 오류");
      console.assert(
        processedData.boolean_column === "Y" || processedData.boolean_column === "N",
        "불린 필드 Y/N 변환 오류",
      );

      console.log("✅ 폼 데이터 저장 타입 안전성 검증 완료");
      return true;
    } catch (error) {
      console.error("❌ 폼 데이터 저장 API 테스트 실패:", error);
      return false;
    }
  }

  /**
   * 🧪 Test 5: 버튼 액션 실행 API 타입 안전성
   */
  static async testButtonActionAPI() {
    console.log("🧪 API Test 5: 버튼 액션 실행 API 타입 안전성");

    try {
      const buttonActions: ButtonActionType[] = [
        "save",
        "cancel",
        "delete",
        "edit",
        "add",
        "search",
        "reset",
        "submit",
        "close",
        "popup",
        "modal",
        "navigate",
        "control",
      ];

      // 각 버튼 액션 타입 검증
      buttonActions.forEach((action) => {
        console.assert(isButtonActionType(action), `유효하지 않은 버튼 액션: ${action}`);
      });

      // 잘못된 액션 타입들 검증
      const invalidActions = ["insert", "update", "remove", ""];
      invalidActions.forEach((action) => {
        console.assert(!isButtonActionType(action), `잘못된 액션이 허용됨: ${action}`);
      });

      console.log("✅ 버튼 액션 타입 안전성 검증 완료");
      return true;
    } catch (error) {
      console.error("❌ 버튼 액션 API 테스트 실패:", error);
      return false;
    }
  }

  /**
   * 🎯 모든 API 연동 테스트 실행
   */
  static async runAllAPITests() {
    console.log("🎯 API 연동 타입 안전성 테스트 시작\n");

    const results = {
      tableInfoAPI: false,
      columnTypeAPI: false,
      screenDefinitionAPI: false,
      formDataSaveAPI: false,
      buttonActionAPI: false,
    };

    try {
      results.tableInfoAPI = await this.testTableInfoAPI();
      results.columnTypeAPI = await this.testColumnTypeAPI();
      results.screenDefinitionAPI = await this.testScreenDefinitionAPI();
      results.formDataSaveAPI = await this.testFormDataSaveAPI();
      results.buttonActionAPI = await this.testButtonActionAPI();

      const passedTests = Object.values(results).filter(Boolean).length;
      const totalTests = Object.keys(results).length;

      console.log(`\n🎉 API 연동 테스트 완료: ${passedTests}/${totalTests} 통과`);

      if (passedTests === totalTests) {
        console.log("✅ 모든 API 연동 타입 안전성 테스트 통과!");
      } else {
        console.log("⚠️ 일부 API 연동 테스트 실패");
      }

      return {
        success: passedTests === totalTests,
        passedTests,
        totalTests,
        results,
      };
    } catch (error) {
      console.error("❌ API 연동 테스트 실행 실패:", error);
      return {
        success: false,
        passedTests: 0,
        totalTests: Object.keys(results).length,
        results,
        error: String(error),
      };
    }
  }
}

export default APIIntegrationTestSuite;
