from __future__ import annotations

from typing import Any
import httpx
from .settings import settings


class ThreeCXClient:
    def __init__(self) -> None:
        self.base_url = settings.cx_base_url.rstrip('/')

    async def token(self) -> str:
        url = f'{self.base_url}{settings.cx_token_path}'
        data = {
            'client_id': settings.cx_client_id,
            'client_secret': settings.cx_client_secret,
            'grant_type': 'client_credentials',
        }
        async with httpx.AsyncClient(timeout=30) as client:
            response = await client.post(url, data=data)
            response.raise_for_status()
            payload = response.json()
            return payload['access_token']

    async def users(self) -> list[dict[str, Any]]:
        access_token = await self.token()
        url = f'{self.base_url}{settings.cx_users_path}'
        headers = {'Authorization': f'Bearer {access_token}', 'Accept': 'application/json'}
        async with httpx.AsyncClient(timeout=60) as client:
            response = await client.get(url, headers=headers)
            response.raise_for_status()
            payload = response.json()

        # OData usually returns {"value": [...]}; keep fallback for custom gateways.
        if isinstance(payload, dict) and isinstance(payload.get('value'), list):
            return payload['value']
        if isinstance(payload, list):
            return payload
        raise ValueError('Unexpected 3CX users response format')


def pick(data: dict[str, Any], *keys: str) -> Any:
    for key in keys:
        if key in data and data[key] not in (None, ''):
            return data[key]
    return None


def normalize_user(user: dict[str, Any]) -> dict[str, Any]:
    extension = str(pick(user, 'Number', 'number', 'Extension', 'extension', 'DN') or '')
    first_name = pick(user, 'FirstName', 'firstName', 'Name', 'name')
    last_name = pick(user, 'LastName', 'lastName', 'Surname', 'surname')
    display_name = pick(user, 'DisplayName', 'displayName') or ' '.join(str(x) for x in [first_name, last_name] if x) or extension
    return {
        'id': extension or str(pick(user, 'Id', 'id')),
        'extension': extension or None,
        'first_name': first_name,
        'last_name': last_name,
        'display_name': display_name,
        'email': pick(user, 'EmailAddress', 'emailAddress', 'Email', 'email'),
        'mobile': pick(user, 'Mobile', 'mobile', 'MobileNumber', 'mobileNumber'),
        'direct_number': pick(user, 'OutboundCallerID', 'outboundCallerID', 'DID', 'did'),
        'department': pick(user, 'Department', 'department', 'GroupName', 'groupName'),
        'job_title': pick(user, 'Title', 'title', 'JobTitle', 'jobTitle'),
    }
