/**
 * 视频编辑功能工具函数
 */

import { EditPoint, EditPointPosition } from './types';

/**
 * 防抖函数
 */
export function debounce<T extends (...args: any[]) => any>(
  func: T,
  wait: number
): (...args: Parameters<T>) => void {
  let timeout: NodeJS.Timeout;
  return (...args: Parameters<T>) => {
    clearTimeout(timeout);
    timeout = setTimeout(() => func(...args), wait);
  };
}

/**
 * 节流函数
 */
export function throttle<T extends (...args: any[]) => any>(
  func: T,
  limit: number
): (...args: Parameters<T>) => void {
  let inThrottle: boolean;
  return (...args: Parameters<T>) => {
    if (!inThrottle) {
      func(...args);
      inThrottle = true;
      setTimeout(() => inThrottle = false, limit);
    }
  };
}

/**
 * 计算两点之间的距离
 */
export function calculateDistance(
  point1: { x: number; y: number },
  point2: { x: number; y: number }
): number {
  const dx = point2.x - point1.x;
  const dy = point2.y - point1.y;
  return Math.sqrt(dx * dx + dy * dy);
}

/**
 * 检查点是否在矩形区域内
 */
export function isPointInRect(
  point: { x: number; y: number },
  rect: { x: number; y: number; width: number; height: number }
): boolean {
  return (
    point.x >= rect.x &&
    point.x <= rect.x + rect.width &&
    point.y >= rect.y &&
    point.y <= rect.y + rect.height
  );
}

/**
 * 将屏幕坐标转换为百分比坐标
 */
export function screenToPercentage(
  screenPoint: { x: number; y: number },
  containerSize: { width: number; height: number }
): EditPointPosition {
  return {
    x: Math.max(0, Math.min(100, (screenPoint.x / containerSize.width) * 100)),
    y: Math.max(0, Math.min(100, (screenPoint.y / containerSize.height) * 100))
  };
}

/**
 * 将百分比坐标转换为屏幕坐标
 */
export function percentageToScreen(
  percentagePoint: EditPointPosition,
  containerSize: { width: number; height: number }
): { x: number; y: number } {
  return {
    x: (percentagePoint.x / 100) * containerSize.width,
    y: (percentagePoint.y / 100) * containerSize.height
  };
}

/**
 * 生成唯一ID
 */
