import { GeoFence, GeoFenceAlert } from '../types/equipment';

/**
 * 生成测试用的电子围栏数据
 */
export function generateTestGeoFences(machineryIds: string[]): GeoFence[] {
  const now = new Date().toISOString();
  
  return [
    // 矩形作业区
    {
      id: 'fence-test-1',
      name: '1号作业区',
      type: 'polygon',
      points: [
        { latitude: 36.6512, longitude: 117.1201 },
        { latitude: 36.6532, longitude: 117.1201 },
        { latitude: 36.6532, longitude: 117.1251 },
        { latitude: 36.6512, longitude: 117.1251 },
      ],
      machineryIds: machineryIds.slice(0, 2),
      alertOnExit: true,
      alertOnEnter: false,
      countWorkHours: true,
      enabled: true,
      createdAt: now,
      updatedAt: now,
      createdBy: '系统管理员',
    },
    
    // 圆形禁入区
    {
      id: 'fence-test-2',
      name: '东侧水塘禁入区',
      type: 'circle',
      center: { latitude: 36.6500, longitude: 117.1200 },
      radius: 200,
      machineryIds: machineryIds,
      alertOnExit: false,
      alertOnEnter: true,
      countWorkHours: false,
      enabled: true,
      createdAt: now,
      updatedAt: now,
      createdBy: '系统管理员',
    },
    
    // 大型多边形作业区
    {
      id: 'fence-test-3',
      name: '2号地块-西区',
      type: 'polygon',
      points: [
        { latitude: 36.6480, longitude: 117.1150 },
        { latitude: 36.6500, longitude: 117.1150 },
        { latitude: 36.6510, longitude: 117.1180 },
        { latitude: 36.6500, longitude: 117.1200 },
        { latitude: 36.6480, longitude: 117.1190 },
      ],
      machineryIds: machineryIds.slice(0, 1),
      alertOnExit: true,
      alertOnEnter: false,
      countWorkHours: true,
      enabled: true,
      createdAt: now,
      updatedAt: now,
      createdBy: '系统管理员',
    },
    
    // 休息区（圆形）
    {
      id: 'fence-test-4',
      name: '农机停放区',
      type: 'circle',
      center: { latitude: 36.6550, longitude: 117.1100 },
      radius: 100,
      machineryIds: machineryIds,
      alertOnExit: false,
      alertOnEnter: false,
      countWorkHours: false,
      enabled: true,
      createdAt: now,
      updatedAt: now,
      createdBy: '系统管理员',
    },
  ];
}

/**
 * 生成测试用的围栏报警数据
 */
export function generateTestGeoFenceAlerts(
  fences: GeoFence[],
  machineryData: { id: string; name: string }[]
): GeoFenceAlert[] {
  const alerts: GeoFenceAlert[] = [];
  
  // 生成一些历史报警
  if (fences.length > 0 && machineryData.length > 0) {
    const fence1 = fences[0];
    const machinery1 = machineryData[0];
    
    alerts.push({
      id: 'alert-test-1',
      fenceId: fence1.id,
      fenceName: fence1.name,
      machineryId: machinery1.id,
      machineryName: machinery1.name,
      alertType: 'exit',
      location: { latitude: 36.6510, longitude: 117.1252 },
      alertedAt: new Date(Date.now() - 2 * 60 * 60 * 1000).toISOString(), // 2小时前
      acknowledged: false,
    });
  }
  
  if (fences.length > 1 && machineryData.length > 1) {
    const fence2 = fences[1];
    const machinery2 = machineryData[1];
    
    alerts.push({
      id: 'alert-test-2',
      fenceId: fence2.id,
      fenceName: fence2.name,
      machineryId: machinery2.id,
      machineryName: machinery2.name,
      alertType: 'enter',
      location: { latitude: 36.6501, longitude: 117.1201 },
      alertedAt: new Date(Date.now() - 30 * 60 * 1000).toISOString(), // 30分钟前
      acknowledged: true,
      acknowledgedBy: '值班员张三',
      acknowledgedAt: new Date(Date.now() - 25 * 60 * 1000).toISOString(),
    });
  }
  
  return alerts;
}

