/**
 * 液化功能集成测试
 * 用于在浏览器环境中测试完整的液化工作流程
 */

import { LiquifyCPUManager } from "../managers/liquify/LiquifyCPUManager.js";
import { LiquifyWebGLManager } from "../managers/liquify/LiquifyWebGLManager.js";
import { LiquifyRealTimeUpdater } from "../managers/liquify/LiquifyRealTimeUpdater.js";
import { EnhancedLiquifyManager } from "../managers/liquify/EnhancedLiquifyManager.js";

// 集成测试结果
let testResults = {
  totalTests: 0,
  passedTests: 0,
  failedTests: 0,
  errors: [],
};

/**
 * 创建测试图像数据
 */
function createTestImageData(width = 100, height = 100) {
  const imageData = new ImageData(width, height);
  const data = imageData.data;

  // 创建一个简单的渐变图案用于测试
  for (let y = 0; y < height; y++) {
    for (let x = 0; x < width; x++) {
      const index = (y * width + x) * 4;
      data[index] = (x / width) * 255; // Red
      data[index + 1] = (y / height) * 255; // Green
      data[index + 2] = 128; // Blue
      data[index + 3] = 255; // Alpha
    }
  }

  return imageData;
}

/**
 * 创建测试Canvas
 */
function createTestCanvas(width = 200, height = 200) {
  const canvas = document.createElement("canvas");
  canvas.width = width;
  canvas.height = height;
  return canvas;
}

/**
 * 创建模拟Fabric对象
 */
function createMockFabricObject(imageData) {
  return {
    left: 50,
    top: 50,
    width: imageData.width,
    height: imageData.height,
    scaleX: 1,
    scaleY: 1,
    angle: 0,
    flipX: false,
    flipY: false,
    _element: null,
    calcTransformMatrix: function () {
      return [this.scaleX, 0, 0, this.scaleY, this.left, this.top];
    },
    set: function (props) {
      Object.assign(this, props);
    },
  };
}

/**
 * 运行单个测试
 */
async function runTest(testName, testFunction) {
  testResults.totalTests++;

  try {
    console.log(`🧪 运行测试: ${testName}`);
    await testFunction();
    testResults.passedTests++;
    console.log(`✅ 测试通过: ${testName}`);
  } catch (error) {
    testResults.failedTests++;
    testResults.errors.push({ testName, error: error.message });
    console.error(`❌ 测试失败: ${testName}`, error);
  }
}

/**
 * 测试CPU管理器基本功能
 */
async function testCPUManagerBasics() {
  const manager = new LiquifyCPUManager();
  const testImageData = createTestImageData();

  // 初始化
  manager.initialize(testImageData);

  // 设置参数
  manager.setParams({
    size: 50,
    pressure: 0.5,
    distortion: 0.3,
    power: 0.8,
  });

  // 设置模式
  manager.setMode("push");

  // 应用变形
  const result = manager.applyDeformation(50, 50);

  if (!result || result.width !== testImageData.width || result.height !== testImageData.height) {
    throw new Error("CPU管理器变形结果无效");
  }

  // 测试不同模式
  const modes = ["push", "clockwise", "counterclockwise", "pinch", "expand", "reconstruct"];
  for (const mode of modes) {
    manager.setMode(mode);
    const modeResult = manager.applyDeformation(25, 25);
    if (!modeResult) {
      throw new Error(`模式 ${mode} 变形失败`);
    }
  }
}

/**
 * 测试WebGL管理器基本功能
 */
async function testWebGLManagerBasics() {
  const manager = new LiquifyWebGLManager();
  const testImageData = createTestImageData();

  try {
    // 初始化
    manager.initialize(testImageData);

    // 检查WebGL是否可用
    if (!manager.initialized) {
      console.warn("WebGL不可用，跳过WebGL测试");
      return;
    }

    // 设置参数
    manager.setParams({
      size: 50,
      pressure: 0.5,
      distortion: 0.3,
      power: 0.8,
    });

    // 设置模式
    manager.setMode("push");

    // 应用变形
    const result = manager.applyDeformation(50, 50);

    if (!result || result.width !== testImageData.width || result.height !== testImageData.height) {
      throw new Error("WebGL管理器变形结果无效");
    }
  } catch (error) {
    if (error.message.includes("WebGL")) {
      console.warn("WebGL不支持，跳过WebGL测试");
      return;
    }
    throw error;
  }
}

