"""
DataDocked API Client
Handles all HTTP requests to the DataDocked Maritime API
"""

import os
from typing import Optional
from dataclasses import dataclass
import httpx

BASE_URL = "https://datadocked.com/api"

# Credit costs per endpoint
CREDIT_COSTS = {
    "get-vessel-location": 1,
    "get-vessels-location-bulk": 1,  # per vessel
    "get-vessel-historical-data": 5,  # per day
    "get-vessels-by-area": 10,
    "get-vessel-info": 5,
    "get-vessel-particulars": 3,
    "get-engine-data": 3,
    "get-management-data": 3,
    "get-port-calls": 1,
    "get-port-traffic": 5,
    "get-psc-inspections": 3,
    "get-weather": 2,
}


@dataclass
class VesselLocation:
    imo: str
    mmsi: str
    name: str
    latitude: float
    longitude: float
    speed: float
    course: float
    heading: float
    destination: str
    eta: str
    timestamp: str
    nav_status: str


@dataclass
class VesselDetails:
    imo: str
    mmsi: str
    name: str
    type: str
    flag: str
    built: int
    call_sign: str
    gross_tonnage: int
    deadweight: int
    length: float
    beam: float
    draft: float


@dataclass
class VesselParticulars:
    imo: str
    length_overall: float
    beam: float
    depth: float
    draft: float
    gross_tonnage: int
    net_tonnage: int
    deadweight: int
    teu_capacity: Optional[int] = None


@dataclass
class EngineData:
    imo: str
    main_engine_type: str
    main_engine_power: int
    fuel_type: str
    speed_service: float
    speed_max: float


@dataclass
class ManagementData:
    imo: str
    owner: str
    operator: str
    manager: str
    p_and_i_club: str
    class_society: str


@dataclass
class PortCall:
    port_code: str
    port_name: str
    country: str
    arrival: str
    departure: str
    time_in_port_hours: float


@dataclass
class PortTraffic:
    port_code: str
    arrivals: list
    departures: list
    expected: list


@dataclass
class PSCInspection:
    date: str
    port: str
    country: str
    deficiencies: int
    detained: bool
    detention_days: Optional[int] = None


@dataclass
class WeatherData:
    latitude: float
    longitude: float
    temperature_c: float
    wind_speed_kts: float
    wind_direction: int
    wave_height_m: float
    visibility_nm: float
    conditions: str


@dataclass
class HistoricalPosition:
    latitude: float
    longitude: float
    speed: float
    course: float
    timestamp: str


@dataclass
class CreditInfo:
    credits_remaining: int
    credits_used_today: int
    plan: str


class DataDockedClient:
    """Client for the DataDocked Maritime API"""

    def __init__(self, api_key: Optional[str] = None, show_cost: bool = True):
        self.api_key = api_key or os.environ.get("DATADOCKED_API_KEY", "")
        self.show_cost = show_cost

        if not self.api_key:
            raise ValueError(
                "DATADOCKED_API_KEY is required. "
                "Set it as an environment variable or pass it to the constructor."
            )

        self.client = httpx.AsyncClient(
            base_url=BASE_URL,
            headers={
                "x-api-key": self.api_key,
                "Content-Type": "application/json",
            },
            timeout=30.0,
        )

    async def _request(self, endpoint: str, params: Optional[dict] = None) -> dict:
        """Make an API request"""
        response = await self.client.get(
            f"/vessels_operations/{endpoint}",
            params=params or {},
        )
        response.raise_for_status()
        return response.json()

    def estimate_cost(self, endpoint: str, multiplier: int = 1) -> int:
        """Estimate credit cost for an operation"""
        base_cost = CREDIT_COSTS.get(endpoint, 1)
        return base_cost * multiplier

    # === TRACKING ENDPOINTS ===

    async def get_vessel_location(self, imo_or_mmsi: str) -> dict:
        """Get real-time vessel position"""
        return await self._request(
            "get-vessel-location",
            {"imo_or_mmsi": imo_or_mmsi},
        )

    async def get_vessels_location_bulk(self, identifiers: list[str]) -> dict:
        """Get positions for multiple vessels"""
        return await self._request(
            "get-vessels-location-bulk",
            {"imo_or_mmsi_list": ",".join(identifiers)},
        )

    async def get_vessel_historical_data(
        self, imo_or_mmsi: str, start_date: str, end_date: str
    ) -> dict:
        """Get historical positions"""
        return await self._request(
            "get-vessel-historical-data",
            {
                "imo_or_mmsi": imo_or_mmsi,
                "start_date": start_date,
                "end_date": end_date,
            },
        )

    async def get_vessels_by_area(
        self,
        lat1: float,
        lon1: float,
        lat2: float,
        lon2: float,
        vessel_type: Optional[str] = None,
    ) -> dict:
        """Get vessels in a geographic area"""
        params = {"lat1": lat1, "lon1": lon1, "lat2": lat2, "lon2": lon2}
        if vessel_type:
            params["vessel_type"] = vessel_type
        return await self._request("get-vessels-by-area", params)

    # === VESSEL DETAILS ENDPOINTS ===

    async def get_vessel_info(self, imo: str) -> dict:
        """Get full vessel profile"""
        return await self._request("get-vessel-info", {"imo": imo})

    async def get_vessel_particulars(self, imo: str) -> dict:
        """Get vessel dimensions and tonnage"""
        return await self._request("get-vessel-particulars", {"imo": imo})

    async def get_engine_data(self, imo: str) -> dict:
        """Get engine specifications"""
        return await self._request("get-engine-data", {"imo": imo})

    async def get_management_data(self, imo: str) -> dict:
        """Get ownership and management info"""
        return await self._request("get-management-data", {"imo": imo})

    # === PORT ENDPOINTS ===

    async def get_port_calls(self, imo_or_mmsi: str) -> dict:
        """Get port call history"""
        return await self._request(
            "get-port-calls",
            {"imo_or_mmsi": imo_or_mmsi},
        )

    async def get_port_traffic(self, port_code: str) -> dict:
        """Get port traffic"""
        return await self._request("get-port-traffic", {"port_code": port_code})

    # === COMPLIANCE ENDPOINTS ===

    async def get_psc_inspections(self, imo: str) -> dict:
        """Get PSC inspection history"""
        return await self._request("get-psc-inspections", {"imo": imo})

    async def get_weather(self, latitude: float, longitude: float) -> dict:
        """Get weather at location"""
        return await self._request(
            "get-weather",
            {"latitude": latitude, "longitude": longitude},
        )

    # === ACCOUNT ===

    async def get_credit_balance(self) -> dict:
        """Get credit balance"""
        return await self._request("get-credit-balance")

    async def close(self):
        """Close the HTTP client"""
        await self.client.aclose()
