//! BigDataCloud — IP Geolocation Sample
//! Run: BIGDATACLOUD_API_KEY=your-key cargo run --example ip_geolocation

use bigdatacloud::{Client, confidence_area::split_into_polygons};

fn main() {
    let client = Client::from_environment().expect("Failed to create client");

    // 1. IP Geolocation
    println!("=== IP Geolocation ===");
    let geo = client.ip_geolocation.get(Some("1.1.1.1"), "en").unwrap();
    println!("IP:           {}", geo.ip.as_deref().unwrap_or(""));
    let loc = geo.location.as_ref().unwrap();
    println!("City:         {}", loc.city.as_deref().unwrap_or(""));
    println!("Subdivision:  {}", loc.principal_subdivision.as_deref().unwrap_or(""));
    let country = geo.country.as_ref().unwrap();
    println!("Country:      {} ({})", country.name.as_deref().unwrap_or(""), country.iso_alpha2.as_deref().unwrap_or(""));
    let net = geo.network.as_ref().unwrap();
    println!("Organisation: {}", net.organisation.as_deref().unwrap_or(""));
    println!("BGP Prefix:   {}", net.bgp_prefix.as_deref().unwrap_or(""));
    println!("Last Updated: {}", geo.last_updated.as_deref().unwrap_or(""));

    // 2. With Confidence Area
    println!("\n=== IP Geolocation with Confidence Area ===");
    let geo_area = client.ip_geolocation.get_with_confidence_area(Some("1.1.1.1"), "en").unwrap();
    let loc = geo_area.location.as_ref().unwrap();
    let country = geo_area.country.as_ref().unwrap();
    println!("City:         {}, {}", loc.city.as_deref().unwrap_or(""), country.name.as_deref().unwrap_or(""));
    println!("Confidence:   {}", geo_area.confidence.as_deref().unwrap_or(""));
    let points = geo_area.confidence_area.as_deref().unwrap_or(&[]);
    let polygons = split_into_polygons(points);
    println!("Total points: {}", points.len());
    println!("Polygons:     {}", polygons.len());
    for (i, ring) in polygons.iter().enumerate() {
        println!("  Ring {}: {} points", i + 1, ring.len());
    }

    // 3. Full with Hazard Report
    println!("\n=== Full Geolocation + Hazard Report ===");
    let full = client.ip_geolocation.get_full(Some("185.220.101.1"), "en").unwrap();
    let loc = full.location.as_ref().unwrap();
    let country = full.country.as_ref().unwrap();
    println!("IP:            {}", full.ip.as_deref().unwrap_or(""));
    println!("City:          {}, {}", loc.city.as_deref().unwrap_or(""), country.name.as_deref().unwrap_or(""));
    println!("Threat:        {}", full.security_threat.as_deref().unwrap_or(""));
    let hazard = full.hazard_report.as_ref().unwrap();
    println!("Is Tor:        {}", hazard.is_known_as_tor_server.unwrap_or(false));
    println!("Hosting Score: {}/10", hazard.hosting_likelihood.unwrap_or(0));

    // 4. Country by IP
    println!("\n=== Country by IP ===");
    let c = client.ip_geolocation.get_country_by_ip(Some("8.8.8.8"), "en").unwrap();
    let country = c.country.as_ref().unwrap();
    let currency = country.currency.as_ref().unwrap();
    println!("Country:  {} ({})", country.name.as_deref().unwrap_or(""), country.iso_alpha2.as_deref().unwrap_or(""));
    println!("Currency: {} — {}", currency.code.as_deref().unwrap_or(""), currency.name.as_deref().unwrap_or(""));
    println!("Calling:  +{}", country.calling_code.as_deref().unwrap_or(""));

    // 5. Country Info
    println!("\n=== Country Info (AU) ===");
    let info = client.ip_geolocation.get_country_info("AU", "en").unwrap();
    println!("Name:      {} ({})", info.name.as_deref().unwrap_or(""), info.iso_alpha2.as_deref().unwrap_or(""));
    println!("Full name: {}", info.iso_name_full.as_deref().unwrap_or(""));
    println!("Region:    {}", info.un_region.as_deref().unwrap_or(""));
    println!("WB Income: {}", info.wb_income_level.as_ref().and_then(|w| w.value.as_deref()).unwrap_or(""));
    println!("Flag:      {}", info.country_flag_emoji.as_deref().unwrap_or(""));

    // 6. All Countries
    println!("\n=== All Countries (first 3) ===");
    let countries = client.ip_geolocation.get_all_countries("en").unwrap();
    println!("Total: {}", countries.len());
    for c in countries.iter().take(3) {
        let code = c.currency.as_ref().and_then(|cu| cu.code.as_deref()).unwrap_or("");
        println!("  {} — {} ({})", c.iso_alpha2.as_deref().unwrap_or(""), c.name.as_deref().unwrap_or(""), code);
    }

    // 7. Hazard Report
    println!("\n=== Hazard Report ===");
    let hazard = client.ip_geolocation.get_hazard_report(Some("185.220.101.1")).unwrap();
    println!("Is Tor:        {}", hazard.is_known_as_tor_server.unwrap_or(false));
    println!("Is VPN:        {}", hazard.is_known_as_vpn.unwrap_or(false));
    println!("Hosting Score: {}/10", hazard.hosting_likelihood.unwrap_or(0));
    println!("Spamhaus DROP: {}", hazard.is_spamhaus_drop.unwrap_or(false));

    // 8. User Risk
    println!("\n=== User Risk ===");
    let risk = client.ip_geolocation.get_user_risk(Some("1.1.1.1")).unwrap();
    println!("Risk:        {}", risk.risk.as_deref().unwrap_or(""));
    println!("Description: {}", risk.description.as_deref().unwrap_or(""));

    // 9. ASN Info (short)
    println!("\n=== ASN Info (short) ===");
    let asn = client.ip_geolocation.get_asn_info("AS13335", "en").unwrap();
    println!("ASN:          {} ({})", asn.asn.as_deref().unwrap_or(""), asn.asn_numeric.unwrap_or(0));
    println!("Organisation: {}", asn.organisation.as_deref().unwrap_or(""));
    println!("Registry:     {}", asn.registry.as_deref().unwrap_or(""));
    println!("IPv4 Addrs:   {}", asn.total_ipv4_addresses.unwrap_or(0));
    println!("Rank:         {}", asn.rank_text.as_deref().unwrap_or(""));

    // 10. Network by IP
    println!("\n=== Network by IP ===");
    let net = client.ip_geolocation.get_network_by_ip("8.8.8.8", "en").unwrap();
    println!("BGP Prefix:   {}", net.bgp_prefix.as_deref().unwrap_or(""));
    println!("Organisation: {}", net.organisation.as_deref().unwrap_or(""));
    println!("Registry:     {}", net.registry.as_deref().unwrap_or(""));
    println!("Country:      {}", net.registered_country_name.as_deref().unwrap_or(""));
    println!("Carriers:     {}", net.carriers.as_ref().map(|c| c.len()).unwrap_or(0));

    // 11. Timezone by IANA ID
    println!("\n=== Timezone by IANA ID ===");
    let tz = client.ip_geolocation.get_timezone_by_iana_id("Australia/Adelaide").unwrap();
    println!("IANA ID:    {}", tz.iana_time_id.as_deref().unwrap_or(""));
    println!("Display:    {}", tz.display_name.as_deref().unwrap_or(""));
    println!("UTC Offset: {}", tz.utc_offset.as_deref().unwrap_or(""));
    println!("Local Time: {}", tz.local_time.as_deref().unwrap_or(""));

    // 12. Timezone by IP
    println!("\n=== Timezone by IP ===");
    let tz_ip = client.ip_geolocation.get_timezone_by_ip(Some("203.10.76.1")).unwrap();
    println!("IANA ID:    {}", tz_ip.iana_time_id.as_deref().unwrap_or(""));
    println!("Offset:     {}", tz_ip.utc_offset.as_deref().unwrap_or(""));
    println!("Local Time: {}", tz_ip.local_time.as_deref().unwrap_or(""));

    // 13. User Agent
    println!("\n=== User Agent ===");
    let ua = client.ip_geolocation.parse_user_agent(
        "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 Mobile/15E148 Safari/604.1"
    ).unwrap();
    println!("Device:  {}", ua.device.as_deref().unwrap_or(""));
    println!("OS:      {}", ua.os.as_deref().unwrap_or(""));
    println!("Browser: {}", ua.user_agent.as_deref().unwrap_or(""));
    println!("Mobile:  {}", ua.is_mobile.unwrap_or(false));
    println!("Spider:  {}", ua.is_spider.unwrap_or(false));
}
