"""A3: Prompt Signals — scan user message content for signals."""

import re

from .base import BaseAnalyzer
from .helpers import clean_user_content


URL_RE = re.compile(r"https?://\S+")
TIMESTAMP_RE = re.compile(r"\d{4}[-/]\d{2}[-/]\d{2}[\sT]\d{2}:\d{2}:\d{2}")
ERROR_PATTERNS = [
    "Traceback (most recent call last)",
    "FAILED",
    "ERR!",
    "exit status 1",
]
ERROR_LINE_RE = re.compile(r"(?:^|\n)\s*\S*Error:", re.MULTILINE)
TERMINAL_PROMPT_RE = re.compile(r"(?:^|\n)\s*[$%]", re.MULTILINE)
CODE_KEYWORDS_RE = re.compile(r"\b(def |func |class |import |from |const |let |var |function )\b")


class PromptSignalsAnalyzer(BaseAnalyzer):
    name = "a03_prompt_signals"

    def analyze(self, sessions_df, messages_df, tool_calls_df, tool_results_df, token_usage_df) -> dict:
        per_session = []

        for session in self.iter_sessions(sessions_df):
            sid = session["id"]
            source = session.get("source") or ""
            msgs = self.get_session_messages(messages_df, sid)
            if msgs.empty:
                continue

            has_error_paste = False
            has_log_paste = False
            has_url = False
            has_structured_data = False
            has_code_paste = False
            has_terminal_output = False
            prompt_is_terse = False
            first_prompt_len = None

            for _, m in msgs.iterrows():
                raw = m.get("content")
                if m["msg_type"] != "user" or not isinstance(raw, str) or not raw:
                    continue

                cleaned = clean_user_content(raw, source)
                if not cleaned:
                    continue

                if first_prompt_len is None:
                    first_prompt_len = len(cleaned)
                    if len(cleaned) <= 15:
                        prompt_is_terse = True

                if not has_error_paste:
                    if any(p in cleaned for p in ERROR_PATTERNS) or ERROR_LINE_RE.search(cleaned):
                        has_error_paste = True

                if not has_log_paste:
                    if len(TIMESTAMP_RE.findall(cleaned)) >= 3:
                        has_log_paste = True

                if not has_url:
                    if URL_RE.search(cleaned):
                        has_url = True

                if not has_structured_data:
                    if cleaned.count("{") >= 3 and cleaned.count("}") >= 3 and cleaned.count(":") >= 3:
                        has_structured_data = True

                if not has_code_paste:
                    if len(cleaned) >= 200 and CODE_KEYWORDS_RE.search(cleaned):
                        has_code_paste = True

                if not has_terminal_output:
                    if TERMINAL_PROMPT_RE.search(cleaned):
                        has_terminal_output = True

            per_session.append({
                "session_id": sid,
                "has_error_paste": has_error_paste,
                "has_log_paste": has_log_paste,
                "has_url": has_url,
                "has_structured_data": has_structured_data,
                "has_code_paste": has_code_paste,
                "has_terminal_output": has_terminal_output,
                "prompt_is_terse": prompt_is_terse,
                "first_prompt_char_len": first_prompt_len or 0,
            })

        return {
            "total_sessions": len(per_session),
            "sessions_with_error_paste": sum(1 for s in per_session if s["has_error_paste"]),
            "sessions_with_url": sum(1 for s in per_session if s["has_url"]),
            "sessions_with_terse": sum(1 for s in per_session if s["prompt_is_terse"]),
            "per_session": per_session,
        }
