/**
 * 🔥 버튼 제어관리 성능 검증 스크립트
 *
 * 실제 환경에서 성능 목표 달성 여부를 확인합니다.
 *
 * 사용법:
 * npm run performance-test
 */

import { optimizedButtonDataflowService } from "../lib/services/optimizedButtonDataflowService";
import { dataflowConfigCache } from "../lib/services/dataflowCache";
import { dataflowJobQueue } from "../lib/services/dataflowJobQueue";
import { PerformanceBenchmark } from "../lib/services/__tests__/buttonDataflowPerformance.test";
import { ButtonActionType, ButtonTypeConfig } from "../types/screen";

// 🔥 성능 목표 상수
const PERFORMANCE_TARGETS = {
  IMMEDIATE_RESPONSE: 200, // ms
  CACHE_HIT: 10, // ms
  SIMPLE_VALIDATION: 50, // ms
  QUEUE_ENQUEUE: 5, // ms
  CACHE_HIT_RATE: 80, // %
} as const;

/**
 * 🔥 메인 성능 테스트 실행
 */
async function runPerformanceTests() {
  console.log("🔥 Button Dataflow Performance Verification");
  console.log("==========================================\n");

  const benchmark = new PerformanceBenchmark();
  let totalTests = 0;
  let passedTests = 0;

  try {
    // 1. 캐시 성능 테스트
    console.log("📊 Testing Cache Performance...");
    const cacheResults = await testCachePerformance(benchmark);
    totalTests += cacheResults.total;
    passedTests += cacheResults.passed;

    // 2. 버튼 실행 성능 테스트
    console.log("\n⚡ Testing Button Execution Performance...");
    const buttonResults = await testButtonExecutionPerformance(benchmark);
    totalTests += buttonResults.total;
    passedTests += buttonResults.passed;

    // 3. 큐 성능 테스트
    console.log("\n🚀 Testing Job Queue Performance...");
    const queueResults = await testJobQueuePerformance(benchmark);
    totalTests += queueResults.total;
    passedTests += queueResults.passed;

    // 4. 통합 성능 테스트
    console.log("\n🔧 Testing Integration Performance...");
    const integrationResults = await testIntegrationPerformance(benchmark);
    totalTests += integrationResults.total;
    passedTests += integrationResults.passed;

    // 최종 결과 출력
    console.log("\n" + "=".repeat(50));
    console.log("🎯 PERFORMANCE TEST SUMMARY");
    console.log("=".repeat(50));
    console.log(`Total Tests: ${totalTests}`);
    console.log(`Passed: ${passedTests} (${((passedTests / totalTests) * 100).toFixed(1)}%)`);
    console.log(`Failed: ${totalTests - passedTests}`);

    // 벤치마크 리포트
    benchmark.printReport();

    // 성공/실패 판정
    const successRate = (passedTests / totalTests) * 100;
    if (successRate >= 90) {
      console.log("\n🎉 PERFORMANCE VERIFICATION PASSED!");
      console.log("All performance targets have been met.");
      process.exit(0);
    } else {
      console.log("\n⚠️  PERFORMANCE VERIFICATION FAILED!");
      console.log("Some performance targets were not met.");
      process.exit(1);
    }
  } catch (error) {
    console.error("\n❌ Performance test failed:", error);
    process.exit(1);
  }
}

/**
 * 캐시 성능 테스트
 */
