"""
KPEN - KiessPen Agent
Handles personalization, first-line generation, and templates.
"""

from __future__ import annotations
import logging
from datetime import datetime
from typing import Optional

from ..core.agent import BaseAgent
from ..core.memory import MemoryEngine
from ..skills.personalization import PersonalizationSkill

logger = logging.getLogger(__name__)


class KiessPenAgent(BaseAgent):
    """
    Personalization agent responsible for:
    - Generating personalized first lines
    - Rendering templates with variables
    - Checking tone and compliance
    - Managing templates
    """

    codename = "KPEN"
    name = "KiessPen"
    description = "Personalization, first lines, templates"

    def __init__(self, config: dict, memory: MemoryEngine):
        super().__init__(config, memory)
        self.personalization_skill = PersonalizationSkill(config)

    def run(self, task: str, **kwargs) -> str:
        """
        Execute a personalization task.

        Supported tasks:
        - personalize: Generate personalized content for a contact
        - render: Render a template with variables
        - first_line: Generate a first line
        - check: Check content for tone issues
        - templates: List or manage templates
        """
        self.update_status("running", task)

        try:
            if task == "personalize" or "personalize" in task.lower():
                return self._handle_personalize(**kwargs)
            elif task == "render" or "render" in task.lower():
                return self._handle_render(**kwargs)
            elif task == "first_line" or "first" in task.lower():
                return self._handle_first_line(**kwargs)
            elif task == "check" or "tone" in task.lower():
                return self._handle_check(**kwargs)
            elif task == "templates" or "template" in task.lower():
                return self._handle_templates(**kwargs)
            else:
                return self._handle_natural_language(task, **kwargs)

        except Exception as e:
            logger.error(f"[KPEN] Error: {e}")
            self.update_status("error", task)
            return f"Error: {str(e)}"

        finally:
            self.update_status("idle")

    def _handle_personalize(
        self,
        contact_id: str = None,
        template_id: str = None,
        **kwargs
    ) -> str:
        """Generate personalized content for a contact."""
        if not contact_id:
            return "Error: contact_id is required"

        # Load contact
        contacts = self.memory.load_data("contacts")
        contact = None
        for c in contacts:
            if c["id"] == contact_id:
                contact = c
                break

        if not contact:
            return f"Contact {contact_id} not found"

        # Load account
        accounts = self.memory.load_data("accounts")
        account = None
        for a in accounts:
            if a["id"] == contact.get("account_id"):
                account = a
                break

        # Extract context
        context = self.personalization_skill.extract_personalization_context(
            contact, account
        )

        # Generate first line using LLM
        first_line_prompt = self.personalization_skill.build_first_line_prompt(
            contact, account, context
        )

        response = self.think(
            user_message=first_line_prompt,
        )

        first_line = response.content.strip()

        # Validate first line
        validation = self.personalization_skill.validate_first_line(first_line)

        # If template provided, render it
        rendered = None
        if template_id:
            templates = self.personalization_skill.get_default_templates()
            template = None
            for t in templates:
                if t["id"] == template_id:
                    template = t
                    break

            if template:
                result = self.personalization_skill.render_template(
                    template["body"],
                    contact,
                    account,
                    {"first_line": first_line},
                )
                rendered = result["rendered"]

        # Log
        self.memory.log(
            "kpen",
            f"**Personalized Content**\n"
            f"- Contact: {contact.get('email')}\n"
            f"- First line: {first_line[:100]}...\n"
            f"- Confidence: {validation['confidence']:.2f}"
        )

        output = f"**First Line Generated**\n\n\"{first_line}\"\n\n"
        output += f"Confidence: {validation['confidence']:.0%}\n"

        if validation["issues"]:
            output += f"Issues: {', '.join(validation['issues'])}\n"

        if rendered:
            output += f"\n**Rendered Template**\n\n{rendered}"

        return output

    def _handle_first_line(
        self,
        contact_id: str = None,
        style: str = "professional",
        **kwargs
    ) -> str:
        """Generate just a first line for a contact."""
        if not contact_id:
            return "Error: contact_id is required"

        # Load contact
        contacts = self.memory.load_data("contacts")
        contact = None
        for c in contacts:
            if c["id"] == contact_id:
                contact = c
                break

        if not contact:
            return f"Contact {contact_id} not found"

        # Load account
        accounts = self.memory.load_data("accounts")
        account = None
        for a in accounts:
            if a["id"] == contact.get("account_id"):
                account = a
                break

        # Generate first line
        prompt = self.personalization_skill.build_first_line_prompt(
            contact, account, style=style
        )

        response = self.think(user_message=prompt)
        first_line = response.content.strip()

        # Validate
        validation = self.personalization_skill.validate_first_line(first_line)

        # If low confidence, try regenerating
        attempts = 1
        while not validation["valid"] and attempts < 3:
            response = self.think(
                user_message=prompt + "\n\nPrevious attempt had issues. Try again with a more specific, genuine approach."
            )
            first_line = response.content.strip()
            validation = self.personalization_skill.validate_first_line(first_line)
            attempts += 1

        return f"\"{first_line}\"\n\nConfidence: {validation['confidence']:.0%}"

    def _handle_render(
        self,
        template: str = None,
        contact_id: str = None,
        **kwargs
    ) -> str:
        """Render a template with variables."""
        if not template:
            return "Error: template text is required"

        # Load contact if provided
        contact = {}
        account = {}

        if contact_id:
            contacts = self.memory.load_data("contacts")
            for c in contacts:
                if c["id"] == contact_id:
                    contact = c
                    break

            if contact.get("account_id"):
                accounts = self.memory.load_data("accounts")
                for a in accounts:
                    if a["id"] == contact["account_id"]:
                        account = a
                        break

        result = self.personalization_skill.render_template(
            template, contact, account, kwargs
        )

        output = f"**Rendered:**\n{result['rendered']}\n\n"
        output += f"Variables used: {', '.join(result['variables_used']) or 'none'}\n"

        if result["missing"]:
            output += f"Missing: {', '.join(result['missing'])}"

        return output

    def _handle_check(self, text: str = None, **kwargs) -> str:
        """Check text for tone and compliance issues."""
        if not text:
            return "Error: text is required"

        result = self.personalization_skill.check_tone(text)

        if result["passed"]:
            output = "Tone check **PASSED**\n\n"
        else:
            output = "Tone check **FAILED**\n\n"

        if result["issues"]:
            output += "**Issues:**\n"
            for issue in result["issues"]:
                output += f"- {issue}\n"

        if result["suggestions"]:
            output += "\n**Suggestions:**\n"
            for suggestion in result["suggestions"]:
                output += f"- {suggestion}\n"

        return output

    def _handle_templates(self, action: str = "list", **kwargs) -> str:
        """List or manage templates."""
        templates = self.personalization_skill.get_default_templates()

        if action == "list":
            output = "**Available Templates**\n\n"
            for t in templates:
                output += f"- **{t['name']}** (`{t['id']}`)\n"
                output += f"  Subject: {t['subject']}\n"
                output += f"  Variables: {', '.join(t['variables'])}\n\n"
            return output

        return "Use action='list' to see templates"

    def _handle_natural_language(self, task: str, **kwargs) -> str:
        """Handle natural language requests."""
        templates = self.personalization_skill.get_default_templates()
        variables = self.personalization_skill.get_available_variables()

        context = (
            f"Available templates: {len(templates)}\n"
            f"Available variables: {', '.join(v['name'] for v in variables)}\n"
        )

        response = self.think(
            user_message=task,
            context=context,
        )

        return response.content