/**
 * 测试实时更新器功能
 */
async function testRealTimeUpdater() {
  const canvas = createTestCanvas();
  const testImageData = createTestImageData();
  const mockFabricObject = createMockFabricObject(testImageData);

  // 模拟fabric Canvas
  const fabricCanvas = {
    getObjects: () => [mockFabricObject],
    remove: () => {},
    insertAt: () => {},
    renderAll: () => {},
  };

  const updater = new LiquifyRealTimeUpdater(fabricCanvas);

  // 设置目标对象
  updater.setTargetObject(mockFabricObject);

  // 测试快速更新
  await updater.updateImage(testImageData, true);

  // 测试完整更新
  await updater.updateImage(testImageData, false);

  // 测试待处理更新
  updater.pendingImageData = testImageData;
  await updater.processPendingUpdates();

  // 清理
  updater.dispose();
}

/**
 * 测试增强液化管理器
 */
async function testEnhancedLiquifyManager() {
  const manager = new EnhancedLiquifyManager();
  const testImageData = createTestImageData();
  const mockFabricObject = createMockFabricObject(testImageData);

  // 初始化
  const result = await manager.prepareForLiquify(mockFabricObject);

  if (!result || !result.originalImageData) {
    throw new Error("增强液化管理器初始化失败");
  }

  // 设置参数
  manager.setParams({
    size: 50,
    pressure: 0.5,
    distortion: 0.3,
    power: 0.8,
  });

  // 应用液化
  const liquifyResult = await manager.applyLiquify(
    mockFabricObject,
    "push",
    { size: 50, pressure: 0.5, distortion: 0.3, power: 0.8 },
    50,
    50
  );

  if (!liquifyResult) {
    throw new Error("液化应用失败");
  }
}

/**
 * 测试坐标转换准确性
 */
async function testCoordinateConversion() {
  const testImageData = createTestImageData(200, 200);
  const mockFabricObject = createMockFabricObject(testImageData);

  // 测试不同的缩放情况
  const testCases = [
    { scaleX: 1, scaleY: 1, flipX: false, flipY: false },
    { scaleX: 2, scaleY: 2, flipX: false, flipY: false },
    { scaleX: 0.5, scaleY: 0.5, flipX: false, flipY: false },
    { scaleX: 1, scaleY: 1, flipX: true, flipY: false },
    { scaleX: 1, scaleY: 1, flipX: false, flipY: true },
  ];

  for (const testCase of testCases) {
    Object.assign(mockFabricObject, testCase);

    // 模拟坐标转换函数（简化版）
    const fabricX = 100,
      fabricY = 100;

    // 创建变换矩阵模拟
    const transform = mockFabricObject.calcTransformMatrix();

    // 基本的坐标边界检查
    const localX = (fabricX - mockFabricObject.left) / mockFabricObject.scaleX;
    const localY = (fabricY - mockFabricObject.top) / mockFabricObject.scaleY;

    if (
      localX < -mockFabricObject.width / 2 ||
      localX > mockFabricObject.width / 2 ||
      localY < -mockFabricObject.height / 2 ||
      localY > mockFabricObject.height / 2
    ) {
      // 坐标在对象外部，这是正常情况
      continue;
    }

    // 转换到图像坐标
    let imageX =
      (localX + mockFabricObject.width / 2) * (testImageData.width / mockFabricObject.width);
    let imageY =
      (localY + mockFabricObject.height / 2) * (testImageData.height / mockFabricObject.height);

    // 处理翻转
    if (mockFabricObject.flipX) {
      imageX = testImageData.width - imageX;
    }
    if (mockFabricObject.flipY) {
      imageY = testImageData.height - imageY;
    }

    // 验证结果在合理范围内
    if (
      imageX < 0 ||
      imageX >= testImageData.width ||
      imageY < 0 ||
      imageY >= testImageData.height
    ) {
      throw new Error(`坐标转换结果超出图像范围: (${imageX}, ${imageY})`);
    }
  }
}

/**
 * 测试性能表现
 */