async function testCachePerformance(benchmark: PerformanceBenchmark) {
  let total = 0;
  let passed = 0;

  // 캐시 초기화
  dataflowConfigCache.clearAllCache();

  // 1. 첫 번째 로드 성능 (서버 호출)
  total++;
  try {
    const time = await benchmark.measure("Cache First Load", async () => {
      return await dataflowConfigCache.getConfig("perf-test-1");
    });

    // 첫 로드는 1초 이내면 통과
    if (benchmark.getResults().details.slice(-1)[0].time < 1000) {
      passed++;
      console.log("  ✅ First load performance: PASSED");
    } else {
      console.log("  ❌ First load performance: FAILED");
    }
  } catch (error) {
    console.log("  ❌ First load test: ERROR -", error.message);
  }

  // 2. 캐시 히트 성능
  total++;
  try {
    await benchmark.measure("Cache Hit Performance", async () => {
      return await dataflowConfigCache.getConfig("perf-test-1");
    });

    const hitTime = benchmark.getResults().details.slice(-1)[0].time;
    if (hitTime < PERFORMANCE_TARGETS.CACHE_HIT) {
      passed++;
      console.log(`  ✅ Cache hit performance: PASSED (${hitTime.toFixed(2)}ms < ${PERFORMANCE_TARGETS.CACHE_HIT}ms)`);
    } else {
      console.log(`  ❌ Cache hit performance: FAILED (${hitTime.toFixed(2)}ms >= ${PERFORMANCE_TARGETS.CACHE_HIT}ms)`);
    }
  } catch (error) {
    console.log("  ❌ Cache hit test: ERROR -", error.message);
  }

  // 3. 캐시 히트율 테스트
  total++;
  try {
    // 여러 버튼에 대해 캐시 로드 및 히트 테스트
    const buttonIds = Array.from({ length: 10 }, (_, i) => `perf-test-${i}`);

    // 첫 번째 로드 (캐시 채우기)
    await Promise.all(buttonIds.map((id) => dataflowConfigCache.getConfig(id)));

    // 두 번째 로드 (캐시 히트)
    await Promise.all(buttonIds.map((id) => dataflowConfigCache.getConfig(id)));

    const metrics = dataflowConfigCache.getMetrics();
    if (metrics.hitRate >= PERFORMANCE_TARGETS.CACHE_HIT_RATE) {
      passed++;
      console.log(
        `  ✅ Cache hit rate: PASSED (${metrics.hitRate.toFixed(1)}% >= ${PERFORMANCE_TARGETS.CACHE_HIT_RATE}%)`,
      );
    } else {
      console.log(
        `  ❌ Cache hit rate: FAILED (${metrics.hitRate.toFixed(1)}% < ${PERFORMANCE_TARGETS.CACHE_HIT_RATE}%)`,
      );
    }
  } catch (error) {
    console.log("  ❌ Cache hit rate test: ERROR -", error.message);
  }

  return { total, passed };
}

/**
 * 버튼 실행 성능 테스트
 */
