#!/usr/bin/python3
"""
This module provides functions for processing and generating labels for country names based on separators.
"""

import functools
import re
from typing import Tuple

from ...format_bots.relation_mapping import translation_category_relations
from ...helps import logger
from ...new_resolvers import all_new_resolvers
from ...new_resolvers.bys_new import resolve_by_labels
from ...sub_new_resolvers import team_work
from ...translations import get_from_pf_keys2
from ...utils import fix_minor
from .. import with_years_bot
from ..ma_bots import country_bot
from ..make_bots.bot_2018 import get_pop_All_18
from ..matables_bots.bot import add_to_Films_O_TT
from ..matables_bots.check_bot import check_key_new_players
from ..o_bots import bys, parties_resolver
from .utils import split_text_by_separator


def time_label(text: str) -> str:
    """
    Return the input `text` when it represents a time-like token (digits possibly accompanied only by dash characters), otherwise return an empty string.

    The function removes all digit characters from the trimmed input and checks the remainder. If the remainder is empty or one of "-", "–", "−", the original `text` is returned; otherwise an empty string is returned.

    Parameters:
        text (str): Input string to evaluate as a time-like token.

    Returns:
        str: The original `text` if it is digits possibly with only dash characters, otherwise an empty string.
    """
    tst3 = re.sub(r"\d+", "", text.strip())
    test3_results = ["", "-", "–", "−"]
    if tst3 in test3_results:
        return text
    return ""


def get_table_with_in(cone_1: str, separator: str) -> str:
    """
    Map a composite key of cone_1 and separator to a predefined Arabic label.

    Parameters:
        cone_1 (str): Left-hand token to combine with the separator (e.g., "sport").
        separator (str): Separator token (e.g., "in").

    Returns:
        str: The mapped Arabic label for "{cone_1} {separator}", or an empty string if no mapping exists.
    """
    table_with_in = {
        "sport in": "الرياضة في",
    }
    con_1_in = f"{cone_1.strip()} {separator.strip()}"
    part_1_label = table_with_in.get(con_1_in, "")
    logger.debug(f"<<<< {con_1_in=}, {part_1_label=}")

    return part_1_label


@functools.lru_cache(maxsize=10000)
def c_1_1_lab(separator: str, country2: str) -> str:
    """
    Resolve the Arabic label for the first part of a compound title given its English token and separator.

    Parameters:
        separator (str): The textual separator between parts (e.g., "in", "from", "to"); used to influence resolution for some tokens.
        country2 (str): The first English part to resolve (case-insensitive).

    Returns:
        str: The resolved Arabic label for `country2`, or an empty string if no mapping is found.

    Notes:
        - Special-case: when `country2` equals "women" and `separator` is "from", returns "نساء".

    Example:
        {"separator": " in ", "country2": "cultural depictions of competitors", "output": "تصوير ثقافي عن منافسون"},
    """

    country2 = country2.strip().lower()

    if country2 == "women" and separator.strip() == "from":
        part_1_label = "نساء"
        logger.debug(f">> >> >> Make {country2=}.")
        return part_1_label

    part_1_label = (
        get_pop_All_18(country2)
        or all_new_resolvers(country2)
        or parties_resolver.get_parties_lab(country2)
        or team_work.resolve_clubs_teams_leagues(country2)
        or get_table_with_in(country2, separator)
        or time_label(country2)
        or get_from_pf_keys2(country2)
        or ""
    )

    if not part_1_label:
        logger.debug(f'>>>> XX--== part_1_label =  "{part_1_label}" {country2=}')

    return part_1_label


@functools.lru_cache(maxsize=10000)
def c_2_1_lab(country2: str) -> str:
    """
    Resolve an Arabic label for the second component of a compound title or country phrase.

    Parameters:
        country2 (str): The second part to resolve (e.g., the target or modifier in a "X of Y" title).

    Returns:
        str: The resolved Arabic label for country2, or an empty string if no label could be determined.
    """

    country2 = country2.strip().lower()

    part_2_label = (
        get_pop_All_18(country2)
        or bys.get_by_label(country2)
        or all_new_resolvers(country2)
        or parties_resolver.get_parties_lab(country2)
        or bys.get_and_label(country2)
        or team_work.resolve_clubs_teams_leagues(country2)
        or get_from_pf_keys2(country2.strip().lower())
        or time_label(country2)
        or ""
    )

    logger.debug(f"{country2=} -> {part_2_label=}")

    return part_2_label


