//! CLI interface for NASA Earthdata SRTM tile downloads
//!
//! This binary provides a command-line interface for downloading SRTM tiles
//! using the elevation_nasa_core library.

use clap::{Arg, Command};
use elevation_nasa_core::tile::{download_tile, ensure_dem_for_bounds, ensure_dem_for_path, tiles_for_bounds};
use log::{error, info};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();

    let matches = Command::new("elevation_nasa")
        .version("0.1.0")
        .author("RMP")
        .about("NASA Earthdata SRTM tile downloader")
        .subcommand(
            Command::new("download")
                .about("Download a single SRTM tile")
                .arg(Arg::new("tile").required(true).help("SRTM tile name (e.g., N45W074)"))
                .arg(Arg::new("dest").required(true).help("Destination directory"))
                .arg(Arg::new("token").long("token").help("NASA Earthdata token (defaults to EARTHDATA_TOKEN env)")),
        )
        .subcommand(
            Command::new("bounds")
                .about("Download all tiles for a bounding box")
                .arg(Arg::new("min_lat").required(true).help("Minimum latitude"))
                .arg(Arg::new("min_lon").required(true).help("Minimum longitude"))
                .arg(Arg::new("max_lat").required(true).help("Maximum latitude"))
                .arg(Arg::new("max_lon").required(true).help("Maximum longitude"))
                .arg(Arg::new("dest").required(true).help("Destination directory"))
                .arg(Arg::new("token").long("token").help("NASA Earthdata token")),
        )
        .subcommand(
            Command::new("path")
                .about("Ensure DEM file exists, download if missing")
                .arg(Arg::new("dem_path").required(true).help("Path to DEM file"))
                .arg(Arg::new("token").long("token").help("NASA Earthdata token")),
        )
        .subcommand(
            Command::new("list")
                .about("List tiles for a bounding box without downloading")
                .arg(Arg::new("min_lat").required(true).help("Minimum latitude"))
                .arg(Arg::new("min_lon").required(true).help("Minimum longitude"))
                .arg(Arg::new("max_lat").required(true).help("Maximum latitude"))
                .arg(Arg::new("max_lon").required(true).help("Maximum longitude")),
        )
        .get_matches();

    match matches.subcommand() {
        Some(("download", args)) => {
            let tile = args.get_one::<String>("tile").unwrap();
            let dest = args.get_one::<String>("dest").unwrap();
            let token = args.get_one::<String>("token").cloned();
            
            match download_tile(tile, dest, token).await {
                Ok(path) => info!("Downloaded: {}", path.display()),
                Err(e) => error!("Failed to download: {}", e),
            }
        }
        Some(("bounds", args)) => {
            let min_lat: f64 = args.get_one::<String>("min_lat").unwrap().parse()?;
            let min_lon: f64 = args.get_one::<String>("min_lon").unwrap().parse()?;
            let max_lat: f64 = args.get_one::<String>("max_lat").unwrap().parse()?;
            let max_lon: f64 = args.get_one::<String>("max_lon").unwrap().parse()?;
            let dest = args.get_one::<String>("dest").unwrap();
            let token = args.get_one::<String>("token").cloned();
            
            match ensure_dem_for_bounds(min_lat, min_lon, max_lat, max_lon, dest, token).await {
                Ok(paths) => {
                    info!("Downloaded {} tiles:", paths.len());
                    for p in paths {
                        info!("  {}", p.display());
                    }
                }
                Err(e) => error!("Failed to download tiles: {}", e),
            }
        }
        Some(("path", args)) => {
            let dem_path = args.get_one::<String>("dem_path").unwrap();
            let token = args.get_one::<String>("token").cloned();
            
            match ensure_dem_for_path(dem_path, token).await {
                Ok(path) => info!("DEM file ready: {}", path),
                Err(e) => error!("Failed to ensure DEM: {}", e),
            }
        }
        Some(("list", args)) => {
            let min_lat: f64 = args.get_one::<String>("min_lat").unwrap().parse()?;
            let min_lon: f64 = args.get_one::<String>("min_lon").unwrap().parse()?;
            let max_lat: f64 = args.get_one::<String>("max_lat").unwrap().parse()?;
            let max_lon: f64 = args.get_one::<String>("max_lon").unwrap().parse()?;
            
            let tiles = tiles_for_bounds(min_lat, min_lon, max_lat, max_lon);
            info!("Tiles for bounds ({}, {}, {}, {}):", min_lat, min_lon, max_lat, max_lon);
            for tile in tiles {
                info!("  {}", tile);
            }
        }
        _ => {
            Command::new("elevation_nasa")
                .version("0.1.0")
                .author("RMP")
                .about("NASA Earthdata SRTM tile downloader")
                .print_long_help()?;
        }
    }

    Ok(())
}