async function testPerformance() {
  const manager = new LiquifyCPUManager();
  const testImageData = createTestImageData(400, 400); // 更大的图像

  manager.initialize(testImageData);
  manager.setParams({
    size: 50,
    pressure: 0.5,
    distortion: 0.3,
    power: 0.8,
  });
  manager.setMode("push");

  // 测试多次操作的性能
  const startTime = performance.now();
  const operationCount = 100;

  for (let i = 0; i < operationCount; i++) {
    const x = Math.random() * testImageData.width;
    const y = Math.random() * testImageData.height;
    manager.applyDeformation(x, y);
  }

  const endTime = performance.now();
  const totalTime = endTime - startTime;
  const avgTime = totalTime / operationCount;

  console.log(
    `性能测试结果: ${operationCount} 次操作，总耗时 ${totalTime.toFixed(
      2
    )}ms，平均 ${avgTime.toFixed(2)}ms/次`
  );

  // 验证性能阈值（每次操作不应超过50ms）
  if (avgTime > 50) {
    throw new Error(`性能不达标：平均操作时间 ${avgTime.toFixed(2)}ms 超过阈值 50ms`);
  }
}

/**
 * 测试内存管理
 */
async function testMemoryManagement() {
  const initialMemory = performance.memory ? performance.memory.usedJSHeapSize : 0;

  // 创建多个管理器实例
  const managers = [];
  for (let i = 0; i < 10; i++) {
    const manager = new LiquifyCPUManager();
    const testImageData = createTestImageData(200, 200);
    manager.initialize(testImageData);
    managers.push(manager);
  }

  // 销毁所有管理器
  for (const manager of managers) {
    if (manager.destroy) {
      manager.destroy();
    }
  }

  // 强制垃圾回收（如果可用）
  if (window.gc) {
    window.gc();
  }

  const finalMemory = performance.memory ? performance.memory.usedJSHeapSize : 0;
  const memoryIncrease = finalMemory - initialMemory;

  console.log(
    `内存测试: 初始 ${(initialMemory / 1024 / 1024).toFixed(2)}MB, 最终 ${(
      finalMemory /
      1024 /
      1024
    ).toFixed(2)}MB, 增长 ${(memoryIncrease / 1024 / 1024).toFixed(2)}MB`
  );

  // 验证内存增长不超过10MB（基本的内存泄漏检查）
  if (memoryIncrease > 10 * 1024 * 1024) {
    console.warn(`潜在内存泄漏: 内存增长 ${(memoryIncrease / 1024 / 1024).toFixed(2)}MB`);
  }
}

/**
 * 运行所有集成测试
 */
export async function runLiquifyIntegrationTests() {
  console.log("🚀 开始液化功能集成测试...");

  // 重置测试结果
  testResults = {
    totalTests: 0,
    passedTests: 0,
    failedTests: 0,
    errors: [],
  };

  try {
    // 基础功能测试
    await runTest("CPU管理器基本功能", testCPUManagerBasics);
    await runTest("WebGL管理器基本功能", testWebGLManagerBasics);
    await runTest("实时更新器功能", testRealTimeUpdater);
    await runTest("增强液化管理器", testEnhancedLiquifyManager);

    // 高级功能测试
    await runTest("坐标转换准确性", testCoordinateConversion);
    await runTest("性能表现", testPerformance);
    await runTest("内存管理", testMemoryManagement);
  } catch (error) {
    console.error("集成测试出现严重错误:", error);
  }

  // 输出测试结果
  console.log("\n📊 液化功能集成测试结果:");
  console.log(`总测试数: ${testResults.totalTests}`);
  console.log(`通过: ${testResults.passedTests}`);
  console.log(`失败: ${testResults.failedTests}`);
  console.log(`成功率: ${((testResults.passedTests / testResults.totalTests) * 100).toFixed(1)}%`);

  if (testResults.errors.length > 0) {
    console.log("\n❌ 失败的测试:");
    testResults.errors.forEach(({ testName, error }) => {
      console.log(`  - ${testName}: ${error}`);
    });
  }

  return testResults;
}

/**
 * 在浏览器控制台中运行测试
 */
if (typeof window !== "undefined") {
  window.runLiquifyIntegrationTests = runLiquifyIntegrationTests;
  console.log("💡 使用 window.runLiquifyIntegrationTests() 运行液化集成测试");
}