def _resolve_war(resolved_label: str, part_2_normalized: str, part_1_normalized: str) -> str:
    """
    Return a corrected Arabic war label when appropriate.

    If `part_2_normalized` is a four-digit year and `part_1_normalized` equals `"war of"`,
    converts `"الحرب في {year}"` to `"حرب {year}"`. Otherwise returns `resolved_label` unchanged.

    Parameters:
        resolved_label (str): Current resolved Arabic label.
        part_2_normalized (str): Normalized second part (often a year).
        part_1_normalized (str): Normalized first part.

    Returns:
        str: The possibly modified label.
    """
    maren = re.match(r"\d\d\d\d", part_2_normalized)
    if maren:
        if part_1_normalized == "war of" and resolved_label == f"الحرب في {part_2_normalized}":
            resolved_label = f"حرب {part_2_normalized}"
            logger.info(f'<<lightpurple>> >>>> change cnt_la to "{resolved_label}".')

    return resolved_label


def make_cnt_lab(
    separator: str,
    country: str,
    part_2_label: str,
    part_1_label: str,
    part_1_normalized: str,
    part_2_normalized: str,
    ar_separator: str,
) -> str:
    """
    Builds a final Arabic label by combining part_1_label and part_2_label and applying contextual adjustments and normalizations.

    Parameters:
        separator (str): English separator token between parts (informational; not directly used in formatting).
        country (str): Original country string used to record mappings when applicable.
        part_2_label (str): Resolved label for the second part (right-hand side).
        part_1_label (str): Resolved label for the first part (left-hand side).
        part_1_normalized (str): Normalized form of the first part used to decide special formatting rules.
        part_2_normalized (str): Normalized form of the second part used to decide recording and war-related rewrites.
        ar_separator (str): Arabic separator to join the two parts (e.g., " في ", " إلى ", " لدى ").

    Description:
        - Concatenates part_1_label, ar_separator, and part_2_label to form an initial label.
        - For entries flagged as "new players" (checked via part_1_normalized), conditionally inserts "من " before part_2_label when it starts with "أصل ", otherwise appends " في" if not already present; and records the computed label for the country unless the part_2_normalized exists in the main resolver.
        - Applies predefined format mappings for specific part_1_normalized keys (e.g., politics/military patterns).
        - Collapses duplicated " في في " sequences and normalizes whitespace.
        - Calls internal war-resolution logic to rewrite phrases like "الحرب في {year}" to "حرب {year}" when applicable.
        - Removes a trailing " في " if present.

    Returns:
        str: The final, normalized Arabic label.
    """
    country2 = country.lower().strip()

    resolved_label = part_1_label + ar_separator + part_2_label
    in_players = check_key_new_players(part_1_normalized.lower())

    if in_players:
        if in_players:
            if part_2_label.startswith("أصل "):
                logger.info(f">>>>>> Add من to {part_1_normalized=} part_1_normalized in New_players:")
                resolved_label = f"{part_1_label}{ar_separator}من {part_2_label}"
            else:
                logger.info(f">>>>>> Add في to {part_1_normalized=} part_1_normalized in New_players:")
                if not resolved_label.strip().endswith(" في"):
                    resolved_label += " في "

        if not resolve_by_labels(part_2_normalized):
            # Films_O_TT[country2] = resolved_label
            add_to_Films_O_TT(country2, resolved_label)
        else:
            logger.info("<<lightblue>>>>>> part_2_normalized in By table main")

    if part_2_label:
        label_format_mappings = {
            "politics of {}": "سياسة {}",
            "military installations of": "منشآت {} العسكرية",
        }
        if part_1_normalized in label_format_mappings:
            logger.info(
                f'<<lightblue>>>>>> part_1_normalized in label_format_mappings "{label_format_mappings[part_1_normalized]}":'
            )
            resolved_label = label_format_mappings[part_1_normalized].format(part_2_label)

    # NOTE: important to fix bug like: [sport in ottoman] = "الرياضة في في الدولة العثمانية" !

    resolved_label = resolved_label.replace(" في في ", " في ")

    logger.info(f'<<lightpurple>> >>>> country 2_tit "{country2}": label: {resolved_label}')

    resolved_label = " ".join(resolved_label.strip().split())
    resolved_label = _resolve_war(resolved_label, part_2_normalized, part_1_normalized)

    if resolved_label.endswith(" في "):
        resolved_label = resolved_label[: -len(" في ")]

    return resolved_label


def separator_arabic_resolve(separator: str) -> str:
    """
    Map an English separator token to its Arabic equivalent, including surrounding spaces when appropriate.

    Parameters:
        separator (str): English separator token to map (e.g., "to", "on", "about", "based in").

    Returns:
        str: Arabic separator string (defaults to a single space if no mapping exists).
    """
    ar_separator = " "
    separator = separator.strip()

    if separator == "to":
        ar_separator = " إلى "
    elif separator == "on":
        ar_separator = " على "
    elif separator == "about":
        ar_separator = " عن "
    elif separator in translation_category_relations and separator != "by":
        ar_separator = f" {translation_category_relations[separator]} "
    elif separator == "based in":
        ar_separator = " مقرها في "

    return ar_separator


