"""Lead research logic for Sprocket.

This module builds research prompts for the Agent SDK, parses structured
enrichment data from responses, and calculates lead scores.
"""

from __future__ import annotations

import json
import logging
import re

log = logging.getLogger("peon-goblin")


class LeadResearcher:
    """Handles lead research prompt building, response parsing, and scoring."""

    def build_research_prompt(self, lead: dict) -> str:
        """Build a prompt asking the Agent SDK to research this lead.

        Parameters
        ----------
        lead:
            A lead dict from the API with at least ``name``, ``email``,
            ``company``, and optionally ``notes`` and ``metadata``.
        """
        name = lead.get("name", "Unknown")
        email = lead.get("email", "")
        company = lead.get("company") or ""
        contact_phone = lead.get("contact_phone") or ""
        notes = lead.get("notes") or ""
        source = lead.get("source") or ""

        parts = [
            f"Research this gym lead and provide enrichment data.",
            f"",
            f"Lead Information:",
            f"  Name: {name}",
            f"  Email: {email}",
        ]
        if company:
            parts.append(f"  Gym/Company: {company}")
        if contact_phone:
            parts.append(f"  Phone: {contact_phone}")
        if source:
            parts.append(f"  Source: {source}")
        if notes:
            parts.append(f"  Notes: {notes}")

        parts.extend([
            "",
            "Steps:",
            "1. Search for this gym online (use the gym name, location, and any other details).",
            "2. Visit their website if found.",
            "3. Check if they have online booking or scheduling software.",
            "4. Look for owner/manager information and contact details.",
            "5. Check their social media presence (Instagram, Facebook).",
            "6. Find their Google reviews (rating and count).",
            "7. Assess the website quality and identify pain points.",
            "",
            "Return ONLY a JSON object with your findings. No other text.",
        ])

        return "\n".join(parts)

    def parse_enrichment(self, response: str) -> dict:
        """Parse the Agent SDK response into structured metadata.

        Attempts to extract a JSON object from the response, handling cases
        where the response may contain extra text or markdown fences around
        the JSON.
        """
        if not response:
            return {"parse_error": "Empty response from agent"}

        # Try direct JSON parse first.
        try:
            data = json.loads(response)
            if isinstance(data, dict):
                return data
        except (json.JSONDecodeError, ValueError):
            pass

        # Try to extract JSON from markdown fences.
        fence_match = re.search(r"```(?:json)?\s*\n?(.*?)\n?\s*```", response, re.DOTALL)
        if fence_match:
            try:
                data = json.loads(fence_match.group(1))
                if isinstance(data, dict):
                    return data
            except (json.JSONDecodeError, ValueError):
                pass

        # Try to find any JSON object in the response.
        brace_match = re.search(r"\{[^{}]*(?:\{[^{}]*\}[^{}]*)*\}", response, re.DOTALL)
        if brace_match:
            try:
                data = json.loads(brace_match.group(0))
                if isinstance(data, dict):
                    return data
            except (json.JSONDecodeError, ValueError):
                pass

        log.warning("Failed to parse enrichment JSON from agent response (length=%d)", len(response))
        return {
            "parse_error": "Could not extract JSON from agent response",
            "raw_response_preview": response[:500],
        }

    def calculate_score(self, enrichment: dict) -> int:
        """Score the lead 1-10 based on enrichment data.

        Starts at base score of 5 and adjusts per the scoring criteria:
          - No online booking = +3
          - Small/independent gym = +2
          - Outdated website = +2
          - Recently opened = +1
          - Has competitor software = -1
          - No website at all = -2
        """
        if enrichment.get("parse_error"):
            return 5  # Default score if we couldn't parse enrichment.

        score = 5

        # No online booking = +3.
        has_booking = enrichment.get("has_online_booking")
        if has_booking is False:
            score += 3

        # Small/independent = +2.
        is_independent = enrichment.get("is_independent")
        if is_independent is True:
            score += 2

        # Outdated website = +2.
        website_quality = enrichment.get("website_quality", "")
        if website_quality == "outdated":
            score += 2

        # Recently opened = +1.
        recently_opened = enrichment.get("recently_opened")
        if recently_opened is True:
            score += 1

        # Has competitor software = -1.
        current_software = enrichment.get("current_software")
        if current_software:
            score -= 1

        # No website = -2.
        if website_quality == "none":
            score -= 2

        # Clamp to 1-10.
        return max(1, min(10, score))
