/**
 * Terrain Service – Phase 4 stub.
 *
 * Provides elevation queries that future phases will use for:
 *  - Line-of-sight (LOS) / non-LOS classification
 *  - Diffraction loss (knife-edge / Bullington)
 *  - Terrain-aware heatmaps
 *
 * For now we expose the interface and a flat-terrain mock.
 * Switch to BackendTerrainService once the FastAPI `/api/terrain/*`
 * endpoints are ready with real SRTM / DEM data.
 */

export interface TerrainService {
  /** Return ground elevation (metres above sea level) at a point. */
  getElevation(lat: number, lon: number): Promise<number>;

  /**
   * Return an elevation profile between two points.
   * @param samples  Number of equidistant samples along the path.
   * @returns        Array of elevations (metres) from start to end.
   */
  getElevationProfile(
    lat1: number,
    lon1: number,
    lat2: number,
    lon2: number,
    samples: number,
  ): Promise<number[]>;
}

// ---------------------------------------------------------------------------
// Mock – flat terrain (elevation 0 everywhere)
// ---------------------------------------------------------------------------
export class MockTerrainService implements TerrainService {
  async getElevation(_lat: number, _lon: number): Promise<number> {
    return 0;
  }

  async getElevationProfile(
    _lat1: number,
    _lon1: number,
    _lat2: number,
    _lon2: number,
    samples: number,
  ): Promise<number[]> {
    return Array(samples).fill(0);
  }
}

// ---------------------------------------------------------------------------
// Backend – calls FastAPI terrain endpoints (Phase 4+)
// ---------------------------------------------------------------------------
export class BackendTerrainService implements TerrainService {
  private apiUrl: string;

  constructor(apiUrl: string) {
    this.apiUrl = apiUrl;
  }

  async getElevation(lat: number, lon: number): Promise<number> {
    const response = await fetch(
      `${this.apiUrl}/api/terrain/elevation?lat=${lat}&lon=${lon}`,
    );
    if (!response.ok) throw new Error(`Terrain API error: ${response.status}`);
    const data = await response.json();
    return data.elevation;
  }

  async getElevationProfile(
    lat1: number,
    lon1: number,
    lat2: number,
    lon2: number,
    samples: number,
  ): Promise<number[]> {
    const response = await fetch(
      `${this.apiUrl}/api/terrain/profile?lat1=${lat1}&lon1=${lon1}&lat2=${lat2}&lon2=${lon2}&samples=${samples}`,
    );
    if (!response.ok) throw new Error(`Terrain API error: ${response.status}`);
    const data = await response.json();
    return data.profile;
  }
}

// ---------------------------------------------------------------------------
// Default export – use Mock until backend is ready
// ---------------------------------------------------------------------------
export const terrainService: TerrainService = new MockTerrainService();