async function testButtonExecutionPerformance(benchmark: PerformanceBenchmark) {
  let total = 0;
  let passed = 0;

  const mockConfig: ButtonTypeConfig = {
    actionType: "save" as ButtonActionType,
    enableDataflowControl: true,
    dataflowTiming: "after",
    dataflowConfig: {
      controlMode: "simple",
      selectedDiagramId: 1,
      selectedRelationshipId: "rel-123",
    },
  };

  // 1. After 타이밍 성능 테스트
  total++;
  try {
    await benchmark.measure("Button Execution (After)", async () => {
      return await optimizedButtonDataflowService.executeButtonWithDataflow(
        "perf-button-1",
        "save",
        mockConfig,
        { testData: "value" },
        "DEFAULT",
      );
    });

    const execTime = benchmark.getResults().details.slice(-1)[0].time;
    if (execTime < PERFORMANCE_TARGETS.IMMEDIATE_RESPONSE) {
      passed++;
      console.log(
        `  ✅ After timing execution: PASSED (${execTime.toFixed(2)}ms < ${PERFORMANCE_TARGETS.IMMEDIATE_RESPONSE}ms)`,
      );
    } else {
      console.log(
        `  ❌ After timing execution: FAILED (${execTime.toFixed(2)}ms >= ${PERFORMANCE_TARGETS.IMMEDIATE_RESPONSE}ms)`,
      );
    }
  } catch (error) {
    console.log("  ❌ After timing test: ERROR -", error.message);
  }

  // 2. Before 타이밍 (간단한 검증) 성능 테스트
  total++;
  try {
    const beforeConfig = {
      ...mockConfig,
      dataflowTiming: "before" as const,
      dataflowConfig: {
        controlMode: "advanced" as const,
        directControl: {
          sourceTable: "test_table",
          triggerType: "insert" as const,
          conditions: [
            {
              id: "cond1",
              type: "condition" as const,
              field: "status",
              operator: "=" as const,
              value: "active",
            },
          ],
          actions: [],
        },
      },
    };

    await benchmark.measure("Button Execution (Before Simple)", async () => {
      return await optimizedButtonDataflowService.executeButtonWithDataflow(
        "perf-button-2",
        "save",
        beforeConfig,
        { status: "active" },
        "DEFAULT",
      );
    });

    const execTime = benchmark.getResults().details.slice(-1)[0].time;
    if (execTime < PERFORMANCE_TARGETS.SIMPLE_VALIDATION) {
      passed++;
      console.log(
        `  ✅ Before simple validation: PASSED (${execTime.toFixed(2)}ms < ${PERFORMANCE_TARGETS.SIMPLE_VALIDATION}ms)`,
      );
    } else {
      console.log(
        `  ❌ Before simple validation: FAILED (${execTime.toFixed(2)}ms >= ${PERFORMANCE_TARGETS.SIMPLE_VALIDATION}ms)`,
      );
    }
  } catch (error) {
    console.log("  ❌ Before timing test: ERROR -", error.message);
  }

  // 3. 제어관리 없는 실행 성능
  total++;
  try {
    const noDataflowConfig = {
      ...mockConfig,
      enableDataflowControl: false,
    };

    await benchmark.measure("Button Execution (No Dataflow)", async () => {
      return await optimizedButtonDataflowService.executeButtonWithDataflow(
        "perf-button-3",
        "save",
        noDataflowConfig,
        { testData: "value" },
        "DEFAULT",
      );
    });

    const execTime = benchmark.getResults().details.slice(-1)[0].time;
    if (execTime < 100) {
      // 제어관리 없으면 더 빨라야 함
      passed++;
      console.log(`  ✅ No dataflow execution: PASSED (${execTime.toFixed(2)}ms < 100ms)`);
    } else {
      console.log(`  ❌ No dataflow execution: FAILED (${execTime.toFixed(2)}ms >= 100ms)`);
    }
  } catch (error) {
    console.log("  ❌ No dataflow test: ERROR -", error.message);
  }

  return { total, passed };
}

/**
 * 작업 큐 성능 테스트
 */
