/**
 * 坐标映射工具类 - 用于测试和验证坐标转换的准确性
 */

interface DeviceInfo {
  density: number
  densityDpi: number
  hasNavigationBar: boolean
  aspectRatio: number
  realScreenSize: { width: number; height: number }
  appScreenSize: { width: number; height: number }
  navigationBarSize: { width: number; height: number }
}

interface CoordinateTestResult {
  success: boolean
  accuracy: number // 准确度百分比
  avgError: number // 平均误差（像素）
  maxError: number // 最大误差（像素）
  testPoints: Array<{
    input: { x: number; y: number }
    expected: { x: number; y: number }
    actual: { x: number; y: number }
    error: number
  }>
}

export class CoordinateMapper {
  /**
   * 测试坐标映射准确性
   */
  static testCoordinateMapping(
    deviceWidth: number,
    deviceHeight: number,
    displayWidth: number,
    displayHeight: number,
    deviceInfo?: DeviceInfo
  ): CoordinateTestResult {
    console.log('🧪 开始坐标映射准确性测试')
    
    // 生成测试点
    const testPoints = [
      // 屏幕角落
      { x: 0, y: 0 },
      { x: deviceWidth - 1, y: 0 },
      { x: 0, y: deviceHeight - 1 },
      { x: deviceWidth - 1, y: deviceHeight - 1 },
      
      // 屏幕中心
      { x: deviceWidth / 2, y: deviceHeight / 2 },
      
      // 常见按钮位置
      { x: deviceWidth * 0.8, y: deviceHeight * 0.9 }, // 右下角按钮
      { x: deviceWidth * 0.5, y: deviceHeight * 0.8 }, // 底部中央按钮
      { x: deviceWidth * 0.2, y: deviceHeight * 0.1 }, // 左上角按钮
      
      // 键盘区域
      { x: deviceWidth * 0.25, y: deviceHeight * 0.6 },
      { x: deviceWidth * 0.5, y: deviceHeight * 0.6 },
      { x: deviceWidth * 0.75, y: deviceHeight * 0.6 },
      
      // 导航栏区域（如果有）
      ...(deviceInfo?.hasNavigationBar ? [
        { x: deviceWidth * 0.2, y: deviceHeight + 50 },
        { x: deviceWidth * 0.5, y: deviceHeight + 50 },
        { x: deviceWidth * 0.8, y: deviceHeight + 50 }
      ] : [])
    ]
    
    const results: CoordinateTestResult['testPoints'] = []
    let totalError = 0
    let maxError = 0
    
    for (const point of testPoints) {
      // 模拟正向转换：设备坐标 → 显示坐标
      const displayCoords = this.deviceToDisplay(point.x, point.y, deviceWidth, deviceHeight, displayWidth, displayHeight)
      
      // 模拟反向转换：显示坐标 → 设备坐标
      const backToDevice = this.displayToDevice(displayCoords.x, displayCoords.y, deviceWidth, deviceHeight, displayWidth, displayHeight, deviceInfo)
      
      // 计算误差
      const error = Math.sqrt(Math.pow(point.x - backToDevice.x, 2) + Math.pow(point.y - backToDevice.y, 2))
      totalError += error
      maxError = Math.max(maxError, error)
      
      results.push({
        input: point,
        expected: point,
        actual: backToDevice,
        error
      })
    }
    
    const avgError = totalError / testPoints.length
    const accuracy = Math.max(0, 100 - (avgError / Math.min(deviceWidth, deviceHeight) * 100))
    
    const result: CoordinateTestResult = {
      success: avgError < 5, // 平均误差小于5像素认为成功
      accuracy,
      avgError,
      maxError,
      testPoints: results
    }
    
    console.log('🧪 坐标映射测试结果:', {
      success: result.success,
      accuracy: `${accuracy.toFixed(2)}%`,
      avgError: `${avgError.toFixed(2)}px`,
      maxError: `${maxError.toFixed(2)}px`,
      testPointsCount: testPoints.length
    })
    
    return result
  }
  
  /**
   * 设备坐标转换为显示坐标
   */
  private static deviceToDisplay(
    deviceX: number,
    deviceY: number,
    deviceWidth: number,
    deviceHeight: number,
    displayWidth: number,
    displayHeight: number
  ): { x: number; y: number } {
    const scaleX = displayWidth / deviceWidth
    const scaleY = displayHeight / deviceHeight
    const scale = Math.min(scaleX, scaleY)
    
    const actualDisplayWidth = deviceWidth * scale
    const actualDisplayHeight = deviceHeight * scale
    const offsetX = (displayWidth - actualDisplayWidth) / 2
    const offsetY = (displayHeight - actualDisplayHeight) / 2
    
    return {
      x: deviceX * scale + offsetX,
      y: deviceY * scale + offsetY
    }
  }
  
