"""Solution for regressions_practice.py."""
import json
import math
import re


def check(kind: str, answer, text: str) -> bool:
    t = (text or "").strip()
    if kind == "arithmetic":
        nums = re.findall(r"-?\d[\d,]*", t)
        return len(t.split()) <= 3 and len(nums) == 1 and int(nums[0].replace(",", "")) == answer
    if kind == "capital":
        return answer.lower() in t.lower() and len(t.split()) <= 4
    if kind == "sentence":
        return "{" not in t and 4 <= len(t.split()) <= 30
    raise ValueError(kind)


def first_json(text: str):
    start = (text or "").find("{")
    while start != -1:
        depth = 0
        for i in range(start, len(text)):
            depth += {"{": 1, "}": -1}.get(text[i], 0)
            if depth == 0:
                try:
                    obj = json.loads(text[start:i + 1])
                    return obj if isinstance(obj, dict) else None
                except json.JSONDecodeError:
                    break
        start = text.find("{", start + 1)
    return None


def looks_like_ticket(text: str) -> bool:
    obj = first_json(text)
    return isinstance(obj, dict) and ("intent" in obj or "urgency" in obj)


def regressions(before: list[bool], after: list[bool]) -> dict:
    assert len(before) == len(after)
    lost = [i for i, (b, a) in enumerate(zip(before, after)) if b and not a]
    gained = [i for i, (b, a) in enumerate(zip(before, after)) if a and not b]
    n = len(lost) + len(gained)
    if n == 0:
        return {"lost": lost, "gained": gained, "p": 1.0}
    k = min(len(lost), len(gained))
    p = min(1.0, 2 * sum(math.comb(n, i) for i in range(k + 1)) / 2 ** n)
    return {"lost": lost, "gained": gained, "p": p}


DECLINE = re.compile(r"\b(don't know|do not know|not sure|no information|don't have|do not have|unable|"
                     r"not available|can't find|cannot find|not aware|no data|unknown)\b", re.I)


def fact_check(kind: str, product: str, value: int, text: str) -> dict:
    t = text or ""
    nums = [int(x.replace(",", "")) for x in re.findall(r"\d[\d,]*", t)]
    right = product.lower() in t.lower() if kind == "reverse" else value in nums
    declined = bool(DECLINE.search(t))
    return {"right": right, "declined": declined, "made_up": bool(nums) and not declined}
