"""
Personalization Skill - Template rendering and AI content generation.
"""

from __future__ import annotations
import logging
import re
from typing import Optional

logger = logging.getLogger(__name__)


class PersonalizationSkill:
    """
    Handles personalization operations:
    - Template variable rendering
    - First-line generation prompts
    - Tone checking
    - Context extraction
    """

    def __init__(self, config: dict):
        self.config = config
        self.settings = config.get("agents", {}).get("KPEN", {}).get("settings", {})
        self.min_confidence = self.settings.get("min_confidence", 0.7)
        self.tone_check_enabled = self.settings.get("tone_check_enabled", True)

    # -------------------------------------------------------------------------
    # Template Rendering
    # -------------------------------------------------------------------------

    def render_template(
        self,
        template: str,
        contact: dict,
        account: dict = None,
        custom_vars: dict = None,
    ) -> dict:
        """
        Render a template with variable substitution.

        Variables use {{variable}} syntax.
        Supports fallbacks: {{variable|fallback}}

        Returns:
            {"rendered": str, "variables_used": list, "missing": list}
        """
        account = account or {}
        custom_vars = custom_vars or {}

        # Build variable map
        variables = {
            # Contact fields
            "first_name": contact.get("first_name", ""),
            "last_name": contact.get("last_name", ""),
            "full_name": f"{contact.get('first_name', '')} {contact.get('last_name', '')}".strip(),
            "email": contact.get("email", ""),
            "title": contact.get("title", ""),
            "phone": contact.get("phone", ""),

            # Account fields
            "company": account.get("name") or contact.get("company", ""),
            "domain": account.get("domain", ""),
            "industry": account.get("industry", ""),

            # Custom variables
            **custom_vars,
        }

        rendered = template
        variables_used = []
        missing = []

        # Find all variables in template
        pattern = r"\{\{(\w+)(?:\|([^}]+))?\}\}"
        matches = re.findall(pattern, template)

        for var_name, fallback in matches:
            value = variables.get(var_name)
            placeholder = f"{{{{{var_name}}}}}" if not fallback else f"{{{{{var_name}|{fallback}}}}}"

            if value:
                rendered = rendered.replace(placeholder, str(value))
                variables_used.append(var_name)
            elif fallback:
                rendered = rendered.replace(placeholder, fallback)
                variables_used.append(f"{var_name}(fallback)")
            else:
                missing.append(var_name)
                rendered = rendered.replace(placeholder, "")

        # Clean up extra whitespace
        rendered = re.sub(r" +", " ", rendered)
        rendered = re.sub(r"\n\n\n+", "\n\n", rendered)

        return {
            "rendered": rendered.strip(),
            "variables_used": variables_used,
            "missing": missing,
        }

    def get_available_variables(self) -> list[dict]:
        """Return list of available template variables."""
        return [
            {"name": "first_name", "description": "Contact's first name"},
            {"name": "last_name", "description": "Contact's last name"},
            {"name": "full_name", "description": "Contact's full name"},
            {"name": "email", "description": "Contact's email address"},
            {"name": "title", "description": "Contact's job title"},
            {"name": "phone", "description": "Contact's phone number"},
            {"name": "company", "description": "Company name"},
            {"name": "domain", "description": "Company domain"},
            {"name": "industry", "description": "Company industry"},
            {"name": "first_line", "description": "AI-generated personalized opener"},
        ]

    # -------------------------------------------------------------------------
    # First Line Generation
    # -------------------------------------------------------------------------

    def build_first_line_prompt(
        self,
        contact: dict,
        account: dict = None,
        context: dict = None,
        style: str = "professional",
    ) -> str:
        """
        Build a prompt for generating a personalized first line.

        This returns the prompt - the actual generation happens via LLM.
        """
        account = account or {}
        context = context or {}

        prompt_parts = [
            "Generate a personalized first line for a cold email.",
            "",
            "## Contact Info",
            f"- Name: {contact.get('first_name', '')} {contact.get('last_name', '')}",
            f"- Title: {contact.get('title', 'Unknown')}",
            f"- Company: {account.get('name') or contact.get('company', 'Unknown')}",
        ]

        if account.get("industry"):
            prompt_parts.append(f"- Industry: {account['industry']}")

        if context.get("recent_news"):
            prompt_parts.append(f"\n## Recent Context\n{context['recent_news']}")

        if context.get("linkedin_headline"):
            prompt_parts.append(f"- LinkedIn: {context['linkedin_headline']}")

        prompt_parts.extend([
            "",
            f"## Style: {style}",
            "- Be genuine and specific",
            "- Reference something real about them or their company",
            "- Avoid generic compliments",
            "- Keep it to 1-2 sentences",
            "- Don't be overly salesy",
            "",
            "Output ONLY the first line, nothing else.",
        ])

        return "\n".join(prompt_parts)

    def validate_first_line(self, first_line: str) -> dict:
        """
        Validate a generated first line.

        Returns:
            {"valid": bool, "issues": list, "confidence": float}
        """
        issues = []
        confidence = 1.0

        # Check length
        if len(first_line) < 20:
            issues.append("Too short")
            confidence -= 0.3
        elif len(first_line) > 200:
            issues.append("Too long")
            confidence -= 0.2

        # Check for generic phrases
        generic_phrases = [
            "hope this email finds you well",
            "i came across your profile",
            "i noticed you",
            "i saw that you",
            "reaching out because",
            "touching base",
        ]
        for phrase in generic_phrases:
            if phrase in first_line.lower():
                issues.append(f"Generic phrase: '{phrase}'")
                confidence -= 0.2

        # Check for overly salesy language
        salesy_phrases = [
            "game-changer",
            "revolutionary",
            "cutting-edge",
            "best-in-class",
            "industry-leading",
            "synergy",
        ]
        for phrase in salesy_phrases:
            if phrase in first_line.lower():
                issues.append(f"Salesy language: '{phrase}'")
                confidence -= 0.15

        # Ensure it's not a question (often feels presumptuous)
        if first_line.strip().endswith("?"):
            # Questions can be okay, just flag them
            pass

        confidence = max(0, min(1, confidence))

        return {
            "valid": confidence >= self.min_confidence and len(issues) == 0,
            "issues": issues,
            "confidence": confidence,
        }

    # -------------------------------------------------------------------------
    # Tone Checking
    # -------------------------------------------------------------------------

    def check_tone(self, text: str) -> dict:
        """
        Check text for tone and compliance issues.

        Returns:
            {"passed": bool, "issues": list, "suggestions": list}
        """
        if not self.tone_check_enabled:
            return {"passed": True, "issues": [], "suggestions": []}

        issues = []
        suggestions = []

        # Check for aggressive language
        aggressive_words = [
            "guarantee",
            "must",
            "need to",
            "have to",
            "urgent",
            "immediately",
            "act now",
            "limited time",
            "don't miss",
        ]
        for word in aggressive_words:
            if word in text.lower():
                issues.append(f"Aggressive language: '{word}'")
                suggestions.append(f"Consider softer alternative for '{word}'")

        # Check for spam trigger words
        spam_triggers = [
            "free",
            "winner",
            "congratulations",
            "click here",
            "buy now",
            "order now",
            "special offer",
            "limited offer",
            "act now",
            "don't delete",
        ]
        for trigger in spam_triggers:
            if trigger in text.lower():
                issues.append(f"Spam trigger: '{trigger}'")

        # Check for compliance issues
        if "unsubscribe" not in text.lower() and len(text) > 500:
            suggestions.append("Consider adding unsubscribe link for longer emails")

        return {
            "passed": len(issues) == 0,
            "issues": issues,
            "suggestions": suggestions,
        }

    # -------------------------------------------------------------------------
    # Context Extraction
    # -------------------------------------------------------------------------

    def extract_personalization_context(
        self,
        contact: dict,
        account: dict = None,
    ) -> dict:
        """
        Extract context useful for personalization.

        This is a placeholder - real implementation would:
        - Scrape company website
        - Check LinkedIn
        - Look up recent news
        - Find mutual connections
        """
        account = account or {}

        context = {
            "contact_name": f"{contact.get('first_name', '')} {contact.get('last_name', '')}".strip(),
            "title": contact.get("title"),
            "company": account.get("name") or contact.get("company"),
            "industry": account.get("industry"),
            "talking_points": [],
        }

        # Generate talking points based on available data
        if contact.get("title"):
            title_lower = contact["title"].lower()
            if any(t in title_lower for t in ["ceo", "founder", "owner"]):
                context["talking_points"].append("Focus on strategic/growth topics")
            elif any(t in title_lower for t in ["vp", "director", "head"]):
                context["talking_points"].append("Focus on team efficiency and results")
            elif "manager" in title_lower:
                context["talking_points"].append("Focus on practical solutions and ROI")

        if account.get("employee_count"):
            if account["employee_count"] < 50:
                context["talking_points"].append("Small team - emphasize simplicity")
            elif account["employee_count"] < 200:
                context["talking_points"].append("Growth stage - discuss scaling")
            else:
                context["talking_points"].append("Enterprise - focus on integration")

        return context

    # -------------------------------------------------------------------------
    # Templates
    # -------------------------------------------------------------------------

    def get_default_templates(self) -> list[dict]:
        """Return default email templates."""
        return [
            {
                "id": "cold_intro_v1",
                "name": "Cold Intro - Professional",
                "subject": "Quick question, {{first_name}}",
                "body": """Hi {{first_name}},

{{first_line}}

I'm reaching out because I work with {{industry|similar}} companies to help them [value proposition].

Would you be open to a quick call to see if this might be relevant for {{company}}?

Best,
[Your name]""",
                "variables": ["first_name", "first_line", "industry", "company"],
            },
            {
                "id": "follow_up_v1",
                "name": "Follow-up #1",
                "subject": "Re: Quick question, {{first_name}}",
                "body": """Hi {{first_name}},

Just wanted to make sure my last email didn't get buried.

I'd love to share how we've helped companies like {{company}} achieve [specific result].

Worth a 15-minute chat?

Best,
[Your name]""",
                "variables": ["first_name", "company"],
            },
            {
                "id": "breakup_v1",
                "name": "Breakup Email",
                "subject": "Should I close your file?",
                "body": """Hi {{first_name}},

I've reached out a few times but haven't heard back, which usually means one of three things:

1. You're not the right person (if so, who should I reach out to?)
2. You're interested but busy (happy to reconnect later)
3. You're not interested (totally fine, I'll stop reaching out)

Just let me know which one, and I'll act accordingly.

Thanks,
[Your name]""",
                "variables": ["first_name"],
            },
        ]