  /**
   * 显示坐标转换为设备坐标（增强版本）
   */
  private static displayToDevice(
    displayX: number,
    displayY: number,
    deviceWidth: number,
    deviceHeight: number,
    displayWidth: number,
    displayHeight: number,
    deviceInfo?: DeviceInfo
  ): { x: number; y: number } {
    const scaleX = displayWidth / deviceWidth
    const scaleY = displayHeight / deviceHeight
    const scale = Math.min(scaleX, scaleY)
    
    const actualDisplayWidth = deviceWidth * scale
    const actualDisplayHeight = deviceHeight * scale
    const offsetX = (displayWidth - actualDisplayWidth) / 2
    const offsetY = (displayHeight - actualDisplayHeight) / 2
    
    const adjustedX = displayX - offsetX
    const adjustedY = displayY - offsetY
    
    let deviceX = adjustedX / scale
    let deviceY = adjustedY / scale
    
    // 应用设备特性修正
    if (deviceInfo) {
      const density = deviceInfo.density
      if (density > 2) {
        deviceX = Math.round(deviceX * 10) / 10
        deviceY = Math.round(deviceY * 10) / 10
      } else {
        deviceX = Math.round(deviceX)
        deviceY = Math.round(deviceY)
      }
      
      // 导航栏区域修正
      if (deviceInfo.hasNavigationBar && deviceInfo.navigationBarSize.height > 0) {
        const navBarHeight = deviceInfo.navigationBarSize.height
        const threshold = deviceHeight - navBarHeight
        if (deviceY > threshold) {
          deviceY = Math.min(deviceY, deviceHeight + Math.min(navBarHeight, 150))
        }
      }
    }
    
    return {
      x: Math.max(0, Math.min(deviceWidth, deviceX)),
      y: Math.max(0, Math.min(deviceHeight, deviceY))
    }
  }
  
  /**
   * 生成坐标映射诊断报告
   */
  static generateDiagnosticReport(
    deviceWidth: number,
    deviceHeight: number,
    displayWidth: number,
    displayHeight: number,
    deviceInfo?: DeviceInfo
  ): string {
    const testResult = this.testCoordinateMapping(deviceWidth, deviceHeight, displayWidth, displayHeight, deviceInfo)
    
    let report = `📊 坐标映射诊断报告\n`
    report += `==========================================\n`
    report += `设备分辨率: ${deviceWidth}x${deviceHeight}\n`
    report += `显示分辨率: ${displayWidth}x${displayHeight}\n`
    report += `设备信息: ${deviceInfo ? '已提供' : '未提供'}\n`
    report += `\n`
    report += `测试结果:\n`
    report += `- 测试状态: ${testResult.success ? '✅ 通过' : '❌ 失败'}\n`
    report += `- 准确度: ${testResult.accuracy.toFixed(2)}%\n`
    report += `- 平均误差: ${testResult.avgError.toFixed(2)}px\n`
    report += `- 最大误差: ${testResult.maxError.toFixed(2)}px\n`
    report += `- 测试点数: ${testResult.testPoints.length}\n`
    report += `\n`
    
    if (!testResult.success) {
      report += `❌ 问题点分析:\n`
      testResult.testPoints
        .filter(p => p.error > 5)
        .forEach((p, i) => {
          report += `  ${i + 1}. 输入(${p.input.x.toFixed(1)}, ${p.input.y.toFixed(1)}) → 输出(${p.actual.x.toFixed(1)}, ${p.actual.y.toFixed(1)}) 误差: ${p.error.toFixed(2)}px\n`
        })
    }
    
    if (deviceInfo) {
      report += `\n📱 设备特征:\n`
      report += `- 密度: ${deviceInfo.density}\n`
      report += `- DPI: ${deviceInfo.densityDpi}\n`
      report += `- 长宽比: ${deviceInfo.aspectRatio.toFixed(3)}\n`
      report += `- 虚拟按键: ${deviceInfo.hasNavigationBar ? '是' : '否'}\n`
      if (deviceInfo.hasNavigationBar) {
        report += `- 导航栏尺寸: ${deviceInfo.navigationBarSize.width}x${deviceInfo.navigationBarSize.height}\n`
      }
    }
    
    report += `==========================================\n`
    
    return report
  }
}

export default CoordinateMapper 