"""
AIS Intelligence Python SDK
Docs: https://ais.binnacleai.com/sdk
Get a key: https://ais.binnacleai.com/signup

Install: pip install httpx
Usage:
    from ais_intelligence import AISClient
    client = AISClient("ais_live_...")
    vessels = client.live_vessels()
"""
import httpx
from typing import Optional, List

BASE = "https://ais.binnacleai.com"


class AISClient:
    def __init__(self, api_key: str, base_url: str = BASE):
        self.api_key = api_key
        self.base = base_url.rstrip("/")
        self._h = {"X-API-Key": api_key}

    def _get(self, path: str, **params):
        p = {k: v for k, v in params.items() if v is not None}
        r = httpx.get(f"{self.base}{path}", headers=self._h, params=p, timeout=15)
        r.raise_for_status()
        return r.json()

    def _post(self, path: str, json=None):
        r = httpx.post(f"{self.base}{path}", headers=self._h, json=json, timeout=15)
        r.raise_for_status()
        return r.json()

    # ── Public ──────────────────────────────────────────────────────────────

    def health(self):
        return httpx.get(f"{self.base}/v1/health").json()

    # ── Vessels ─────────────────────────────────────────────────────────────

    def live_vessels(self, bbox: Optional[str] = None, minutes: int = 60,
                     type_code: Optional[int] = None):
        return self._get("/v1/vessels/live", bbox=bbox, minutes=minutes, type_code=type_code)

    def live_geojson(self, bbox: Optional[str] = None, minutes: int = 60):
        return self._get("/v1/vessels/live.geojson", bbox=bbox, minutes=minutes)

    def vessel(self, mmsi: str):
        return self._get(f"/v1/vessels/{mmsi}")

    def track(self, mmsi: str, hours: int = 24):
        return self._get(f"/v1/vessels/{mmsi}/track", hours=hours)

    def voyages(self, mmsi: str):
        return self._get(f"/v1/vessels/{mmsi}/voyages")

    def search(self, name: str):
        return self._get("/v1/search", name=name)

    def fleet_lookup(self, mmsis: List[str]):
        return self._get("/v1/fleet", mmsis=",".join(mmsis))

    # ── Intelligence ─────────────────────────────────────────────────────────

    def dark_ships(self, silent_minutes: int = 360, active_hours: int = 72,
                   bbox: Optional[str] = None):
        return self._get("/v1/intelligence/dark", silent_minutes=silent_minutes,
                          active_hours=active_hours, bbox=bbox)

    def anchored(self, port: str, min_minutes: int = 60):
        return self._get("/v1/intelligence/anchored", port=port, min_minutes=min_minutes)

    def anomalies(self, hours: int = 12):
        return self._get("/v1/intelligence/anomalies", hours=hours)

    def gaps(self, mmsi: str, days: int = 7, min_gap_hours: float = 4.0):
        return self._get("/v1/intelligence/gaps", mmsi=mmsi, days=days,
                          min_gap_hours=min_gap_hours)

    def congestion(self, port: str):
        return self._get("/v1/intelligence/congestion", port=port)

    def eta(self, mmsi: str, port: str):
        return self._get("/v1/intelligence/eta", mmsi=mmsi, port=port)

    def fishing_effort(self, hours: int = 24, lat_min: float = 54.0, lat_max: float = 60.0,
                       lng_min: float = -157.0, lng_max: float = -130.0,
                       grid_size: float = 0.1):
        return self._get("/v1/intelligence/fishing-effort", hours=hours,
                          lat_min=lat_min, lat_max=lat_max,
                          lng_min=lng_min, lng_max=lng_max, grid_size=grid_size)

    def proximity(self, mmsi1: str, mmsi2: str, alert_nm: float = 1.0):
        return self._get("/v1/intelligence/proximity", mmsi1=mmsi1, mmsi2=mmsi2,
                          alert_nm=alert_nm)

    # ── Area ─────────────────────────────────────────────────────────────────

    def heatmap(self, bbox: str, resolution: float = 0.1, hours: int = 24):
        return self._get("/v1/area/heatmap", bbox=bbox, resolution=resolution, hours=hours)

    def heatmap_geojson(self, bbox: str, resolution: float = 0.1, hours: int = 24):
        return self._get("/v1/area/heatmap.geojson", bbox=bbox, resolution=resolution,
                          hours=hours)

    def area_traffic(self, bbox: str, hours: int = 24):
        return self._get("/v1/area/traffic", bbox=bbox, hours=hours)

    # ── Reports ──────────────────────────────────────────────────────────────

    def port_report(self, port: str, days: int = 7):
        return self._get(f"/v1/reports/port/{port}", days=days)

    # ── Fleets ───────────────────────────────────────────────────────────────

    def fleets(self):
        return self._get("/v1/fleets")

    def create_fleet(self, name: str, mmsis: List[str]):
        return self._post("/v1/fleets", {"name": name, "mmsis": mmsis})

    def fleet_positions(self, fleet_id: int):
        return self._get(f"/v1/fleets/{fleet_id}/positions")

    def add_fleet_mmsis(self, fleet_id: int, mmsis: List[str]):
        return self._post(f"/v1/fleets/{fleet_id}/mmsis", {"mmsis": mmsis})

    # ── Account ───────────────────────────────────────────────────────────────

    def rotate_key(self):
        return self._post("/v1/keys/rotate")

    def usage_breakdown(self, days: int = 30):
        return self._get("/v1/usage/breakdown", days=days)
