import logging
from operator import itemgetter

from maps_adv.export.lib.core.url_signer import ActionUrlSigner

from .advert_data import advert_data_transform
from .advert_tag import advert_tag_transform, advert_tag_hash
from .menu_item import menu_item_transform
from .pin_data import pin_data_transform
from .place import place_transform
from .polygon import polygon_transform

logger = logging.getLogger(__name__)


async def pipeline_data_transform(
    data: dict, navi_signer: ActionUrlSigner, ctype: str
) -> tuple[dict, dict]:
    menu_item_list = []
    advert_data_list = []
    pin_data_list = []
    advert_tag_list = []
    place_list = []
    polygon_list = []

    for campaign in sorted(data["campaigns"], key=itemgetter("id")):
        menu_item = await menu_item_transform(campaign)
        if menu_item:
            menu_item_list.append(menu_item)

        advert_data = await advert_data_transform(campaign)
        if advert_data:
            advert_data_list.extend(advert_data)

        pin_data = await pin_data_transform(campaign, navi_signer, ctype)
        if pin_data:
            pin_data_list.extend(pin_data)

    for search_tag in data["search_tags"]:
        advert_tag = await advert_tag_transform(search_tag)
        if advert_tag:
            advert_tag_list.append(advert_tag)

    places = sorted(map(lambda item: (str(item[0]), item[1]), data["places"].items()))
    for _, item in places:
        place = await place_transform(item)
        place_list.append(place)

    polygons = sorted(
        map(lambda item: (str(item[0]), item[1]), data["polygons"].items())
    )
    for _, item in polygons:
        polygon = await polygon_transform(item)
        polygon_list.append(polygon)

    # remove duplicates (items with the same id) from menu items
    menu_item_list_by_id = {item["id"]: item for item in menu_item_list}

    if len(menu_item_list) != len(menu_item_list_by_id):
        uniques = []
        dups = []
        for each in menu_item_list:
            if each["id"] not in uniques:
                uniques.append(each["id"])
            else:
                dups.append(each["id"])
        logger.error(f"Duplicated menu items for campaigns {dups}")
        # GEODISPLAY-1438 TODO вернуть репорт взамен sentry

    xml_data = dict(
        menu_items=list(menu_item_list_by_id.values()),
        advert_data_list=advert_data_list,
        advert_tags=advert_tag_list,
        places=place_list,
        polygons=polygon_list,
        pin_data_list=pin_data_list,
    )

    attrs = dict(
        advert_tag_hash=advert_tag_hash(advert_tag_list),
    )

    return xml_data, attrs
