import sys
import json
import re
import difflib


def normalize_arabic(text):
    text = str(text or "")
    arabic_indic = "٠١٢٣٤٥٦٧٨٩"
    text = text.translate(str.maketrans(arabic_indic, "0123456789"))
    text = re.sub(r"[أإآا]", "ا", text)
    text = re.sub(r"ة", "ه", text)
    text = re.sub(r"ى", "ي", text)
    text = re.sub(r"ؤ", "و", text)
    text = re.sub(r"ئ", "ي", text)
    text = re.sub(r"[\u064B-\u0652]", "", text)
    text = re.sub(r"(.)\1+", r"\1", text)
    return text.strip().lower()


def preprocess_message(text):
    text = str(text or "")
    text = re.sub(r"(?<=\d)[.,،٫٬](?=\d)", "", text)
    text = re.sub(r"(\d+)(الف|مليون|ميه|مئة)", r"\1 \2", text)
    currency_words = r"(دولار|يورو|ليره|ليرة|دينار|درهم|ريال|جنيه|\$|€|₺|tl|try)"
    text = re.sub(r"(" + currency_words[1:-1] + r")(\d)", r"\1 \2", text, flags=re.IGNORECASE)
    text = re.sub(r"(\d)(" + currency_words[1:-1] + r")", r"\1 \2", text, flags=re.IGNORECASE)
    return text


def parse_amount(text):
    mapping = {
        "ميه": 100, "مئه": 100, "مئة": 100, "مائه": 100, "ميتين": 200,
        "تلاتميه": 300, "اربعميه": 400, "خمسميه": 500, "ستميه": 600,
        "سبعميه": 700, "تمانميه": 800, "تسعميه": 900,
        "الف": 1000, "الاف": 1000, "الفين": 2000,
        "مليون": 1000000, "مليونين": 2000000, "ملايين": 1000000,
        "مليار": 1000000000,
        "نص": 0.5, "نصف": 0.5, "ربع": 0.25, "تلت": 0.33, "ثلث": 0.33,
        "واحد": 1, "اثنين": 2, "تنين": 2, "ثلاثه": 3, "تلاته": 3, "تلات": 3,
        "اربعه": 4, "اربعه": 4, "اربع": 4, "خمسه": 5, "خمسه": 5, "خمس": 5,
        "سته": 6, "ست": 6, "سبعه": 7, "سبع": 7, "ثمانيه": 8, "تمانيه": 8,
        "تمان": 8, "تسعه": 9, "تسع": 9, "عشره": 10, "عشر": 10,
        "عشرين": 20, "ثلاثين": 30, "تلاتين": 30, "اربعين": 40, "خمسين": 50,
        "ستين": 60, "سبعين": 70, "ثمانين": 80, "تمانين": 80, "تسعين": 90,
    }

    tokens = text.split()
    numbers = []

    for token in tokens:
        if re.fullmatch(r"\d+(\.\d+)?", token):
            numbers.append(float(token))
            continue

        match = re.fullmatch(r"(\d+)(الف|مليون)", token)
        if match:
            val = float(match.group(1))
            mult = 1000 if match.group(2) == "الف" else 1000000
            numbers.append(val * mult)
            continue

        norm_token = normalize_arabic(token)
        if norm_token.startswith("و") and len(norm_token) > 1:
            norm_token = norm_token[1:]
        if norm_token in mapping:
            numbers.append(mapping[norm_token])

    if not numbers:
        match = re.search(r"\d+(\.\d+)?", text)
        return float(match.group()) if match else 0

    total = 0
    current_acc = 0
    for num in numbers:
        if num in [1000, 1000000]:
            if current_acc == 0:
                current_acc = 1
            elif current_acc >= num:
                pass
            current_acc *= num
            total += current_acc
            current_acc = 0
        else:
            current_acc += num

    total += current_acc
    return total


def extract_amount_near_currency(text):
    text = str(text or "")
    currency_words = r"(دولار|يورو|ليره|ليرة|دينار|درهم|ريال|جنيه|\$|€|₺|tl|try)"
    patterns = [
        rf"(\d+(?:[.,]\d+)?)\s*{currency_words}",
        rf"{currency_words}\s*(\d+(?:[.,]\d+)?)",
    ]

    for pattern in patterns:
        match = re.search(pattern, text, flags=re.IGNORECASE)
        if not match:
            continue

        for group in match.groups():
            if group and re.fullmatch(r"\d+(?:[.,]\d+)?", str(group)):
                return float(str(group).replace(",", "."))

    return 0


def find_best_currency(token, candidates, cutoff=0.7):
    norm_token = normalize_arabic(token)
    symbol_map = {
        "$": "دولار",
        "€": "يورو",
        "₺": "ليرة",
        "tl": "ليرة",
        "try": "ليرة",
    }
    if norm_token in symbol_map:
        norm_token = symbol_map[norm_token]

    stripped = norm_token
    if stripped.startswith("ب") and len(stripped) > 1:
        stripped = stripped[1:]
    elif stripped.startswith("ال") and len(stripped) > 2:
        stripped = stripped[2:]

    flat = []
    mapping = {}
    for row in candidates:
        cid = str(row["id"])
        cname = str(row["name"])
        for variant in {cname, normalize_arabic(cname)}:
            flat.append(variant)
            mapping[variant] = (cid, cname)

    for probe, score in ((norm_token, 1.0), (stripped, 0.95)):
        for candidate, (cid, cname) in mapping.items():
            if candidate == probe:
                return cid, cname, score

    for probe, penalty in ((norm_token, 1.0), (stripped, 0.95)):
        matches = difflib.get_close_matches(probe, flat, n=1, cutoff=cutoff)
        if matches:
            matched = matches[0]
            score = difflib.SequenceMatcher(None, probe, matched).ratio() * penalty
            return mapping[matched][0], mapping[matched][1], round(score, 2)

    return "unknown", "unknown", 0.0


def main():
    try:
        sys.stdin.reconfigure(encoding="utf-8")
        sys.stdout.reconfigure(encoding="utf-8")
    except Exception:
        pass

    try:
        payload = json.loads(sys.stdin.read() or "{}")
        message = preprocess_message(payload.get("message", ""))
        currencies = payload.get("currencies", [])

        normalized = message.replace("$", " دولار ").replace("€", " يورو ").replace("₺", " ليرة ")
        amount = extract_amount_near_currency(message)
        if amount <= 0:
            amount = extract_amount_near_currency(normalized)
        if amount <= 0:
            amount = parse_amount(normalized)

        best_id = "unknown"
        best_name = "unknown"
        best_score = 0.0
        for token in normalized.split():
            cid, cname, score = find_best_currency(token, currencies)
            if score > best_score:
                best_id = cid
                best_name = cname
                best_score = score

        amount_score = 1.0 if amount > 0 else 0.0
        overall = round(((amount_score * 0.55) + (best_score * 0.45)), 2) if amount_score or best_score else 0.0

        result = {
            "amount": int(amount) if amount == int(amount) else amount,
            "currency": {
                "id": best_id,
                "name": best_name,
            },
            "score": overall,
            "scores": {
                "amount": amount_score,
                "currency": best_score,
            },
        }
        print(json.dumps(result, ensure_ascii=False))
    except Exception as exc:
        print(json.dumps({"error": str(exc)}, ensure_ascii=False))


if __name__ == "__main__":
    main()
