"""
senzib.integrations.amocrm.utils

Вспомогательные функции для работы с amoCRM:

- Извлечение значения из custom_fields.
- Построение параметров фильтра для приватного AJAX эндпоинта leads/list.
- Построение карты {pipeline_id: [status_id, ...]} из уже загруженных данных воронок.
"""

from __future__ import annotations

from typing import Any, Dict, Iterable, List, Optional, Tuple


def get_custom_field_value(
    custom_fields: Optional[Iterable[Dict[str, Any]]],
    field_id: Any,
) -> Any:
    """
    Возвращает значение кастомного поля по его ID из массива custom_fields amoCRM.

    :param custom_fields:
        То, что приходит из amoCRM в custom_fields_values:
            [
                {"field_id": 123456, "values": [{"value": "some value"}]},
                ...
            ]

    :param field_id:
        ID поля (int или str). Сравниваем как строки.

    :return:
        value первого элемента values или None,
        если поле не найдено / нет values.
    """
    if not custom_fields:  # None, [], '', и т.п.
        return None

    str_field_id = str(field_id)

    for field in custom_fields:
        if str(field.get("field_id")) == str_field_id:
            values = field.get("values") or []
            if not values:
                return None
            return values[0].get("value")

    return None


def build_filter_params(
    pipeline_statuses: Dict[int, Iterable[int]],
) -> List[Tuple[str, str]]:
    """
    Строит список параметров для фильтра по воронкам/стадиям
    под приватный эндпоинт /ajax/leads/list/.

    На вход подаётся словарь вида:
        {
            123: [456, 789],
            321: [654],
        }

    На выходе будет список пар (key, value):
        [
            ("filter[pipe][123][]", "456"),
            ("filter[pipe][123][]", "789"),
            ("filter[pipe][321][]", "654"),
        ]

    Это удобно передавать в requests.get(..., params=список_пар), чтобы
    не париться с тем, как requests кодирует такие параметры.
    """
    params: List[Tuple[str, str]] = []
    for pipe_id, statuses in pipeline_statuses.items():
        for st in statuses:
            params.append((f"filter[pipe][{pipe_id}][]", str(st)))
    return params


def build_pipeline_status_map(
    pipelines_data: Dict[str, Any],
    include_empty: bool = False,
) -> Dict[int, List[int]]:
    """
    Собирает карту {pipeline_id: [status_id, ...]} из уже загруженных данных
    /api/v4/leads/pipelines.

    ВАЖНО:
    - Функция НЕ вызывает API.
    - Ей передаётся результат client.get_pipelines(...) или аналогичный dict.

    Пример использования:

        pipelines_data = client.get_pipelines()  # это делает приложение
        status_map = build_pipeline_status_map(pipelines_data)

    :param pipelines_data:
        dict, как возвращает get_pipelines(...):
            {
                "_embedded": {
                    "pipelines": [
                        {
                            "id": 123,
                            "_embedded": {
                                "statuses": [
                                    {"id": 111, ...},
                                    {"id": 222, ...},
                                ]
                            }
                        },
                        ...
                    ]
                }
            }

    :param include_empty:
        Если True — добавлять воронки даже без статусов.
        Если False (по умолчанию) — такие воронки пропускаются.

    :return:
        {pipeline_id: [status_id, ...]}
    """
    result: Dict[int, List[int]] = {}
    if not pipelines_data:
        return result

    embedded = pipelines_data.get("_embedded") or {}
    pipelines = embedded.get("pipelines") or []

    for pipe in pipelines:
        pid = pipe.get("id")
        if pid is None:
            continue

        statuses: List[int] = []
        pipe_emb = pipe.get("_embedded") or {}
        for st in pipe_emb.get("statuses") or []:
            sid = st.get("id")
            if sid is not None:
                statuses.append(int(sid))

        if statuses or include_empty:
            result[int(pid)] = statuses

    return result


__all__ = [
    "get_custom_field_value",
    "build_filter_params",
    "build_pipeline_status_map",
]
