import re
from typing import List

def extract_additional_services(text: str) -> List[str]:
    """
    Извлекает дополнительные услуги ТОЛЬКО из тела письма (без вложений).
    Услуга добавляется, если:
      - упоминается сама услуга,
      - рядом (в пределах ~120 символов) есть слово-запрос,
      - отсутствует отрицание.
    """
    if not text or not text.strip():
        return []

    text_lower = text.lower().strip()

    # ----- вспомогательные функции -----
    def _has_negation_near(regex: str, text_scope: str, window: int = 60) -> bool:
        for m in re.finditer(regex, text_scope):
            start = max(0, m.start() - window)
            end = min(len(text_scope), m.end() + window)
            ctx = text_scope[start:end]
            if re.search(
                r"(?:не\s+(?:нуж(?:ен|на|но|ны)|требу(?:ется|ются)|треб(?:уется|уются)"
                r"|предоставл(?:яется|яются)|план(?:ируется|ируем)|будет|надо)"
                r"|без\s|нет\s+необходимост[и]|не\s+требуется)",
                ctx,
                re.IGNORECASE,
            ):
                return True
        return False

    def _has_request_near(regex: str, text_scope: str, window: int = 120) -> bool:
        for m in re.finditer(regex, text_scope):
            start = max(0, m.start() - window)
            end = min(len(text_scope), m.end() + window)
            ctx = text_scope[start:end]
            if re.search(
                r"(?:необход[иа]м[оы]?|требу[ею]тся?|нуж(?:ен|на|но|ны)|"
                r"прош[уу]|предусмотр[ие]те?|организу[ей]те?|зака[жз]ите?|"
                r"сдела[ей]те?|запросите?|обеспечьте?|просим|пожалуйста|"
                r"просьба|required|please\s+(?:provide|arrange)|need|necessary|"
                r"provide|arrange|request|ensure)",
                ctx,
                re.IGNORECASE,
            ):
                return True
        return False

    # ----- Единый список услуг (упоминание + запрос) -----
    services = {
        # упаковка и тара
        "упаковка / переупаковка": [
            r"переупаковк[аи]", r"упаковк[аи]\s*груза", r"паллет(?:иров|изаци)",
            r"обреш[её]тк[аи]", r"ж[её]стк[аи]я\s+(?:упаковка|тара)",
            r"деревянн[аи]я\s+(?:тара|упаковка)", r"вакуумн[аи]я\s+упаковк[аи]",
            r"креплени[ея]\s+груза", r"страпы|упорные\s+брусья",
        ],
        "маркировка / этикетирование": [
            r"маркировк[аи]", r"этикетировани[ея]",
            r"нанесени[ея]\s+(?:маркировки|знаков\s+опасности)",
            r"штрихкод", r"стикер[а-я]*",
        ],
        "страхование груза": [
            r"страхов(?:ани[ея]|к[аи])\s+груз[а-я]*", r"застраховать\s+груз",
            r"страхов(?:ой|ого)\s+полис", r"cargo\s+insurance",
        ],
        "таможенное оформление / брокерские услуги": [
            r"таможенн(?:ое|ая|ый)\s+оформлени[ея]", r"таможн[а-я]+\s+очистк[аи]",
            r"таможенн[а-я]+\s+брокер", r"customs\s+clearance", r"customs\s+broker",
        ],
        "сертификация / разрешительные документы": [
            r"сертификац[а-я]*", r"сертификат\s+соответствия",
            r"декларац[а-я]*\s+соответствия", r"фитосанитарн[а-я]+\s+сертификац",
            r"ветеринарн[а-я]+\s+сертификац", r"карантинн[а-я]+\s+сертификац",
            r"радиационн[а-я]+\s+контрол[а-я]*", r"сертификат\s+происхождения",
        ],
        "фитосанитарный / карантинный контроль": [
            r"фитосанитарн[а-я]+\s+контрол[а-я]*", r"фитоконтрол[а-я]*",
            r"карантинн[а-я]+\s+контрол[а-я]*",
        ],
        "фумигация": [
            r"фумигац[а-я]*", r"fumigation",
        ],
        "погрузо-разгрузочные работы (ПРР)": [
            r"погрузочн[а-я]*\s*[-–]\s*разгрузочн[а-я]*", r"погрузк[аи]\s*/\s*разгрузк[аи]",
            r"погрузочн[а-я]*\s+работ[а-я]*", r"разгрузочн[а-я]*\s+работ[а-я]*",
            r"грузов[а-я]*\s+работ[а-я]*", r"тальманск[а-я]+\s+услуг",
            r"сюрвейерск[а-я]+\s+услуг",
        ],
        "складские услуги / хранение": [
            r"складск[а-я]+\s+(?:услуг|обработк|логистик)", r"ответственное\s+хранение",
            r"временное\s+хранение", r"бондов[а-я]+\s+склад",
            r"консолидац[а-я]+\s+груз[а-я]*", r"кросс[-\s]?докинг",
            r"управлени[ея]\s+запасами", r"pick\s*(?:&|and)\s*pack",
        ],
        "доставка до двери / last mile": [
            r"доставк[аи]\s+до\s+двер[ией]", r"от\s+двери\s+до\s+двери",
            r"last\s*mile\s*delivery", r"плечев[а-я]+\s+доставк[аи]",
            r"door[-\s]to[-\s]door",
        ],
        "отслеживание / мониторинг груза": [
            r"отслеживани[ея]\s+груз[а-я]*", r"трекинг\s+груз[а-я]*",
            r"мониторинг\s+груз[а-я]*", r"gps[-\s]?слежени[ея]",
            r"датчик[а-я]*\s+(?:удар[а-я]*|вскрыти[ея]|температур)",
            r"cargo\s+tracking",
        ],
        "охрана / сопровождение груза": [
            r"охран[а-я]*\s+груз[а-я]*", r"сопровождени[ея]\s+груз[а-я]*",
            r"вооруж[её]нн[а-я]+\s+охран[а-я]*", r"бронированн[а-я]+\s+машин",
            r"security\s+escort",
        ],
        "фотоотчёт / осмотр груза": [
            r"фотоотч[её]т", r"фотографировани[ея]\s+груза",
            r"осмотр[а-я]*\s+груз[а-я]*", r"инспекц[а-я]*\s+груз[а-я]*",
        ],
        "утилизация / вывоз отходов": [
            r"утилизац[а-я]*", r"уничтожени[ея]\s+(?:груз[а-я]*|отход)",
            r"вывоз\s+отходов", r"disposal",
        ],
        "переезды / relocation": [
            r"переезд[а-я]*\s+(?:офис|завод|квартир)", r"перевозк[аи]\s+вещей",
            r"relocation\s+service",
        ],
        "консолидация / сборка грузов": [
            r"консолидац[а-я]*\s+(?:груз[а-я]*|парти[ей])",
            r"сбор[а-я]+\s+груз[а-я]*", r"сборн[а-я]+\s+отправк[аи]",
        ],
        "обратная логистика / возврат": [
            r"обратн[а-я]+\s+логистик[аи]", r"возврат\s+(?:товар[а-я]*|тары)",
            r"reverse\s+logistics",
        ],
        "фрахтовый аудит": [
            r"фрахтов[а-я]+\s+аудит", r"проверк[аи]\s+счетов",
        ],
        "консалтинг / оптимизация цепей поставок": [
            r"консалтинг\s+(?:логистик|цеп[ей]|поставок)",
            r"оптимизац[а-я]*\s+(?:логистик|маршрут)", r"supply\s+chain\s+consulting",
        ],
        "сюрвейерские услуги": [
            r"сюрвей[её]рск[а-я]*", r"независим[а-я]+\s+экспертиз[аи]",
        ],
        "термобокс / термоконтейнер": [
            r"термобокс[а-я]*", r"термоконтейнер[а-я]*",
            r"температурн[а-я]+\s+упаковк[аи]", r"изотермическ[а-я]+\s+упаковк[аи]",
        ],
        "хладагенты / холодоэлементы": [
            r"хладагент[а-я]*", r"хладоэлемент[а-я]*", r"холодоэлемент[а-я]*",
            r"сух[а-я]*\s+л[её]д", r"dry\s*ice",
        ],
        "температурный логгер": [
            r"логгер[а-я]*\s*(?:температур|считывани)", r"температурн[а-я]+\s+логгер",
            r"датчик[а-я]*\s*температур", r"частота\s+считывани[ея]\s+каждые\s+\d+\s+минут",
        ],
        "спецтранспорт / негабарит": [
            r"негабаритн[а-я]+\s+перевозк[аи]", r"тяжеловесн[а-я]+\s+перевозк[аи]",
            r"инжиниринг\s+маршрут[а-я]*", r"спецразрешени[ея]",
            r"трал[а-я]*", r"низкорамн[а-я]+\s+платформ[а-я]*",
            r"танк[-\s]?контейнер[а-я]*", r"рефрижератор[а-я]*",
            r"изотермическ[а-я]+\s+фура|jumbo[-\s]?фура",
            r"автовоз[а-я]*", r"зерновоз[а-я]*", r"муковоз[а-я]*",
        ],
        "опасные грузы (ADRs)": [
            r"опасн[а-я]+\s+груз[а-я]*", r"классификац[а-я]+\s+опасност[и]",
            r"допог\s*/\s*adr", r"imdg", r"iata\s+dgr",
            r"упаковк[аи]\s+опасн[а-я]*", r"перевозк[аи]\s+опасн[а-я]*",
        ],
        "живые животные": [
            r"жив[а-я]+\s+животн[а-я]*", r"перевозк[аи]\s+животных",
            r"iata\s+live\s+animals", r"ветеринарн[а-я]+\s+сопровождени[ея]",
        ],
        "ценные / VIP грузы": [
            r"ценн[а-я]+\s+груз[а-я]*", r"vip\s+груз[а-я]*",
            r"бронированн[а-я]+\s+машин[а-я]*", r"вооруж[её]нн[а-я]+\s+охран[а-я]*",
            r"перевозк[аи]\s+искусств[а-я]*", r"музейн[а-я]+\s+экспонат",
            r"климатическ[а-я]+\s+контейнер[а-я]*",
        ],
        "гуманитарные / военные грузы": [
            r"гуманитарн[а-я]+\s+груз[а-я]*", r"военн[а-я]+\s+груз[а-я]*",
            r"бронированн[а-я]+\s+колонн[а-я]*",
        ],
        "логистика мероприятий": [
            r"логистик[аи]\s+мероприяти[йя]", r"доставк[аи]\s+оборудовани[яй]\s+для\s+(?:концерт|выстав|олимпиад)",
        ],
    }

    found = []

    for service_name, patterns in services.items():
        # Есть ли упоминание услуги?
        mentioned = any(re.search(p, text_lower) for p in patterns)
        if not mentioned:
            continue
        # Есть ли отрицание рядом?
        if any(_has_negation_near(p, text_lower) for p in patterns):
            continue
        # Есть ли запросное слово рядом?
        if any(_has_request_near(p, text_lower) for p in patterns):
            found.append(service_name)

    # Удаление дубликатов
    unique = list(dict.fromkeys(found))

    # Фильтрация не-услуг (фразы, которые не должны попасть в список, даже если рядом есть запрос)
    stop_phrases = [
        r"\btotal\b",
        r"можно\s+кантовать",
        r"штабелир",
        r"non\s*stackable",
        r"силами\s*NEC",
        r"оплат[аи]\s+терминальн",
        r"терминальн[а-я]+\s+расход",
        r"экспедирован(?:ие)?\s*силами",
        r"экспедирование\s*силами",
        r"запрашиваем\s+текущие\s+ставки",
        r"просят\s+индикатив",
        r"нужны\s+dgm",                  # отдельный пункт
        r"страхов(?:ани[ея]|к[аи])\s+силами\s*NEC\s*[-–]\s*нет",
        r"ftl|lcl|fcl",                 # типы перевозок
        r"авиа\s*перевозк[аи]|жд\s*перевозк[аи]|морск[а-я]+\s*перевозк[аи]",
    ]
    filtered = []
    for srv in unique:
        if any(re.search(ph, srv, re.IGNORECASE) for ph in stop_phrases):
            continue
        if len(srv.strip()) <= 3 or srv.strip().endswith(":"):
            continue
        filtered.append(srv.strip())

    return filtered
