import httpx
from typing import Any

BASE_URL = 'https://api.fathom.ai/external/v1'


class FathomClient:
    def __init__(self, api_key: str, timeout: int = 30):
        self._client = httpx.AsyncClient(
            base_url=BASE_URL,
            headers={'X-Api-Key': api_key},
            timeout=timeout,
        )

    async def _get(self, path: str, params: dict[str, Any] | None = None) -> dict:
        params = {k: v for k, v in (params or {}).items() if v is not None}
        resp = await self._client.get(path, params=params)
        resp.raise_for_status()
        return resp.json()

    async def _post(self, path: str, json: dict[str, Any]) -> dict:
        resp = await self._client.post(path, json=json)
        resp.raise_for_status()
        return resp.json()

    async def _delete(self, path: str) -> None:
        resp = await self._client.delete(path)
        resp.raise_for_status()

    async def list_meetings(
        self,
        cursor: str | None = None,
        created_after: str | None = None,
        created_before: str | None = None,
        meeting_type: str | None = None,
        calendar_invitees_domains: list[str] | None = None,
        calendar_invitees_domains_type: str | None = None,
        recorded_by: list[str] | None = None,
        teams: list[str] | None = None,
        include_transcript: bool = False,
        include_summary: bool = False,
        include_action_items: bool = False,
        include_crm_matches: bool = False,
    ) -> dict:
        params: dict[str, Any] = {
            'cursor': cursor,
            'created_after': created_after,
            'created_before': created_before,
            'meeting_type': meeting_type,
            'calendar_invitees_domains_type': calendar_invitees_domains_type,
            'include_transcript': include_transcript or None,
            'include_summary': include_summary or None,
            'include_action_items': include_action_items or None,
            'include_crm_matches': include_crm_matches or None,
        }
        if calendar_invitees_domains:
            for domain in calendar_invitees_domains:
                params.setdefault('calendar_invitees_domains[]', [])
                params['calendar_invitees_domains[]'] = calendar_invitees_domains
        if recorded_by:
            params['recorded_by[]'] = recorded_by
        if teams:
            params['teams[]'] = teams
        return await self._get('/meetings', params)

    async def get_transcript(self, recording_id: int) -> dict:
        return await self._get(f'/recordings/{recording_id}/transcript')

    async def get_summary(self, recording_id: int) -> dict:
        return await self._get(f'/recordings/{recording_id}/summary')

    async def list_teams(self, cursor: str | None = None) -> dict:
        return await self._get('/teams', {'cursor': cursor})

    async def list_team_members(
        self,
        team: str | None = None,
        cursor: str | None = None,
    ) -> dict:
        return await self._get('/team_members', {'cursor': cursor, 'team': team})

    async def create_webhook(
        self,
        destination_url: str,
        triggered_for: list[str],
        include_transcript: bool = False,
        include_summary: bool = False,
        include_action_items: bool = False,
        include_crm_matches: bool = False,
    ) -> dict:
        return await self._post('/webhooks', {
            'destination_url': destination_url,
            'triggered_for': triggered_for,
            'include_transcript': include_transcript,
            'include_summary': include_summary,
            'include_action_items': include_action_items,
            'include_crm_matches': include_crm_matches,
        })

    async def delete_webhook(self, webhook_id: str) -> None:
        await self._delete(f'/webhooks/{webhook_id}')

    async def close(self):
        await self._client.aclose()
