from logging import info
from typing import Any

from requests import Response, get, post


class Api:
    def __init__(
        self, base_url: str, username: str, password: str, logging: bool = False
    ) -> None:
        self.base_url: str = base_url
        self.auth: tuple[str, str] = (username, password)
        self.logging: bool = logging

    def log(self, message: str | dict[str, Any]) -> None:
        if self.logging:
            if isinstance(message, dict) and "password" in message:
                message = {**message, "password": "[REDACTED]"}

            info(msg=message)

    def log_response(self, response: Response) -> None:
        if self.logging and not response.ok:
            info(msg=response.status_code)
            info(msg=response.content)

    def get(self, path: str) -> Response:
        self.log(message=f"GET {self.base_url}/{path}")

        response: Response = get(
            url=f"{self.base_url}/{path}",
            headers={
                "Accept": "application/json",
            },
            auth=self.auth,
        )

        self.log_response(response=response)
        return response

    def post(self, path: str, json: dict[str, Any]) -> Response:
        sanitized_json: dict[str, Any] = {**json}
        if "password" in sanitized_json:
            sanitized_json["password"] = "[REDACTED]"
        self.log(message=f"POST {self.base_url}/{path} {sanitized_json}")

        response: Response = post(
            url=f"{self.base_url}/{path}",
            headers={"Accept": "application/json", "Content-Type": "application/json"},
            auth=self.auth,
            json=json,
        )

        self.log_response(response=response)
        return response

    def user(self) -> Response:
        return self.get(path="user/self")

    def create_user(self, email: str, password: str, role: str, name: str) -> Response:
        return self.post(
            path="user",
            json={
                "email": email,
                "password": password,
                "role": role,
                "name": name,
            },
        )

    def create_station(
        self,
        name: str,
        operation_type: str,
        wmo_id: int,
        latitude: float,
        longitude: float,
        altitude: float,
    ) -> Response:
        return self.post(
            path="station",
            json={
                "name": name,
                "type": operation_type,
                "wmo_id": wmo_id,
                "latitude": latitude,
                "longitude": longitude,
                "altitude": altitude,
            },
        )

    def attach_station_to_user(self, user_id: int, station_id: int) -> Response:
        return self.post(path=f"user/{user_id}/attachStation/{station_id}", json={})
