/**
 * 战场防御线：反弓曲线路径 + 锯齿齿形
 */

export type LngLat = [number, number]

/** 二次贝塞尔 B(t) = (1-t)²P0 + 2(1-t)t P1 + t² P2 */
function quadraticBezier(P0: LngLat, P1: LngLat, P2: LngLat, t: number): LngLat {
  const u = 1 - t
  return [
    u * u * P0[0] + 2 * u * t * P1[0] + t * t * P2[0],
    u * u * P0[1] + 2 * u * t * P1[1] + t * t * P2[1],
  ]
}

/**
 * 生成反弓曲线路径：通过 path 各点，弧面向进攻方向（西侧）凸出
 * @param path 关键点 [[lng, lat], ...]（如大不里士→萨南达季→克尔曼沙赫）
 * @param bulgeWest 向西凸出量（经度，正值表示弧顶在西侧/面向进攻方）
 * @param samplesPerSegment 每段贝塞尔采样点数
 */
export function createCurvedDefensePath(
  path: LngLat[],
  bulgeWest: number = 0.35,
  samplesPerSegment: number = 24
): LngLat[] {
  if (path.length < 2) return path
  const out: LngLat[] = []
  for (let i = 0; i < path.length - 1; i++) {
    const a = path[i]
    const b = path[i + 1]
    const midLng = (a[0] + b[0]) / 2
    const midLat = (a[1] + b[1]) / 2
    const control: LngLat = [midLng - bulgeWest, midLat]
    const startK = i === 0 ? 0 : 1
    for (let k = startK; k <= samplesPerSegment; k++) {
      out.push(quadraticBezier(a, control, b, k / samplesPerSegment))
    }
  }
  return out
}

/**
 * 沿路径线性插值增加点（直线段）
 */
export function interpolatePath(path: LngLat[], stepsPerSegment: number = 4): LngLat[] {
  if (path.length < 2) return path
  const out: LngLat[] = []
  for (let i = 0; i < path.length - 1; i++) {
    const a = path[i]
    const b = path[i + 1]
    const startK = i === 0 ? 0 : 1
    for (let k = startK; k <= stepsPerSegment; k++) {
      const t = k / stepsPerSegment
      out.push([a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t])
    }
  }
  return out
}

/**
 * 锯齿防御线：沿 path 每 toothWidth（比例）生成齿，齿高 toothHeight，朝向法向（敌方侧）
 * @param path 路径点 [[lng, lat], ...]（可先经 interpolatePath 插值）
 * @param toothWidth 齿宽（与段长同单位，经纬度）
 * @param toothHeight 齿高（法向伸出）
 */
export function createDefenseLine(
  path: number[][],
  toothWidth: number,
  toothHeight: number
): number[][] {
  const coords: number[][] = []

  for (let i = 0; i < path.length - 1; i++) {
    const start = path[i] as [number, number]
    const end = path[i + 1] as [number, number]

    const dx = end[0] - start[0]
    const dy = end[1] - start[1]
    const L = Math.sqrt(dx * dx + dy * dy)
    if (L < 1e-9) continue

    const ux = dx / L
    const uy = dy / L
    const nx = -uy
    const ny = ux

    const numTeeth = Math.max(1, Math.floor(L / toothWidth))
    const actualWidth = L / numTeeth

    for (let j = 0; j < numTeeth; j++) {
      const t1 = j * actualWidth
      const t2 = t1 + actualWidth * 0.5
      const t3 = (j + 1) * actualWidth

      coords.push([start[0] + ux * t1, start[1] + uy * t1])
      coords.push([
        start[0] + ux * t2 + nx * toothHeight,
        start[1] + uy * t2 + ny * toothHeight,
      ])
      coords.push([start[0] + ux * t3, start[1] + uy * t3])
    }
  }
  coords.push(path[path.length - 1] as [number, number])
  return coords
}