async function testJobQueuePerformance(benchmark: PerformanceBenchmark) {
  let total = 0;
  let passed = 0;

  const mockConfig: ButtonTypeConfig = {
    actionType: "save" as ButtonActionType,
    enableDataflowControl: true,
    dataflowTiming: "after",
    dataflowConfig: {
      controlMode: "simple",
      selectedDiagramId: 1,
      selectedRelationshipId: "rel-123",
    },
  };

  // 큐 초기화
  dataflowJobQueue.clearQueue();

  // 1. 단일 작업 큐잉 성능
  total++;
  try {
    await benchmark.measure("Job Queue Enqueue (Single)", async () => {
      return dataflowJobQueue.enqueue("queue-perf-1", "save", mockConfig, {}, "DEFAULT", "normal");
    });

    const queueTime = benchmark.getResults().details.slice(-1)[0].time;
    if (queueTime < PERFORMANCE_TARGETS.QUEUE_ENQUEUE) {
      passed++;
      console.log(
        `  ✅ Single job enqueue: PASSED (${queueTime.toFixed(2)}ms < ${PERFORMANCE_TARGETS.QUEUE_ENQUEUE}ms)`,
      );
    } else {
      console.log(
        `  ❌ Single job enqueue: FAILED (${queueTime.toFixed(2)}ms >= ${PERFORMANCE_TARGETS.QUEUE_ENQUEUE}ms)`,
      );
    }
  } catch (error) {
    console.log("  ❌ Single enqueue test: ERROR -", error.message);
  }

  // 2. 대량 작업 큐잉 성능
  total++;
  try {
    const jobCount = 50;
    await benchmark.measure("Job Queue Enqueue (Batch)", async () => {
      const promises = Array.from({ length: jobCount }, (_, i) =>
        dataflowJobQueue.enqueue(`queue-perf-batch-${i}`, "save", mockConfig, {}, "DEFAULT", "normal"),
      );
      return Promise.resolve(promises);
    });

    const batchTime = benchmark.getResults().details.slice(-1)[0].time;
    const averageTime = batchTime / jobCount;

    if (averageTime < PERFORMANCE_TARGETS.QUEUE_ENQUEUE) {
      passed++;
      console.log(
        `  ✅ Batch job enqueue: PASSED (avg ${averageTime.toFixed(2)}ms < ${PERFORMANCE_TARGETS.QUEUE_ENQUEUE}ms)`,
      );
    } else {
      console.log(
        `  ❌ Batch job enqueue: FAILED (avg ${averageTime.toFixed(2)}ms >= ${PERFORMANCE_TARGETS.QUEUE_ENQUEUE}ms)`,
      );
    }
  } catch (error) {
    console.log("  ❌ Batch enqueue test: ERROR -", error.message);
  }

  // 3. 우선순위 처리 확인
  total++;
  try {
    // 일반 우선순위 작업들
    const normalJobs = Array.from({ length: 5 }, (_, i) =>
      dataflowJobQueue.enqueue(`normal-${i}`, "save", mockConfig, {}, "DEFAULT", "normal"),
    );

    // 높은 우선순위 작업
    const highJob = dataflowJobQueue.enqueue("high-priority", "save", mockConfig, {}, "DEFAULT", "high");

    const queueInfo = dataflowJobQueue.getQueueInfo();

    // 높은 우선순위 작업이 맨 앞에 있는지 확인
    if (queueInfo.pending[0].id === highJob && queueInfo.pending[0].priority === "high") {
      passed++;
      console.log("  ✅ Priority handling: PASSED");
    } else {
      console.log("  ❌ Priority handling: FAILED");
    }
  } catch (error) {
    console.log("  ❌ Priority test: ERROR -", error.message);
  }

  return { total, passed };
}

/**
 * 통합 성능 테스트
 */
async function testIntegrationPerformance(benchmark: PerformanceBenchmark) {
  let total = 0;
  let passed = 0;

  // 실제 사용 시나리오 시뮬레이션
  total++;
  try {
    const scenarios = [
      { timing: "after", count: 10, actionType: "save" },
      { timing: "before", count: 5, actionType: "delete" },
      { timing: "replace", count: 3, actionType: "submit" },
    ];

    await benchmark.measure("Integration Load Test", async () => {
      for (const scenario of scenarios) {
        const promises = Array.from({ length: scenario.count }, async (_, i) => {
          const config: ButtonTypeConfig = {
            actionType: scenario.actionType as ButtonActionType,
            enableDataflowControl: true,
            dataflowTiming: scenario.timing as any,
            dataflowConfig: {
              controlMode: "simple",
              selectedDiagramId: 1,
              selectedRelationshipId: `rel-${i}`,
            },
          };

          return await optimizedButtonDataflowService.executeButtonWithDataflow(
            `integration-${scenario.timing}-${i}`,
            scenario.actionType as ButtonActionType,
            config,
            { testData: `value-${i}` },
            "DEFAULT",
          );
        });

        await Promise.all(promises);
      }
    });

    const totalTime = benchmark.getResults().details.slice(-1)[0].time;
    const totalRequests = scenarios.reduce((sum, s) => sum + s.count, 0);
    const averageTime = totalTime / totalRequests;

    // 통합 테스트에서는 평균 300ms 이내면 통과
    if (averageTime < 300) {
      passed++;
      console.log(`  ✅ Integration load test: PASSED (avg ${averageTime.toFixed(2)}ms < 300ms)`);
    } else {
      console.log(`  ❌ Integration load test: FAILED (avg ${averageTime.toFixed(2)}ms >= 300ms)`);
    }
  } catch (error) {
    console.log("  ❌ Integration test: ERROR -", error.message);
  }

  return { total, passed };
}

// 스크립트가 직접 실행될 때만 테스트 실행
if (require.main === module) {
  runPerformanceTests();
}

export { runPerformanceTests };