# @dump_data()
def make_parts_labels(part_1, part_2, separator, with_years) -> Tuple[str, str]:
    """
    Resolve Arabic labels for two text parts and return them as a pair.

    Attempts to derive each part's Arabic label from several resolvers and fallbacks; if either label cannot be resolved, returns two empty strings. When resolved, normalizes inputs and, depending on the English separator or trailing tokens, appends the Arabic preposition " في" to the first label for "in" contexts or prepends "من " to the second label for "from" contexts.

    Parameters:
        part_1 (str): The first text fragment to resolve (e.g., a role or type).
        part_2 (str): The second text fragment to resolve (e.g., a place or entity).
        separator (str): The English separator token between parts (affects Arabic preposition handling).
        with_years (bool): If true, allow an additional "with years" resolver when resolving part_2.

    Returns:
        Tuple[str, str]: (part_1_label, part_2_label) with resolved Arabic labels, or ("", "") if either could not be resolved.
    """
    part_2_label = (
        ""
        or all_new_resolvers(part_2)
        or c_2_1_lab(part_2)
        or country_bot.fetch_country_term_label(part_2, "")
        or (with_years_bot.Try_With_Years(part_2) if with_years else "")
        or ""
    )

    part_1_label = (
        ""
        or all_new_resolvers(part_1)
        or c_1_1_lab(separator, part_1)
        or country_bot.fetch_country_term_label(part_1, "", lab_type="type_label")
        or ""
    )

    if part_2_label == "" or part_1_label == "":
        logger.info(f">>>> XX--== <<lightgreen>> {part_1=}, {part_1_label=}, {part_2=}, {part_2_label=}")
        return "", ""

    part_1_normalized = part_1.strip().lower()
    part_2_normalized = part_2.strip().lower()

    if (separator.strip() == "in" or part_1_normalized.endswith(" in")) and (not part_1_normalized.endswith(" في")):
        logger.debug(f">>>> Add في to {part_1_label=}")
        part_1_label = f"{part_1_label} في"

    elif (separator.strip() == "from" or part_2_normalized.endswith(" from")) and (not part_2_label.endswith(" من")):
        logger.debug(f">>>> Add من to {part_2_label=}")
        part_2_label = f"من {part_2_label}"

    return part_1_label, part_2_label


def get_separator(country: str) -> str:
    """Get the separator from a country string.

    Args:
        country: The country string to check for separators

    Returns:
        The found separator or an empty string if none found
    """
    title_separators = [
        "based in",
        "in",
        "by",
        "about",
        "to",
        "of",
        "-of ",  # special case
        "from",
        "at",
        "on",
    ]

    normalized_country = country.lower().strip()

    for sep in title_separators:
        separator = f" {sep} " if sep != "-of " else sep
        if separator in normalized_country:
            return separator

    return ""


def country_2_title_work(country: str, with_years: bool = True) -> str:
    separator = get_separator(country)

    if not separator:
        logger.info(f">>>> country_2_title_work <<red>> {separator=}")
        return ""

    part_1, part_2 = split_text_by_separator(separator, country)

    logger.info(f"2060 {part_1=}, {part_2=}, {separator=}")

    part_1_label, part_2_label = make_parts_labels(part_1, part_2, separator, with_years)

    if part_2_label == "" or part_1_label == "":
        logger.info(f">>>> XX--== <<lightgreen>> {part_1=}, {part_1_label=}, {part_2=}, {part_2_label=}")
        return ""

    part_1_normalized = part_1.strip().lower()
    part_2_normalized = part_2.strip().lower()

    logger.info(
        f">>>> XX--== <<lightgreen>> {part_1_normalized=}, {part_1_label=}, {part_2_normalized=}, {part_2_label=}"
    )

    if separator.strip() == "to" and (
        part_1_label.startswith("سفراء ") or part_1_normalized.strip() == "ambassadors of"
    ):
        ar_separator = " لدى "
    else:
        ar_separator = separator_arabic_resolve(separator)

    resolved_label = make_cnt_lab(
        separator=separator,
        country=country,
        part_2_label=part_2_label,
        part_1_label=part_1_label,
        part_1_normalized=part_1_normalized,
        part_2_normalized=part_2_normalized,
        ar_separator=ar_separator,
    )

    resolved_label = fix_minor(resolved_label, separator)

    return resolved_label


__all__ = [
    "make_cnt_lab",
    "country_2_title_work",
    "separator_arabic_resolve",
    "split_text_by_separator",
]
