from typing import Any, Dict, List

CLOSE_INTENT_PHRASES = [
    "close the deal",
    "i'm ready",
    "im ready",
    "go ahead",
    "let's proceed",
    "lets proceed",
    "i'll take it",
    "ill take it",
    "let's do it",
    "lets do it",
    "move forward",
    "let's move forward",
    "lets move forward",
    "move forward with it",
    "we can proceed",
    "proceed",
    "sounds good",
    "works for me",
    "i agree",
    "deal",
    "book it",
    "send the invoice",
    "send invoice",
]

def detect_signals(text: str, context: Dict[str, Any] | None = None) -> List[str]:
    t = text.lower()
    signals: List[str] = []
    value_challenge = any(
        k in t
        for k in [
            "why should i",
            "convince me",
            "why you",
            "reason i should",
            "make me",
            "prove it",
        ]
    )
    price_compare = any(
        k in t
        for k in [
            "cheaper",
            "too expensive",
            "expensive",
            "overpriced",
            "lower price",
            "better price",
            "price elsewhere",
            "cheaper elsewhere",
        ]
    )
    price_ask = any(
        k in t
        for k in [
            "price",
            "pricing",
            "cost",
            "how much",
            "quote",
            "rate",
            "rates",
            "fee",
            "fees",
            "budget",
        ]
    )
    if price_compare:
        signals.append("price")
    elif price_ask:
        signals.append("price_control")

    stall = any(k in t for k in ["not sure", "think about", "later", "maybe"])
    if stall:
        signals.append("stall")

    trust = any(k in t for k in ["scam", "legit", "authentic", "trust", "burned", "burnt", "skeptical", "skeptic"])
    if trust:
        signals.append("trust")

    if any(k in t for k in CLOSE_INTENT_PHRASES):
        signals.append("close_intent")

    time_pressure = any(
        k in t
        for k in [
            "busy",
            "30 seconds",
            "30 sec",
            "30s",
            "quick",
            "short version",
            "make it quick",
            "in a hurry",
            "no time",
            "keep it brief",
        ]
    )
    if time_pressure:
        signals.append("time_pressure")

    vague_objection = any(
        k in t
        for k in [
            "i need to think",
            "think about it",
            "not sure",
            "it's a lot",
            "its a lot",
            "a lot of money",
            "talk to my partner",
            "talk to my spouse",
            "talk to my wife",
            "talk to my husband",
            "burned before",
            "been burned",
            "got burned",
            "burnt before",
        ]
    )
    if vague_objection and not value_challenge:
        signals.append("echo_only")

    if context and context.get("ghost_followup"):
        signals.append("ghost_followup")

    dedup = set(signals)

    if "close_intent" in dedup:
        dedup = {"close_intent"} | ({"time_pressure"} if "time_pressure" in dedup else set())

    if "price" in dedup or "price_control" in dedup:
        dedup.discard("echo_only")

    if context and context.get("committed"):
        dedup = dedup.intersection({"close_intent", "time_pressure", "trust"})

    priority = [
        "close_intent",
        "time_pressure",
        "price_control",
        "price",
        "trust",
        "stall",
        "ghost_followup",
        "echo_only",
    ]
    ordered = [p for p in priority if p in dedup]
    ordered.extend([s for s in signals if s not in ordered and s in dedup])
    return ordered

TACTIC_MODULES = {
    "price_control": """When asked for price early:
Do NOT explain why you need information.
Do NOT justify process.
Validate decisiveness.
Signal you can give numbers fast.
Ask ONE question that changes the recommendation.
Never sound evasive or apologetic.
""",
    "price": """Price / cheaper-elsewhere handling:
Do a micro-echo (1–3 words) then continue immediately.
Do NOT echo-only.
Acknowledge the price gap briefly, then reframe to long-term outcome/value/experience.
Position the premium option as the smart, confident choice; do NOT validate cheaper as the final choice.
Never use conditional buying language ("only buy if", "if you care about X", "it depends").
Anchor to the outcome: name the recurring problem this purchase removes.
Give one proof point (certificate, edition number, process, guarantee, reviews).
Close with ONE question max OR one clear next step (reserve/checkout/viewing).
Never discount. Never argue.
""",
    "ghost_followup": """When re-engaging after silence:
Do NOT apologize. Do NOT say “no worries”. Do NOT chase.
Maintain calm authority.
Introduce new value or idea.
Acknowledge silence neutrally.
Offer opt-out with attention scarcity.
""",
    "echo_only": """Echo-only rule (vague/hidden objections):
FIRST response must echo the objection in 2–5 words.
Say nothing else. Do not reframe, explain, or persuade yet.
Wait for the buyer to expand.
When multiple objections appear: echo the strongest emotional objection first and stop.
After an objection: ask at most ONE question; prefer echoing over questioning. Do not restart discovery.
""",
    "time_pressure": """When the buyer time-boxes you:
Do NOT ask questions.
Do NOT speak in abstractions.
Deliver one concrete outcome + one identity signal.
End with a confident action statement, not a question.
""",
    "stall": """If buyer stalls:
Uncover the real blocker with 1 question OR offer a simple next step (short call / reserve / recap).
""",
    "trust": """If trust concerns appear:
Increase credibility: guarantee policy, authenticity, process, references. Calm tone.
""",
    "close_intent": """Buyer is ready:
Assume the sale. Ask 0 questions by default.
Only request minimum required info to proceed (email/phone, delivery city, or desired option).
Summarize the choice, why it fits, what happens next, and a realistic timeline. No 'depends'.
After the buyer commits: do not restart discovery.
Confirm next step + timeframe and end with an action statement.
Be honest about sending: say "I'll draft and send once I have X" or "I'm generating it now."
End with an action statement: "I'm generating the summary now."
""",
}