/**
 * 验证围栏坐标是否有效
 */
export function validateGeoFence(fence: Partial<GeoFence>): { valid: boolean; errors: string[] } {
  const errors: string[] = [];
  
  if (!fence.name || fence.name.trim() === '') {
    errors.push('围栏名称不能为空');
  }
  
  if (!fence.type) {
    errors.push('必须选择围栏类型');
  }
  
  if (fence.type === 'circle') {
    if (!fence.center) {
      errors.push('圆形围栏必须设置中心点');
    } else {
      if (!isValidLatitude(fence.center.latitude)) {
        errors.push('中心点纬度无效（应在-90到90之间）');
      }
      if (!isValidLongitude(fence.center.longitude)) {
        errors.push('中心点经度无效（应在-180到180之间）');
      }
    }
    
    if (!fence.radius || fence.radius <= 0) {
      errors.push('圆形围栏半径必须大于0');
    }
  }
  
  if (fence.type === 'polygon') {
    if (!fence.points || fence.points.length < 3) {
      errors.push('多边形围栏至少需要3个顶点');
    } else {
      fence.points.forEach((point, index) => {
        if (!isValidLatitude(point.latitude)) {
          errors.push(`顶点${index + 1}的纬度无效`);
        }
        if (!isValidLongitude(point.longitude)) {
          errors.push(`顶点${index + 1}的经度无效`);
        }
      });
    }
  }
  
  if (!fence.machineryIds || fence.machineryIds.length === 0) {
    errors.push('必须至少关联一台农机');
  }
  
  if (!fence.alertOnEnter && !fence.alertOnExit) {
    errors.push('建议至少启用一种报警方式（进入或离开）');
  }
  
  return {
    valid: errors.length === 0,
    errors,
  };
}

/**
 * 验证纬度是否有效
 */
function isValidLatitude(lat: number): boolean {
  return !isNaN(lat) && lat >= -90 && lat <= 90;
}

/**
 * 验证经度是否有效
 */
function isValidLongitude(lng: number): boolean {
  return !isNaN(lng) && lng >= -180 && lng <= 180;
}

/**
 * 计算两点之间的距离（米）
 * 使用 Haversine 公式
 */
export function calculateDistance(
  point1: { latitude: number; longitude: number },
  point2: { latitude: number; longitude: number }
): number {
  const R = 6371000; // 地球半径，米
  const lat1 = (point1.latitude * Math.PI) / 180;
  const lat2 = (point2.latitude * Math.PI) / 180;
  const deltaLat = ((point2.latitude - point1.latitude) * Math.PI) / 180;
  const deltaLng = ((point2.longitude - point1.longitude) * Math.PI) / 180;

  const a =
    Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) +
    Math.cos(lat1) * Math.cos(lat2) * Math.sin(deltaLng / 2) * Math.sin(deltaLng / 2);

  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

  return R * c;
}

/**
 * 判断点是否在圆形围栏内
 */
export function isPointInCircle(
  point: { latitude: number; longitude: number },
  center: { latitude: number; longitude: number },
  radius: number
): boolean {
  const distance = calculateDistance(point, center);
  return distance <= radius;
}

/**
 * 判断点是否在多边形围栏内
 * 使用射线法（Ray Casting Algorithm）
 */
export function isPointInPolygon(
  point: { latitude: number; longitude: number },
  polygon: { latitude: number; longitude: number }[]
): boolean {
  let inside = false;
  const x = point.longitude;
  const y = point.latitude;

  for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
    const xi = polygon[i].longitude;
    const yi = polygon[i].latitude;
    const xj = polygon[j].longitude;
    const yj = polygon[j].latitude;

    const intersect = yi > y !== yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi;

    if (intersect) {
      inside = !inside;
    }
  }

  return inside;
}