export function generateId(): string {
  return `edit-point-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
}

/**
 * 格式化时间戳为可读格式
 */
export function formatTimestamp(seconds: number): string {
  const minutes = Math.floor(seconds / 60);
  const remainingSeconds = Math.floor(seconds % 60);
  return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;
}

/**
 * 验证编辑点数据
 */
export function validateEditPoint(editPoint: Partial<EditPoint>): string[] {
  const errors: string[] = [];

  if (!editPoint.videoId) {
    errors.push('Video ID is required');
  }

  if (!editPoint.projectId) {
    errors.push('Project ID is required');
  }

  if (!editPoint.position) {
    errors.push('Position is required');
  } else {
    if (editPoint.position.x < 0 || editPoint.position.x > 100) {
      errors.push('Position X must be between 0 and 100');
    }
    if (editPoint.position.y < 0 || editPoint.position.y > 100) {
      errors.push('Position Y must be between 0 and 100');
    }
  }

  if (editPoint.timestamp !== undefined && editPoint.timestamp < 0) {
    errors.push('Timestamp must be non-negative');
  }

  if (editPoint.description && editPoint.description.length > 500) {
    errors.push('Description must be less than 500 characters');
  }

  return errors;
}

/**
 * 计算最佳输入框位置（避免重叠）
 */
export function calculateOptimalInputPosition(
  editPoint: EditPointPosition,
  containerSize: { width: number; height: number },
  existingPositions: { x: number; y: number }[],
  inputSize: { width: number; height: number } = { width: 280, height: 120 }
): { x: number; y: number; connectionEnd: { x: number; y: number } } {
  const pointScreen = percentageToScreen(editPoint, containerSize);
  
  // 候选位置（相对于编辑点）
  const candidates = [
    { x: 60, y: -60, direction: 'top-right' },
    { x: -60 - inputSize.width, y: -60, direction: 'top-left' },
    { x: 60, y: 60, direction: 'bottom-right' },
    { x: -60 - inputSize.width, y: 60, direction: 'bottom-left' },
    { x: 80, y: -30, direction: 'right' },
    { x: -80 - inputSize.width, y: -30, direction: 'left' }
  ];

  // 为每个候选位置计算得分
  const scoredCandidates = candidates.map(candidate => {
    const absolutePos = {
      x: pointScreen.x + candidate.x,
      y: pointScreen.y + candidate.y
    };

    let score = 0;

    // 检查是否在容器内
    if (
      absolutePos.x >= 10 &&
      absolutePos.x + inputSize.width <= containerSize.width - 10 &&
      absolutePos.y >= 10 &&
      absolutePos.y + inputSize.height <= containerSize.height - 10
    ) {
      score += 100;
    }

    // 检查与现有位置的距离
    const minDistance = Math.min(
      ...existingPositions.map(pos => calculateDistance(absolutePos, pos)),
      Infinity
    );
    score += Math.min(minDistance / 10, 50);

    // 偏好右上角位置
    if (candidate.direction === 'top-right') {
      score += 20;
    }

    return {
      ...candidate,
      position: absolutePos,
      score
    };
  });

  // 选择得分最高的位置
  const bestCandidate = scoredCandidates.reduce((best, current) =>
    current.score > best.score ? current : best
  );

  // 计算连接线终点
  const connectionEnd = {
    x: bestCandidate.position.x + (bestCandidate.x > 0 ? 0 : inputSize.width),
    y: bestCandidate.position.y + inputSize.height / 2
  };

  return {
    x: Math.max(10, Math.min(containerSize.width - inputSize.width - 10, bestCandidate.position.x)),
    y: Math.max(10, Math.min(containerSize.height - inputSize.height - 10, bestCandidate.position.y)),
    connectionEnd
  };
}

/**
 * 深度比较两个对象是否相等
 */
export function deepEqual(obj1: any, obj2: any): boolean {
  if (obj1 === obj2) return true;
  
  if (obj1 == null || obj2 == null) return false;
  
  if (typeof obj1 !== typeof obj2) return false;
  
  if (typeof obj1 !== 'object') return obj1 === obj2;
  
  const keys1 = Object.keys(obj1);
  const keys2 = Object.keys(obj2);
  
  if (keys1.length !== keys2.length) return false;
  
  for (const key of keys1) {
    if (!keys2.includes(key)) return false;
    if (!deepEqual(obj1[key], obj2[key])) return false;
  }
  
  return true;
}

/**
 * 创建错误处理装饰器
 */
export function withErrorHandling<T extends (...args: any[]) => any>(
  fn: T,
  errorHandler?: (error: Error) => void
): T {
  return ((...args: Parameters<T>) => {
    try {
      const result = fn(...args);
      if (result instanceof Promise) {
        return result.catch((error: Error) => {
          console.error('Async function error:', error);
          errorHandler?.(error);
          throw error;
        });
      }
      return result;
    } catch (error) {
      console.error('Function error:', error);
      errorHandler?.(error as Error);
      throw error;
    }
  }) as T;
}

/**
 * 性能监控装饰器
 */
export function withPerformanceMonitoring<T extends (...args: any[]) => any>(
  fn: T,
  name: string
): T {
  return ((...args: Parameters<T>) => {
    const start = performance.now();
    const result = fn(...args);
    
    if (result instanceof Promise) {
      return result.finally(() => {
        const end = performance.now();
        console.log(`${name} took ${end - start} milliseconds`);
      });
    } else {
      const end = performance.now();
      console.log(`${name} took ${end - start} milliseconds`);
      return result;
    }
  }) as T;
}

/**
 * 本地存储工具
 */
export const storage = {
  get<T>(key: string, defaultValue: T): T {
    try {
      const item = localStorage.getItem(key);
      return item ? JSON.parse(item) : defaultValue;
    } catch {
      return defaultValue;
    }
  },

  set<T>(key: string, value: T): void {
    try {
      localStorage.setItem(key, JSON.stringify(value));
    } catch (error) {
      console.error('Failed to save to localStorage:', error);
    }
  },

  remove(key: string): void {
    try {
      localStorage.removeItem(key);
    } catch (error) {
      console.error('Failed to remove from localStorage:', error);
    }
  }
};
