from typing import Any, Dict, List, Optional, Union, cast
from datetime import datetime

import httpx

from ..client import Client
from ..errors import ApiResponseError
from ..models.http_validation_error import HTTPValidationError
from ..models.programs import Programs
from ..models.program import Program


def get_programs(
    *,
    client: Client,
    name: Optional[str] = None,
    types: Optional[List[str]] = None,
    platforms: Optional[List[str]] = None,
    exclude_platforms: Optional[List[str]] = None,
    rewards: Optional[List[str]] = None,
    page: Optional[int] = None,
    created_since: Optional[datetime] = None,
) -> Union[Programs, HTTPValidationError]:
    url = "{}/v0b/programs".format(client.base_url)

    params: Dict[str, Any] = {}
    if name is not None:
        params["name"] = name
    if types is not None:
        params["types"] = types
    if platforms is not None:
        params["platforms"] = platforms
    if exclude_platforms is not None:
        params["excludePlatforms"] = exclude_platforms
    if rewards is not None:
        params["rewards"] = rewards
    if page is not None:
        params["page"] = page
    if created_since is not None:
        params["createdSince"] = created_since.strftime("%Y-%m-%dT%H:%M:%SZ")

    response = httpx.get(url=url, headers=client.get_headers(), params=params)

    if response.status_code == 200:
        return Programs.from_dict(cast(Dict[str, Any], response.json()))
    if response.status_code == 422:
        return HTTPValidationError.from_dict(cast(Dict[str, Any], response.json()))
    if response.status_code == 401:
        return HTTPValidationError.from_dict(cast(Dict[str, Any], response.json()))
    else:
        raise ApiResponseError(response=response)


def get_program(*, client: Client, slug: str) -> Union[Program, HTTPValidationError]:
    url = "{}/v0b/programs/{slug}".format(client.base_url, slug=slug)
    response = httpx.get(url=url, headers=client.get_headers())

    if response.status_code == 200:
        return Program.from_dict(cast(Dict[str, Any], response.json()))
    if response.status_code == 422:
        return HTTPValidationError.from_dict(cast(Dict[str, Any], response.json()))
    if response.status_code == 401:
        return HTTPValidationError.from_dict(cast(Dict[str, Any], response.json()))
    else:
        raise ApiResponseError(response=response)
